Implemented the window flash operations for X11

This commit is contained in:
Sam Lantinga 2021-07-24 15:10:57 -07:00
parent 5ae0dd4b52
commit ff1b5e1bf7
4 changed files with 52 additions and 14 deletions

View file

@ -404,6 +404,9 @@ X11_DispatchFocusIn(_THIS, SDL_WindowData *data)
#ifdef SDL_USE_IME
SDL_IME_SetFocus(SDL_TRUE);
#endif
if (data->flashing_window) {
X11_FlashWindow(_this, data->window, SDL_FLASH_CANCEL);
}
}
static void
@ -1548,6 +1551,7 @@ X11_PumpEvents(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
XEvent xevent;
int i;
if (data->last_mode_change_deadline) {
if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) {
@ -1586,6 +1590,15 @@ X11_PumpEvents(_THIS)
/* FIXME: Only need to do this when there are pending focus changes */
X11_HandleFocusChanges(_this);
/* FIXME: Only need to do this when there are flashing windows */
for (i = 0; i < data->numwindows; ++i) {
if (data->windowlist[i] != NULL &&
data->windowlist[i]->flash_cancel_time &&
SDL_TICKS_PASSED(SDL_GetTicks(), data->windowlist[i]->flash_cancel_time)) {
X11_FlashWindow(_this, data->windowlist[i]->window, SDL_FLASH_CANCEL);
}
}
}

View file

@ -119,8 +119,9 @@ SDL_X11_SYM(int,XSetSelectionOwner,(Display* a,Atom b,Window c,Time d),(a,b,c,d)
SDL_X11_SYM(int,XSetTransientForHint,(Display* a,Window b,Window c),(a,b,c),return)
SDL_X11_SYM(void,XSetTextProperty,(Display* a,Window b,XTextProperty* c,Atom d),(a,b,c,d),)
SDL_X11_SYM(int,XSetWindowBackground,(Display* a,Window b,unsigned long c),(a,b,c),return)
SDL_X11_SYM(void,XSetWMProperties,(Display* a,Window b,XTextProperty* c,XTextProperty* d,char** e,int f,XSizeHints* g,XWMHints* h,XClassHint* i),(a,b,c,d,e,f,g,h,i),)
SDL_X11_SYM(void,XSetWMHints,(Display* a,Window b,XWMHints* c),(a,b,c),)
SDL_X11_SYM(void,XSetWMNormalHints,(Display* a,Window b,XSizeHints* c),(a,b,c),)
SDL_X11_SYM(void,XSetWMProperties,(Display* a,Window b,XTextProperty* c,XTextProperty* d,char** e,int f,XSizeHints* g,XWMHints* h,XClassHint* i),(a,b,c,d,e,f,g,h,i),)
SDL_X11_SYM(Status,XSetWMProtocols,(Display* a,Window b,Atom* c,int d),(a,b,c,d),return)
SDL_X11_SYM(int,XStoreColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return)
SDL_X11_SYM(int,XStoreName,(Display* a,Window b,_Xconst char* c),(a,b,c),return)

View file

@ -1752,23 +1752,45 @@ int
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;
Display *display = data->videodata->display;
XWMHints *wmhints;
Atom demands_attention = X11_XInternAtom(display, "_NET_WM_STATE_DEMANDS_ATTENTION", 1);
Atom wm_state = X11_XInternAtom(display, "_NET_WM_STATE", 1);
wmhints = X11_XGetWMHints(display, data->xwindow);
if (!wmhints) {
return SDL_SetError("Couldn't get WM hints");
}
XEvent snd_ntfy_ev = {ClientMessage};
snd_ntfy_ev.xclient.window = data->xwindow;
snd_ntfy_ev.xclient.message_type = wm_state;
snd_ntfy_ev.xclient.format = 32;
snd_ntfy_ev.xclient.data.l[0] = 1; /* _NET_WM_STATE_ADD */
snd_ntfy_ev.xclient.data.l[1] = demands_attention;
snd_ntfy_ev.xclient.data.l[2] = 0;
snd_ntfy_ev.xclient.data.l[3] = 1; /* normal application */
snd_ntfy_ev.xclient.data.l[4] = 0;
X11_XSendEvent(display, RootWindow(display, displaydata->screen), False, SubstructureNotifyMask | SubstructureRedirectMask, &snd_ntfy_ev);
wmhints->flags &= ~XUrgencyHint;
data->flashing_window = SDL_FALSE;
data->flash_cancel_time = 0;
switch (operation) {
case SDL_FLASH_CANCEL:
/* Taken care of above */
break;
case SDL_FLASH_BRIEFLY:
if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
wmhints->flags |= XUrgencyHint;
data->flashing_window = SDL_TRUE;
/* On Ubuntu 21.04 this causes a dialog to pop up, so leave it up for a full second so users can see it */
data->flash_cancel_time = SDL_GetTicks() + 1000;
if (!data->flash_cancel_time) {
data->flash_cancel_time = 1;
}
}
break;
case SDL_FLASH_UNTIL_FOCUSED:
if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
wmhints->flags |= XUrgencyHint;
data->flashing_window = SDL_TRUE;
}
break;
default:
break;
}
X11_XSetWMHints(display, data->xwindow, wmhints);
X11_XFree(wmhints);
return 0;
}

View file

@ -68,6 +68,8 @@ typedef struct
unsigned long user_time;
Atom xdnd_req;
Window xdnd_source;
SDL_bool flashing_window;
Uint32 flash_cancel_time;
#if SDL_VIDEO_OPENGL_EGL
EGLSurface egl_surface;
#endif