Browse Source

Added love.window.requestAttention. Bounces the dock icon in OS X and flashes the taskbar icon in Windows when called, if the program isn't in focus.

Alex Szpakowski 10 years ago
parent
commit
cf73aa0107

+ 5 - 0
src/common/OSX.h

@@ -50,6 +50,11 @@ std::string checkDropEvents();
  **/
 std::string getExecutablePath();
 
+/**
+ * Bounce the dock icon, if the app isn't in the foreground.
+ **/
+void requestAttention(bool continuous);
+
 } // osx
 } // love
 

+ 13 - 1
src/common/OSX.mm

@@ -23,6 +23,7 @@
 #ifdef LOVE_MACOSX
 
 #import <Foundation/Foundation.h>
+#import <Cocoa/Cocoa.h>
 
 #include <SDL2/SDL.h>
 
@@ -41,7 +42,7 @@ std::string getLoveInResources()
 		NSString *lovepath = [[NSBundle mainBundle] pathForResource:nil ofType:@"love"];
 
 		if (lovepath != nil)
-			path = [lovepath UTF8String];
+			path = lovepath.UTF8String;
 	}
 
 	return path;
@@ -77,6 +78,17 @@ std::string getExecutablePath()
 	}
 }
 
+void requestAttention(bool continuous)
+{
+	@autoreleasepool
+	{
+		if (continuous)
+			[NSApp requestUserAttention:NSCriticalRequest];
+		else
+			[NSApp requestUserAttention:NSInformationalRequest];
+	}
+}
+
 } // osx
 } // love
 

+ 2 - 0
src/modules/window/Window.h

@@ -171,6 +171,8 @@ public:
 	virtual bool showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow) = 0;
 	virtual int showMessageBox(const MessageBoxData &data) = 0;
 
+	virtual void requestAttention(bool continuous) = 0;
+
 	//virtual static Window *createSingleton() = 0;
 	// No virtual statics, of course, but you are supposed to implement this static.
 

+ 36 - 1
src/modules/window/sdl/Window.cpp

@@ -31,8 +31,13 @@
 // C
 #include <cstdio>
 
-#ifdef LOVE_WINDOWS
+// SDL
+#include <SDL_syswm.h>
+
+#if defined(LOVE_WINDOWS)
 #include <windows.h>
+#elif defined(LOVE_MACOSX)
+#include "common/OSX.h"
 #endif
 
 #ifndef APIENTRY
@@ -965,6 +970,36 @@ int Window::showMessageBox(const MessageBoxData &data)
 	return pressedbutton;
 }
 
+void Window::requestAttention(bool continuous)
+{
+#if defined(LOVE_WINDOWS)
+
+	SDL_SysWMinfo wminfo = {};
+	SDL_VERSION(&wminfo.version);
+
+	if (SDL_GetWindowWMInfo(window, &wminfo))
+	{
+		FLASHWINFO flashinfo = {};
+		flashinfo.cbSize = sizeof(FLASHWINFO);
+		flashinfo.hwnd = wminfo.info.win.window;
+		flashinfo.uCount = 1;
+		flashinfo.dwFlags = FLASHW_ALL;
+
+		if (continuous)
+			flashinfo.dwFlags |= FLASHW_TIMERNOFG;
+
+		FlashWindowEx(&flashinfo);
+	}
+
+#elif defined(LOVE_MACOSX)
+
+	love::osx::requestAttention(continuous);
+	
+#endif
+	
+	// TODO: Linux?
+}
+
 love::window::Window *Window::createSingleton()
 {
 	if (!singleton)

+ 2 - 0
src/modules/window/sdl/Window.h

@@ -100,6 +100,8 @@ public:
 	bool showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow);
 	int showMessageBox(const MessageBoxData &data);
 
+	void requestAttention(bool continuous) override;
+
 	static love::window::Window *createSingleton();
 
 	const char *getName() const;

+ 8 - 0
src/modules/window/wrap_Window.cpp

@@ -483,6 +483,13 @@ int w_showMessageBox(lua_State *L)
 	return 1;
 }
 
+int w_requestAttention(lua_State *L)
+{
+	bool continuous = luax_optboolean(L, 1, false);
+	instance()->requestAttention(continuous);
+	return 0;
+}
+
 static const luaL_Reg functions[] =
 {
 	{ "getDisplayCount", w_getDisplayCount },
@@ -509,6 +516,7 @@ static const luaL_Reg functions[] =
 	{ "minimize", w_minimize },
 	{ "maximize", w_maximize },
 	{ "showMessageBox", w_showMessageBox },
+	{ "requestAttention", w_requestAttention },
 	{ 0, 0 }
 };
 

+ 1 - 0
src/modules/window/wrap_Window.h

@@ -53,6 +53,7 @@ int w_fromPixels(lua_State *L);
 int w_minimize(lua_State *L);
 int w_maximize(lua_State *L);
 int w_showMessageBox(lua_State *L);
+int w_requestAttention(lua_State *L);
 extern "C" LOVE_EXPORT int luaopen_love_window(lua_State *L);
 
 } // window