On Compiz (etc?), _NET_WM_ACTION_FULLSCREEN needs the window to be resizable.
authorRyan C. Gordon
Thu, 27 Sep 2012 00:53:37 -0400
changeset 6466ebe165c00fab
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
     1.1 --- a/src/video/x11/SDL_x11video.c	Wed Sep 26 20:28:58 2012 -0700
     1.2 +++ b/src/video/x11/SDL_x11video.c	Thu Sep 27 00:53:37 2012 -0400
     1.3 @@ -339,6 +339,8 @@
     1.4      GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
     1.5      GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
     1.6      GET_ATOM(_NET_WM_STATE_FULLSCREEN);
     1.7 +    GET_ATOM(_NET_WM_ALLOWED_ACTIONS);
     1.8 +    GET_ATOM(_NET_WM_ACTION_FULLSCREEN);
     1.9      GET_ATOM(_NET_WM_NAME);
    1.10      GET_ATOM(_NET_WM_ICON_NAME);
    1.11      GET_ATOM(_NET_WM_ICON);
     2.1 --- a/src/video/x11/SDL_x11video.h	Wed Sep 26 20:28:58 2012 -0700
     2.2 +++ b/src/video/x11/SDL_x11video.h	Thu Sep 27 00:53:37 2012 -0400
     2.3 @@ -86,6 +86,8 @@
     2.4      Atom _NET_WM_STATE_MAXIMIZED_VERT;
     2.5      Atom _NET_WM_STATE_MAXIMIZED_HORZ;
     2.6      Atom _NET_WM_STATE_FULLSCREEN;
     2.7 +    Atom _NET_WM_ALLOWED_ACTIONS;
     2.8 +    Atom _NET_WM_ACTION_FULLSCREEN;
     2.9      Atom _NET_WM_NAME;
    2.10      Atom _NET_WM_ICON_NAME;
    2.11      Atom _NET_WM_ICON;
     3.1 --- a/src/video/x11/SDL_x11window.c	Wed Sep 26 20:28:58 2012 -0700
     3.2 +++ b/src/video/x11/SDL_x11window.c	Thu Sep 27 00:53:37 2012 -0400
     3.3 @@ -882,6 +882,31 @@
     3.4      X11_ShowWindow(_this, window);
     3.5  }
     3.6  
     3.7 +static Bool
     3.8 +isActionAllowed(SDL_WindowData *data, Atom action)
     3.9 +{
    3.10 +    Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS;
    3.11 +    Atom type;
    3.12 +    Display *display = data->videodata->display;
    3.13 +    int form;
    3.14 +    unsigned long remain;
    3.15 +    unsigned long len, i;
    3.16 +    Atom *list;
    3.17 +    Bool ret = False;
    3.18 +    if (XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success)
    3.19 +    {
    3.20 +        for (i=0; i<len; ++i)
    3.21 +        {
    3.22 +            if (list[i] == action) {
    3.23 +                ret = True;
    3.24 +                break;
    3.25 +            }
    3.26 +        }
    3.27 +        XFree(list);
    3.28 +    }
    3.29 +    return ret;
    3.30 +}
    3.31 +
    3.32  void
    3.33  X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen)
    3.34  {
    3.35 @@ -896,6 +921,29 @@
    3.36      if (X11_IsWindowMapped(_this, window)) {
    3.37          XEvent e;
    3.38  
    3.39 +        if (isActionAllowed(data, data->videodata->_NET_WM_ACTION_FULLSCREEN) == False)
    3.40 +        {
    3.41 +            /* We aren't allowed to go into fullscreen mode... */
    3.42 +            if ((window->flags & SDL_WINDOW_RESIZABLE) == 0) {
    3.43 +                /* ...and we aren't resizable. Compiz refuses fullscreen toggle in this case. */
    3.44 +                XSizeHints *sizehints = XAllocSizeHints();
    3.45 +                long flags = 0;
    3.46 +                XGetWMNormalHints(display, data->xwindow, sizehints, &flags);
    3.47 +                /* set the resize flags on */
    3.48 +                sizehints->flags |= PMinSize | PMaxSize;
    3.49 +                if (fullscreen) {
    3.50 +                    /* we are going fullscreen so turn the flags off */
    3.51 +                    sizehints->flags ^= (PMinSize | PMaxSize);
    3.52 +                } else {
    3.53 +                    /* Reset the min/max width height to make the window non-resizable again */
    3.54 +                    sizehints->min_width = sizehints->max_width = window->w;
    3.55 +                    sizehints->min_height = sizehints->max_height = window->h;
    3.56 +                }
    3.57 +                XSetWMNormalHints(display, data->xwindow, sizehints);
    3.58 +                XFree(sizehints);
    3.59 +            }
    3.60 +        }
    3.61 +        
    3.62          SDL_zero(e);
    3.63          e.xany.type = ClientMessage;
    3.64          e.xclient.message_type = _NET_WM_STATE;