On Compiz (etc?), _NET_WM_ACTION_FULLSCREEN needs the window to be resizable.
authorRyan C. Gordon <icculus@icculus.org>
Thu, 27 Sep 2012 00:53:37 -0400
changeset 6466 ebe165c00fab
parent 6465 09b96f7ebe80
child 6467 ec5a04e921d4
On Compiz (etc?), _NET_WM_ACTION_FULLSCREEN needs the window to be resizable. Thanks to Edward Rudd for the patch!
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11window.c
--- a/src/video/x11/SDL_x11video.c	Wed Sep 26 20:28:58 2012 -0700
+++ b/src/video/x11/SDL_x11video.c	Thu Sep 27 00:53:37 2012 -0400
@@ -339,6 +339,8 @@
     GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
     GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
     GET_ATOM(_NET_WM_STATE_FULLSCREEN);
+    GET_ATOM(_NET_WM_ALLOWED_ACTIONS);
+    GET_ATOM(_NET_WM_ACTION_FULLSCREEN);
     GET_ATOM(_NET_WM_NAME);
     GET_ATOM(_NET_WM_ICON_NAME);
     GET_ATOM(_NET_WM_ICON);
--- a/src/video/x11/SDL_x11video.h	Wed Sep 26 20:28:58 2012 -0700
+++ b/src/video/x11/SDL_x11video.h	Thu Sep 27 00:53:37 2012 -0400
@@ -86,6 +86,8 @@
     Atom _NET_WM_STATE_MAXIMIZED_VERT;
     Atom _NET_WM_STATE_MAXIMIZED_HORZ;
     Atom _NET_WM_STATE_FULLSCREEN;
+    Atom _NET_WM_ALLOWED_ACTIONS;
+    Atom _NET_WM_ACTION_FULLSCREEN;
     Atom _NET_WM_NAME;
     Atom _NET_WM_ICON_NAME;
     Atom _NET_WM_ICON;
--- a/src/video/x11/SDL_x11window.c	Wed Sep 26 20:28:58 2012 -0700
+++ b/src/video/x11/SDL_x11window.c	Thu Sep 27 00:53:37 2012 -0400
@@ -882,6 +882,31 @@
     X11_ShowWindow(_this, window);
 }
 
+static Bool
+isActionAllowed(SDL_WindowData *data, Atom action)
+{
+    Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS;
+    Atom type;
+    Display *display = data->videodata->display;
+    int form;
+    unsigned long remain;
+    unsigned long len, i;
+    Atom *list;
+    Bool ret = False;
+    if (XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success)
+    {
+        for (i=0; i<len; ++i)
+        {
+            if (list[i] == action) {
+                ret = True;
+                break;
+            }
+        }
+        XFree(list);
+    }
+    return ret;
+}
+
 void
 X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen)
 {
@@ -896,6 +921,29 @@
     if (X11_IsWindowMapped(_this, window)) {
         XEvent e;
 
+        if (isActionAllowed(data, data->videodata->_NET_WM_ACTION_FULLSCREEN) == False)
+        {
+            /* We aren't allowed to go into fullscreen mode... */
+            if ((window->flags & SDL_WINDOW_RESIZABLE) == 0) {
+                /* ...and we aren't resizable. Compiz refuses fullscreen toggle in this case. */
+                XSizeHints *sizehints = XAllocSizeHints();
+                long flags = 0;
+                XGetWMNormalHints(display, data->xwindow, sizehints, &flags);
+                /* set the resize flags on */
+                sizehints->flags |= PMinSize | PMaxSize;
+                if (fullscreen) {
+                    /* we are going fullscreen so turn the flags off */
+                    sizehints->flags ^= (PMinSize | PMaxSize);
+                } else {
+                    /* Reset the min/max width height to make the window non-resizable again */
+                    sizehints->min_width = sizehints->max_width = window->w;
+                    sizehints->min_height = sizehints->max_height = window->h;
+                }
+                XSetWMNormalHints(display, data->xwindow, sizehints);
+                XFree(sizehints);
+            }
+        }
+        
         SDL_zero(e);
         e.xany.type = ClientMessage;
         e.xclient.message_type = _NET_WM_STATE;