Compositing window managers can show and hide windows without ever affecting the mapped state. However they do send NetWM protocol messages to indicate this is happening.
authorSam Lantinga
Thu, 27 Sep 2012 23:55:38 -0700
changeset 6481fab4b15b17e9
parent 6480 d02a4369b3f5
child 6482 94e3643928ed
Compositing window managers can show and hide windows without ever affecting the mapped state. However they do send NetWM protocol messages to indicate this is happening.
Also refactored the netwm state code so it's consistent between the places that use it.
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11window.c
src/video/x11/SDL_x11window.h
     1.1 --- a/src/video/x11/SDL_x11events.c	Thu Sep 27 17:17:33 2012 -0700
     1.2 +++ b/src/video/x11/SDL_x11events.c	Thu Sep 27 23:55:38 2012 -0700
     1.3 @@ -109,6 +109,19 @@
     1.4  #endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */
     1.5  
     1.6  
     1.7 +static void
     1.8 +X11_DispatchMapNotify(SDL_WindowData *data)
     1.9 +{
    1.10 +    SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
    1.11 +    SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
    1.12 +}
    1.13 +
    1.14 +static void
    1.15 +X11_DispatchUnmapNotify(SDL_WindowData *data)
    1.16 +{
    1.17 +    SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
    1.18 +    SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
    1.19 +}
    1.20  
    1.21  static void
    1.22  X11_DispatchEvent(_THIS)
    1.23 @@ -315,8 +328,7 @@
    1.24  #ifdef DEBUG_XEVENTS
    1.25              printf("UnmapNotify!\n");
    1.26  #endif
    1.27 -            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0);
    1.28 -            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
    1.29 +            X11_DispatchUnmapNotify(data);
    1.30          }
    1.31          break;
    1.32  
    1.33 @@ -325,8 +337,7 @@
    1.34  #ifdef DEBUG_XEVENTS
    1.35              printf("MapNotify!\n");
    1.36  #endif
    1.37 -            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
    1.38 -            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
    1.39 +            X11_DispatchMapNotify(data);
    1.40          }
    1.41          break;
    1.42  
    1.43 @@ -463,7 +474,26 @@
    1.44                      }
    1.45                  }
    1.46              }
    1.47 -#endif
    1.48 +            if (status == Success) {
    1.49 +                XFree(propdata);
    1.50 +            }
    1.51 +#endif /* DEBUG_XEVENTS */
    1.52 +
    1.53 +            if (xevent.xproperty.atom == data->videodata->_NET_WM_STATE) {
    1.54 +                /* Get the new state from the window manager.
    1.55 +                   Compositing window managers can alter visibility of windows
    1.56 +                   without ever mapping / unmapping them, so we handle that here,
    1.57 +                   because they use the NETWM protocol to notify us of changes.
    1.58 +                 */
    1.59 +                Uint32 flags = X11_GetNetWMState(_this, data->window);
    1.60 +                if ((flags^data->window->flags) & SDL_WINDOW_HIDDEN) {
    1.61 +                    if (flags & SDL_WINDOW_HIDDEN) {
    1.62 +                        X11_DispatchUnmapNotify(data);
    1.63 +                    } else {
    1.64 +                        X11_DispatchMapNotify(data);
    1.65 +                    }
    1.66 +                }
    1.67 +            }
    1.68          }
    1.69          break;
    1.70  
     2.1 --- a/src/video/x11/SDL_x11video.c	Thu Sep 27 17:17:33 2012 -0700
     2.2 +++ b/src/video/x11/SDL_x11video.c	Thu Sep 27 23:55:38 2012 -0700
     2.3 @@ -336,10 +336,12 @@
     2.4      GET_ATOM(WM_DELETE_WINDOW);
     2.5      GET_ATOM(_NET_WM_STATE);
     2.6      GET_ATOM(_NET_WM_STATE_HIDDEN);
     2.7 +    GET_ATOM(_NET_WM_STATE_FOCUSED);
     2.8      GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
     2.9      GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
    2.10      GET_ATOM(_NET_WM_STATE_FULLSCREEN);
    2.11      GET_ATOM(_NET_WM_ALLOWED_ACTIONS);
    2.12 +    GET_ATOM(_NET_WM_ACTION_RESIZE);
    2.13      GET_ATOM(_NET_WM_ACTION_FULLSCREEN);
    2.14      GET_ATOM(_NET_WM_NAME);
    2.15      GET_ATOM(_NET_WM_ICON_NAME);
     3.1 --- a/src/video/x11/SDL_x11video.h	Thu Sep 27 17:17:33 2012 -0700
     3.2 +++ b/src/video/x11/SDL_x11video.h	Thu Sep 27 23:55:38 2012 -0700
     3.3 @@ -83,10 +83,12 @@
     3.4      Atom WM_DELETE_WINDOW;
     3.5      Atom _NET_WM_STATE;
     3.6      Atom _NET_WM_STATE_HIDDEN;
     3.7 +    Atom _NET_WM_STATE_FOCUSED;
     3.8      Atom _NET_WM_STATE_MAXIMIZED_VERT;
     3.9      Atom _NET_WM_STATE_MAXIMIZED_HORZ;
    3.10      Atom _NET_WM_STATE_FULLSCREEN;
    3.11      Atom _NET_WM_ALLOWED_ACTIONS;
    3.12 +    Atom _NET_WM_ACTION_RESIZE;
    3.13      Atom _NET_WM_ACTION_FULLSCREEN;
    3.14      Atom _NET_WM_NAME;
    3.15      Atom _NET_WM_ICON_NAME;
     4.1 --- a/src/video/x11/SDL_x11window.c	Thu Sep 27 17:17:33 2012 -0700
     4.2 +++ b/src/video/x11/SDL_x11window.c	Thu Sep 27 23:55:38 2012 -0700
     4.3 @@ -87,22 +87,115 @@
     4.4      }
     4.5  }
     4.6  
     4.7 -static int
     4.8 -X11_GetWMStateProperty(_THIS, SDL_Window * window, Atom atoms[3])
     4.9 +static SDL_bool
    4.10 +X11_IsActionAllowed(SDL_Window *window, Atom action)
    4.11  {
    4.12 -    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    4.13 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    4.14 +    Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS;
    4.15 +    Atom type;
    4.16 +    Display *display = data->videodata->display;
    4.17 +    int form;
    4.18 +    unsigned long remain;
    4.19 +    unsigned long len, i;
    4.20 +    Atom *list;
    4.21 +    SDL_bool ret = SDL_FALSE;
    4.22 +
    4.23 +    if (XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success)
    4.24 +    {
    4.25 +        for (i=0; i<len; ++i)
    4.26 +        {
    4.27 +            if (list[i] == action) {
    4.28 +                ret = SDL_TRUE;
    4.29 +                break;
    4.30 +            }
    4.31 +        }
    4.32 +        XFree(list);
    4.33 +    }
    4.34 +    return ret;
    4.35 +}
    4.36 +
    4.37 +int
    4.38 +X11_GetWMStateProperty(_THIS, Uint32 flags, Atom atoms[5])
    4.39 +{
    4.40 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    4.41 +    Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN;
    4.42 +    Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED;
    4.43 +    Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT;
    4.44 +    Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
    4.45 +    Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN;
    4.46      int count = 0;
    4.47  
    4.48 -    if (window->flags & SDL_WINDOW_FULLSCREEN) {
    4.49 -        atoms[count++] = data->_NET_WM_STATE_FULLSCREEN;
    4.50 +    if (flags & SDL_WINDOW_HIDDEN) {
    4.51 +        atoms[count++] = _NET_WM_STATE_HIDDEN;
    4.52 +    }
    4.53 +    if (flags & SDL_WINDOW_INPUT_FOCUS) {
    4.54 +        atoms[count++] = _NET_WM_STATE_FOCUSED;
    4.55      }
    4.56 -    if (window->flags & SDL_WINDOW_MAXIMIZED) {
    4.57 -        atoms[count++] = data->_NET_WM_STATE_MAXIMIZED_VERT;
    4.58 -        atoms[count++] = data->_NET_WM_STATE_MAXIMIZED_HORZ;
    4.59 +    if (flags & SDL_WINDOW_MAXIMIZED) {
    4.60 +        atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT;
    4.61 +        atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
    4.62 +    }
    4.63 +    if (flags & SDL_WINDOW_FULLSCREEN) {
    4.64 +        atoms[count++] = _NET_WM_STATE_FULLSCREEN;
    4.65      }
    4.66      return count;
    4.67  }
    4.68  
    4.69 +Uint32
    4.70 +X11_GetNetWMState(_THIS, SDL_Window * window)
    4.71 +{
    4.72 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    4.73 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    4.74 +    Atom _NET_WM_STATE = videodata->_NET_WM_STATE;
    4.75 +    Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN;
    4.76 +    Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED;
    4.77 +    Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT;
    4.78 +    Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
    4.79 +    Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN;
    4.80 +    Atom _NET_WM_ACTION_RESIZE = videodata->_NET_WM_ACTION_RESIZE;
    4.81 +    Atom actualType;
    4.82 +    int actualFormat;
    4.83 +    unsigned long i, numItems, bytesAfter;
    4.84 +    unsigned char *propertyValue = NULL;
    4.85 +    long maxLength = 1024;
    4.86 +    Uint32 flags = 0;
    4.87 +
    4.88 +    if (XGetWindowProperty(videodata->display, data->xwindow, _NET_WM_STATE,
    4.89 +                           0l, maxLength, False, XA_ATOM, &actualType,
    4.90 +                           &actualFormat, &numItems, &bytesAfter,
    4.91 +                           &propertyValue) == Success) {
    4.92 +        Atom *atoms = (Atom *) propertyValue;
    4.93 +        int maximized = 0;
    4.94 +        int fullscreen = 0;
    4.95 +
    4.96 +        for (i = 0; i < numItems; ++i) {
    4.97 +            if (atoms[i] == _NET_WM_STATE_HIDDEN) {
    4.98 +                flags |= (SDL_WINDOW_HIDDEN|SDL_WINDOW_MINIMIZED);
    4.99 +            } else if (atoms[i] == _NET_WM_STATE_FOCUSED) {
   4.100 +                flags |= SDL_WINDOW_INPUT_FOCUS;
   4.101 +            } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
   4.102 +                maximized |= 1;
   4.103 +            } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
   4.104 +                maximized |= 2;
   4.105 +            } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) {
   4.106 +                fullscreen = 1;
   4.107 +            }
   4.108 +        }
   4.109 +        if (maximized == 3) {
   4.110 +            flags |= SDL_WINDOW_MAXIMIZED;
   4.111 +        }  else if (fullscreen == 1) {
   4.112 +            flags |= SDL_WINDOW_FULLSCREEN;
   4.113 +        }
   4.114 +        XFree(propertyValue);
   4.115 +    }
   4.116 +
   4.117 +    if (X11_IsActionAllowed(window, _NET_WM_ACTION_RESIZE)) {
   4.118 +        flags |= SDL_WINDOW_RESIZABLE;
   4.119 +    }
   4.120 +
   4.121 +    return flags;
   4.122 +}
   4.123 +
   4.124  static int
   4.125  SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
   4.126  {
   4.127 @@ -118,6 +211,8 @@
   4.128          SDL_OutOfMemory();
   4.129          return -1;
   4.130      }
   4.131 +    window->driverdata = data;
   4.132 +
   4.133      data->window = window;
   4.134      data->xwindow = w;
   4.135  #ifdef X_HAVE_UTF8_STRING
   4.136 @@ -171,42 +266,7 @@
   4.137          data->colormap = attrib.colormap;
   4.138      }
   4.139  
   4.140 -    {
   4.141 -        Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
   4.142 -        Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
   4.143 -        Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
   4.144 -        Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
   4.145 -        Atom actualType;
   4.146 -        int actualFormat;
   4.147 -        unsigned long i, numItems, bytesAfter;
   4.148 -        unsigned char *propertyValue = NULL;
   4.149 -        long maxLength = 1024;
   4.150 -
   4.151 -        if (XGetWindowProperty(data->videodata->display, w, _NET_WM_STATE,
   4.152 -                               0l, maxLength, False, XA_ATOM, &actualType,
   4.153 -                               &actualFormat, &numItems, &bytesAfter,
   4.154 -                               &propertyValue) == Success) {
   4.155 -            Atom *atoms = (Atom *) propertyValue;
   4.156 -            int maximized = 0;
   4.157 -            int fullscreen = 0;
   4.158 -
   4.159 -            for (i = 0; i < numItems; ++i) {
   4.160 -                if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
   4.161 -                    maximized |= 1;
   4.162 -                } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
   4.163 -                    maximized |= 2;
   4.164 -                } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) {
   4.165 -                    fullscreen = 1;
   4.166 -                }
   4.167 -            }
   4.168 -            if (maximized == 3) {
   4.169 -                window->flags |= SDL_WINDOW_MAXIMIZED;
   4.170 -            }  else if (fullscreen == 1) {
   4.171 -                window->flags |= SDL_WINDOW_FULLSCREEN;
   4.172 -            }
   4.173 -            XFree(propertyValue);
   4.174 -        }
   4.175 -    }
   4.176 +    window->flags |= X11_GetNetWMState(_this, window);
   4.177  
   4.178      {
   4.179          Window FocalWindow;
   4.180 @@ -215,6 +275,9 @@
   4.181          if (FocalWindow==w)
   4.182          {
   4.183              window->flags |= SDL_WINDOW_INPUT_FOCUS;
   4.184 +        }
   4.185 +
   4.186 +        if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
   4.187              SDL_SetKeyboardFocus(data->window);
   4.188          }
   4.189  
   4.190 @@ -223,43 +286,7 @@
   4.191          }
   4.192      }
   4.193  
   4.194 -    /* FIXME: How can I tell?
   4.195 -       {
   4.196 -       DWORD style = GetWindowLong(hwnd, GWL_STYLE);
   4.197 -       if (style & WS_VISIBLE) {
   4.198 -       if (style & (WS_BORDER | WS_THICKFRAME)) {
   4.199 -       window->flags &= ~SDL_WINDOW_BORDERLESS;
   4.200 -       } else {
   4.201 -       window->flags |= SDL_WINDOW_BORDERLESS;
   4.202 -       }
   4.203 -       if (style & WS_THICKFRAME) {
   4.204 -       window->flags |= SDL_WINDOW_RESIZABLE;
   4.205 -       } else {
   4.206 -       window->flags &= ~SDL_WINDOW_RESIZABLE;
   4.207 -       }
   4.208 -       if (style & WS_MINIMIZE) {
   4.209 -       window->flags |= SDL_WINDOW_MINIMIZED;
   4.210 -       } else {
   4.211 -       window->flags &= ~SDL_WINDOW_MINIMIZED;
   4.212 -       }
   4.213 -       }
   4.214 -       if (GetFocus() == hwnd) {
   4.215 -       int index = data->videodata->keyboard;
   4.216 -       window->flags |= SDL_WINDOW_INPUT_FOCUS;
   4.217 -       SDL_SetKeyboardFocus(index, data->window);
   4.218 -
   4.219 -       if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
   4.220 -       RECT rect;
   4.221 -       GetClientRect(hwnd, &rect);
   4.222 -       ClientToScreen(hwnd, (LPPOINT) & rect);
   4.223 -       ClientToScreen(hwnd, (LPPOINT) & rect + 1);
   4.224 -       ClipCursor(&rect);
   4.225 -       }
   4.226 -       }
   4.227 -     */
   4.228 -
   4.229      /* All done! */
   4.230 -    window->driverdata = data;
   4.231      return 0;
   4.232  }
   4.233  
   4.234 @@ -313,7 +340,7 @@
   4.235      Atom _NET_WM_WINDOW_TYPE_NORMAL;
   4.236      Atom _NET_WM_PID;
   4.237      int wmstate_count;
   4.238 -    Atom wmstate_atoms[3];
   4.239 +    Atom wmstate_atoms[5];
   4.240      Uint32 fevent = 0;
   4.241  
   4.242  #if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
   4.243 @@ -719,8 +746,9 @@
   4.244      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   4.245      Display *display = data->videodata->display;
   4.246  
   4.247 -    if (SDL_IsShapedWindow(window))
   4.248 +    if (SDL_IsShapedWindow(window)) {
   4.249          X11_ResizeWindowShape(window);
   4.250 +    }
   4.251      if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
   4.252           /* Apparently, if the X11 Window is set to a 'non-resizable' window, you cannot resize it using the XResizeWindow, thus
   4.253              we must set the size hints to adjust the window size.*/
   4.254 @@ -735,8 +763,9 @@
   4.255           XSetWMNormalHints(display, data->xwindow, sizehints);
   4.256  
   4.257           XFree(sizehints);
   4.258 -    } else
   4.259 +    } else {
   4.260          XResizeWindow(display, data->xwindow, window->w, window->h);
   4.261 +    }
   4.262      XFlush(display);
   4.263  }
   4.264  
   4.265 @@ -821,7 +850,6 @@
   4.266      Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
   4.267      Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
   4.268      Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
   4.269 -    Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
   4.270  
   4.271      if (X11_IsWindowMapped(_this, window)) {
   4.272          XEvent e;
   4.273 @@ -840,16 +868,17 @@
   4.274          XSendEvent(display, RootWindow(display, displaydata->screen), 0,
   4.275                     SubstructureNotifyMask | SubstructureRedirectMask, &e);
   4.276      } else {
   4.277 -        int count = 0;
   4.278 -        Atom atoms[3];
   4.279 +        int count;
   4.280 +        Uint32 flags;
   4.281 +        Atom atoms[5];
   4.282  
   4.283 -        if (window->flags & SDL_WINDOW_FULLSCREEN) {
   4.284 -            atoms[count++] = _NET_WM_STATE_FULLSCREEN;
   4.285 -        }
   4.286 +        flags = window->flags;
   4.287          if (maximized) {
   4.288 -            atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT;
   4.289 -            atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
   4.290 +            flags |= SDL_WINDOW_MAXIMIZED;
   4.291 +        } else {
   4.292 +            flags &= ~SDL_WINDOW_MAXIMIZED;
   4.293          }
   4.294 +        count = X11_GetWMStateProperty(_this, flags, atoms);
   4.295          if (count > 0) {
   4.296              XChangeProperty(display, data->xwindow, _NET_WM_STATE, XA_ATOM, 32,
   4.297                              PropModeReplace, (unsigned char *)atoms, count);
   4.298 @@ -885,31 +914,6 @@
   4.299      X11_ShowWindow(_this, window);
   4.300  }
   4.301  
   4.302 -static Bool
   4.303 -isActionAllowed(SDL_WindowData *data, Atom action)
   4.304 -{
   4.305 -    Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS;
   4.306 -    Atom type;
   4.307 -    Display *display = data->videodata->display;
   4.308 -    int form;
   4.309 -    unsigned long remain;
   4.310 -    unsigned long len, i;
   4.311 -    Atom *list;
   4.312 -    Bool ret = False;
   4.313 -    if (XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success)
   4.314 -    {
   4.315 -        for (i=0; i<len; ++i)
   4.316 -        {
   4.317 -            if (list[i] == action) {
   4.318 -                ret = True;
   4.319 -                break;
   4.320 -            }
   4.321 -        }
   4.322 -        XFree(list);
   4.323 -    }
   4.324 -    return ret;
   4.325 -}
   4.326 -
   4.327  /* This asks the Window Manager to handle fullscreen for us. Most don't do it right, though. */
   4.328  static void
   4.329  X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen)
   4.330 @@ -918,15 +922,13 @@
   4.331      SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
   4.332      Display *display = data->videodata->display;
   4.333      Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
   4.334 -    Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
   4.335 -    Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
   4.336      Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
   4.337 +    Atom _NET_WM_ACTION_FULLSCREEN = data->videodata->_NET_WM_ACTION_FULLSCREEN;
   4.338  
   4.339      if (X11_IsWindowMapped(_this, window)) {
   4.340          XEvent e;
   4.341  
   4.342 -        if (isActionAllowed(data, data->videodata->_NET_WM_ACTION_FULLSCREEN) == False)
   4.343 -        {
   4.344 +        if (!X11_IsActionAllowed(window, _NET_WM_ACTION_FULLSCREEN)) {
   4.345              /* We aren't allowed to go into fullscreen mode... */
   4.346              if ((window->flags & SDL_WINDOW_RESIZABLE) == 0) {
   4.347                  /* ...and we aren't resizable. Compiz refuses fullscreen toggle in this case. */
   4.348 @@ -961,16 +963,17 @@
   4.349          XSendEvent(display, RootWindow(display, displaydata->screen), 0,
   4.350                     SubstructureNotifyMask | SubstructureRedirectMask, &e);
   4.351      } else {
   4.352 -        int count = 0;
   4.353 -        Atom atoms[3];
   4.354 +        int count;
   4.355 +        Uint32 flags;
   4.356 +        Atom atoms[5];
   4.357  
   4.358 +        flags = window->flags;
   4.359          if (fullscreen) {
   4.360 -            atoms[count++] = _NET_WM_STATE_FULLSCREEN;
   4.361 +            flags |= SDL_WINDOW_FULLSCREEN;
   4.362 +        } else {
   4.363 +            flags &= ~SDL_WINDOW_FULLSCREEN;
   4.364          }
   4.365 -        if (window->flags & SDL_WINDOW_MAXIMIZED) {
   4.366 -            atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT;
   4.367 -            atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
   4.368 -        }
   4.369 +        count = X11_GetWMStateProperty(_this, flags, atoms);
   4.370          if (count > 0) {
   4.371              XChangeProperty(display, data->xwindow, _NET_WM_STATE, XA_ATOM, 32,
   4.372                              PropModeReplace, (unsigned char *)atoms, count);
     5.1 --- a/src/video/x11/SDL_x11window.h	Thu Sep 27 17:17:33 2012 -0700
     5.2 +++ b/src/video/x11/SDL_x11window.h	Thu Sep 27 23:55:38 2012 -0700
     5.3 @@ -42,6 +42,9 @@
     5.4      struct SDL_VideoData *videodata;
     5.5  } SDL_WindowData;
     5.6  
     5.7 +extern int X11_GetWMStateProperty(_THIS, Uint32 flags, Atom atoms[5]);
     5.8 +extern Uint32 X11_GetNetWMState(_THIS, SDL_Window * window);
     5.9 +
    5.10  extern int X11_CreateWindow(_THIS, SDL_Window * window);
    5.11  extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
    5.12  extern char *X11_GetWindowTitle(_THIS, Window xwindow);