Răsfoiți Sursa

x11: Don't set the hidden flag when minimizing windows

On non-compositing window managers, XIconifyWindow can trigger map/unmap events, which would toggle the window hidden/shown state. This should not be done, as a hidden window in SDL is equivalent to a withdrawn window in X, and SDL will try to set/reset state when it is shown again.

Unless the window is explicitly being withdrawn via X11_HideWindow(), set unmapped windows to the minimized/occluded state, and send a restored event when mapped again.
Frank Praznik 2 săptămâni în urmă
părinte
comite
667b706a93
1 a modificat fișierele cu 22 adăugiri și 14 ștergeri
  1. 22 14
      src/video/x11/SDL_x11events.c

+ 22 - 14
src/video/x11/SDL_x11events.c

@@ -506,17 +506,29 @@ static void X11_DispatchFocusOut(SDL_VideoDevice *_this, SDL_WindowData *data)
 static void X11_DispatchMapNotify(SDL_WindowData *data)
 {
     SDL_Window *window = data->window;
-    SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
+
     SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_SHOWN, 0, 0);
-    if (!(window->flags & SDL_WINDOW_HIDDEN) && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
+
+    // This may be sent when restoring a minimized window.
+    if (window->flags & SDL_WINDOW_MINIMIZED) {
+        SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
+        SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_EXPOSED, 0, 0);
+    }
+
+    if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
         SDL_UpdateWindowGrab(window);
     }
 }
 
 static void X11_DispatchUnmapNotify(SDL_WindowData *data)
 {
-    SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_HIDDEN, 0, 0);
-    SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
+    SDL_Window *window = data->window;
+
+    // This may be sent when minimizing a window.
+    if (!window->is_hiding) {
+        SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
+        SDL_SendWindowEvent(data->window, SDL_EVENT_WINDOW_OCCLUDED, 0, 0);
+    }
 }
 
 static void DispatchWindowMove(SDL_VideoDevice *_this, const SDL_WindowData *data, const SDL_Point *point)
@@ -1320,7 +1332,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
             xevent->xcrossing.detail != NotifyInferior) {
 
             /* In order for interaction with the window decorations and menu to work properly
-               on Mutter, we need to ungrab the keyboard when the the mouse leaves. */
+               on Mutter, we need to ungrab the keyboard when the mouse leaves. */
             if (!(data->window->flags & SDL_WINDOW_FULLSCREEN)) {
                 X11_SetWindowKeyboardGrab(_this, data->window, false);
             }
@@ -1782,19 +1794,15 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
 
         if (xevent->xproperty.atom == data->videodata->atoms._NET_WM_STATE) {
             /* Get the new state from the window manager.
-               Compositing window managers can alter visibility of windows
-               without ever mapping / unmapping them, so we handle that here,
-               because they use the NETWM protocol to notify us of changes.
+             * Compositing window managers can alter visibility of windows
+             * without ever mapping / unmapping them, so we handle that here,
+             * because they use the NETWM protocol to notify us of changes.
              */
             const SDL_WindowFlags flags = X11_GetNetWMState(_this, data->window, xevent->xproperty.window);
             const SDL_WindowFlags changed = flags ^ data->window->flags;
 
-            if ((changed & (SDL_WINDOW_HIDDEN | SDL_WINDOW_FULLSCREEN)) != 0) {
-                if (flags & SDL_WINDOW_HIDDEN) {
-                    X11_DispatchUnmapNotify(data);
-                } else {
-                    X11_DispatchMapNotify(data);
-                }
+            if ((changed & SDL_WINDOW_HIDDEN) && !(flags & SDL_WINDOW_HIDDEN)) {
+                X11_DispatchMapNotify(data);
             }
 
             if (!SDL_WINDOW_IS_POPUP(data->window)) {