Added a window flash operation to be explicit about window flash behavior
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index eaed22a..549ed66 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -1441,15 +1441,6 @@ extern "C" {
#define SDL_HINT_WAVE_TRUNCATION "SDL_WAVE_TRUNCATION"
/**
- * \brief Controls the number of times a window flashes with SDL_FlashWindow()
- *
- * On Windows, if this variable is set, the SDL_FlashWindow() call will flash
- * the specified number of times. Otherwise the window will flash until it
- * becomes the foreground window.
- */
-#define SDL_HINT_WINDOW_FLASH_COUNT "SDL_WINDOW_FLASH_COUNT"
-
-/**
* \brief Tell SDL not to name threads on Windows with the 0x406D1388 Exception.
* The 0x406D1388 Exception is a trick used to inform Visual Studio of a
* thread's name, but it tends to cause problems with other debuggers,
diff --git a/include/SDL_test_common.h b/include/SDL_test_common.h
index ff6c975..97f036d 100644
--- a/include/SDL_test_common.h
+++ b/include/SDL_test_common.h
@@ -64,6 +64,7 @@ typedef struct
const char *window_title;
const char *window_icon;
Uint32 window_flags;
+ SDL_bool flash_on_focus_loss;
int window_x;
int window_y;
int window_w;
diff --git a/include/SDL_video.h b/include/SDL_video.h
index afced02..73bc660 100644
--- a/include/SDL_video.h
+++ b/include/SDL_video.h
@@ -188,6 +188,9 @@ typedef enum
SDL_DISPLAYEVENT_DISCONNECTED /**< Display has been removed from the system */
} SDL_DisplayEventID;
+/**
+ * \brief Display orientation
+ */
typedef enum
{
SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */
@@ -198,6 +201,16 @@ typedef enum
} SDL_DisplayOrientation;
/**
+ * \brief Window flash operation
+ */
+typedef enum
+{
+ SDL_FLASH_CANCEL, /**< Cancel any window flash state */
+ SDL_FLASH_BRIEFLY, /**< Flash the window briefly to get attention */
+ SDL_FLASH_UNTIL_FOCUSED, /**< Flash the window until it gets focus */
+} SDL_FlashOperation;
+
+/**
* \brief An opaque handle to an OpenGL context.
*/
typedef void *SDL_GLContext;
@@ -1511,10 +1524,11 @@ extern DECLSPEC int SDLCALL SDL_SetWindowHitTest(SDL_Window * window,
* Request a window to demand attention from the user.
*
* \param window the window to be flashed
+ * \param the flash operation
* \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information.
*/
-extern DECLSPEC int SDLCALL SDL_FlashWindow(SDL_Window * window);
+extern DECLSPEC int SDLCALL SDL_FlashWindow(SDL_Window * window, SDL_FlashOperation operation);
/**
* Destroy a window.
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index d6ff463..f878b5e 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -876,6 +876,6 @@ SDL_DYNAPI_PROC(int,SDL_AndroidShowToast,(const char *a, int b, int c, int d, in
SDL_DYNAPI_PROC(int,SDL_GetAudioDeviceSpec,(int a, int b, SDL_AudioSpec *c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_TLSCleanup,(void),(),)
SDL_DYNAPI_PROC(void,SDL_SetWindowAlwaysOnTop,(SDL_Window *a, SDL_bool b),(a,b),)
-SDL_DYNAPI_PROC(int,SDL_FlashWindow,(SDL_Window *a),(a),return)
+SDL_DYNAPI_PROC(int,SDL_FlashWindow,(SDL_Window *a, SDL_FlashOperation b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerSendEffect,(SDL_GameController *a, const void *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_JoystickSendEffect,(SDL_Joystick *a, const void *b, int c),(a,b,c),return)
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index 94ec47c..5fea48f 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -37,7 +37,7 @@ static const char *video_usage[] = {
"[--scale N]", "[--depth N]", "[--refresh R]", "[--vsync]", "[--noframe]",
"[--resizable]", "[--minimize]", "[--maximize]", "[--grab]", "[--keyboard-grab]",
"[--shown]", "[--hidden]", "[--input-focus]", "[--mouse-focus]",
- "[--allow-highdpi]", "[--usable-bounds]"
+ "[--flash-on-focus-loss]", "[--allow-highdpi]", "[--usable-bounds]"
};
static const char *audio_usage[] = {
@@ -441,6 +441,10 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index)
state->window_flags |= SDL_WINDOW_MOUSE_FOCUS;
return 1;
}
+ if (SDL_strcasecmp(argv[index], "--flash-on-focus-loss") == 0) {
+ state->flash_on_focus_loss = SDL_TRUE;
+ return 1;
+ }
if (SDL_strcasecmp(argv[index], "--grab") == 0) {
state->window_flags |= SDL_WINDOW_MOUSE_GRABBED;
return 1;
@@ -1808,6 +1812,16 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
}
}
break;
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ if (state->flash_on_focus_loss) {
+ SDL_Window *window = SDL_GetWindowFromID(event->window.windowID);
+ if (window) {
+ SDL_FlashWindow(window, SDL_FLASH_UNTIL_FOCUSED);
+ }
+ }
+ break;
+ default:
+ break;
}
break;
case SDL_KEYDOWN: {
@@ -1963,7 +1977,7 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done)
/* Ctrl-F flash the window */
SDL_Window *window = SDL_GetWindowFromID(event->key.windowID);
if (window) {
- SDL_FlashWindow(window);
+ SDL_FlashWindow(window, SDL_FLASH_BRIEFLY);
}
}
break;
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index 50010a2..0be19c1 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -240,7 +240,7 @@ struct SDL_VideoDevice
int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window);
void (*OnWindowEnter) (_THIS, SDL_Window * window);
- int (*FlashWindow) (_THIS, SDL_Window * window);
+ int (*FlashWindow) (_THIS, SDL_Window * window, SDL_FlashOperation operation);
/* * * */
/*
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 49ebbc2..47f19b1 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -2793,12 +2793,12 @@ SDL_GetGrabbedWindow(void)
}
int
-SDL_FlashWindow(SDL_Window * window)
+SDL_FlashWindow(SDL_Window * window, SDL_FlashOperation operation)
{
CHECK_WINDOW_MAGIC(window, -1);
if (_this->FlashWindow) {
- return _this->FlashWindow(_this, window);
+ return _this->FlashWindow(_this, window, operation);
}
return SDL_Unsupported();
diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h
index ed53fec..e14bb1d 100644
--- a/src/video/cocoa/SDL_cocoawindow.h
+++ b/src/video/cocoa/SDL_cocoawindow.h
@@ -117,6 +117,7 @@ struct SDL_WindowData
NSMutableArray *nscontexts;
SDL_bool created;
SDL_bool inWindowFullscreenTransition;
+ NSInteger flash_request;
Cocoa_WindowListener *listener;
struct SDL_VideoData *videodata;
#if SDL_VIDEO_OPENGL_EGL
@@ -151,7 +152,7 @@ extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info);
extern int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
extern void Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
-extern int Cocoa_FlashWindow(_THIS, SDL_Window * window);
+extern int Cocoa_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
#endif /* SDL_cocoawindow_h_ */
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 43aad09..4586073 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -2117,11 +2117,30 @@ Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
}
int
-Cocoa_FlashWindow(_THIS, SDL_Window *window)
+Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
{ @autoreleasepool
{
/* Note that this is app-wide and not window-specific! */
- [NSApp requestUserAttention:NSInformationalRequest];
+ SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
+
+ if (data->flash_request) {
+ [NSApp cancelUserAttentionRequest:data->flash_request];
+ data->flash_request = 0;
+ }
+
+ switch (operation) {
+ case SDL_FLASH_CANCEL:
+ /* Canceled above */
+ break;
+ case SDL_FLASH_BRIEFLY:
+ data->flash_request = [NSApp requestUserAttention:NSInformationalRequest];
+ break;
+ case SDL_FLASH_UNTIL_FOCUSED:
+ data->flash_request = [NSApp requestUserAttention:NSCriticalRequest];
+ break;
+ default:
+ return SDL_Unsupported();
+ }
return 0;
}}
diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m
index 54f8887..6d78685 100644
--- a/src/video/uikit/SDL_uikitevents.m
+++ b/src/video/uikit/SDL_uikitevents.m
@@ -196,7 +196,7 @@ static void UpdateMouseGrab()
static int SetGCMouseRelativeMode(SDL_bool enabled)
{
- mouse_relative_mode = enabled;
+ mouse_relative_mode = enabled;
UpdateMouseGrab();
return 0;
}
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 773cc46..960e3c9 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -920,7 +920,7 @@ Wayland_RaiseWindow(_THIS, SDL_Window *window)
}
int
-Wayland_FlashWindow(_THIS, SDL_Window *window)
+Wayland_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
{
Wayland_activate_window(_this->driverdata,
window->driverdata,
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index 873ea02..5956cf3 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -113,7 +113,7 @@ extern void Wayland_SuspendScreenSaver(_THIS);
extern SDL_bool
Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
-extern int Wayland_FlashWindow(_THIS, SDL_Window * window);
+extern int Wayland_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
extern void Wayland_HandlePendingResize(SDL_Window *window);
diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c
index 96eb67d..93d1903 100644
--- a/src/video/windows/SDL_windowswindow.c
+++ b/src/video/windows/SDL_windowswindow.c
@@ -1064,19 +1064,26 @@ WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
}
int
-WIN_FlashWindow(_THIS, SDL_Window * window)
+WIN_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation)
{
FLASHWINFO desc;
- const char *hint = SDL_GetHint(SDL_HINT_WINDOW_FLASH_COUNT);
SDL_zero(desc);
desc.cbSize = sizeof(desc);
desc.hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
- desc.dwFlags = FLASHW_TRAY;
- if (hint && *hint) {
- desc.uCount = SDL_atoi(hint);
- } else {
- desc.dwFlags |= FLASHW_TIMERNOFG;
+ switch (operation) {
+ case SDL_FLASH_CANCEL:
+ desc.dwFlags = FLASHW_STOP;
+ break;
+ case SDL_FLASH_BRIEFLY:
+ desc.dwFlags = FLASHW_TRAY;
+ desc.uCount = 1;
+ break;
+ case SDL_FLASH_UNTIL_FOCUSED:
+ desc.dwFlags = (FLASHW_TRAY | FLASHW_TIMERNOFG);
+ break;
+ default:
+ return SDL_Unsupported();
}
FlashWindowEx(&desc);
diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h
index 335326a..700566e 100644
--- a/src/video/windows/SDL_windowswindow.h
+++ b/src/video/windows/SDL_windowswindow.h
@@ -86,7 +86,7 @@ extern void WIN_OnWindowEnter(_THIS, SDL_Window * window);
extern void WIN_UpdateClipCursor(SDL_Window *window);
extern int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
extern void WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
-extern int WIN_FlashWindow(_THIS, SDL_Window * window);
+extern int WIN_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
#endif /* SDL_windowswindow_h_ */
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index d041dd9..9a09fee 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/src/video/x11/SDL_x11window.c
@@ -1749,7 +1749,7 @@ X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
}
int
-X11_FlashWindow(_THIS, SDL_Window * window)
+X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h
index ad46563..25d12dd 100644
--- a/src/video/x11/SDL_x11window.h
+++ b/src/video/x11/SDL_x11window.h
@@ -107,7 +107,7 @@ extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
extern void X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
-extern int X11_FlashWindow(_THIS, SDL_Window * window);
+extern int X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
#endif /* SDL_x11window_h_ */