Implemented the window flash operations for X11
parent
5ae0dd4b52
commit
ff1b5e1bf7
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue