Fixed setting fullscreen and maximized states for windows that haven't been mapped yet.
authorSam Lantinga <slouken@libsdl.org>
Wed, 14 Jul 2010 00:56:08 -0700
changeset 4522a4da6b906abb
parent 4521 50125e8aab94
child 4523 657bea918a30
Fixed setting fullscreen and maximized states for windows that haven't been mapped yet.
src/video/x11/SDL_x11window.c
     1.1 --- a/src/video/x11/SDL_x11window.c	Wed Jul 14 00:28:15 2010 -0700
     1.2 +++ b/src/video/x11/SDL_x11window.c	Wed Jul 14 00:56:08 2010 -0700
     1.3 @@ -43,10 +43,9 @@
     1.4  #define _NET_WM_STATE_TOGGLE    2l
     1.5  
     1.6  static SDL_bool
     1.7 -X11_WindowIsOldstyleFullscreen(SDL_Window * window)
     1.8 +X11_IsWindowOldFullscreen(_THIS, SDL_Window * window)
     1.9  {
    1.10 -    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    1.11 -    SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
    1.12 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    1.13  
    1.14      /* ICCCM2.0-compliant window managers can handle fullscreen windows */
    1.15      if ((window->flags & SDL_WINDOW_FULLSCREEN) && !videodata->net_wm) {
    1.16 @@ -56,6 +55,37 @@
    1.17      }
    1.18  }
    1.19  
    1.20 +static SDL_bool
    1.21 +X11_IsWindowMapped(_THIS, SDL_Window * window)
    1.22 +{
    1.23 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    1.24 +    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    1.25 +    XWindowAttributes attr;
    1.26 +
    1.27 +    XGetWindowAttributes(videodata->display, data->xwindow, &attr);
    1.28 +    if (attr.map_state != IsUnmapped) {
    1.29 +        return SDL_TRUE;
    1.30 +    } else {
    1.31 +        return SDL_FALSE;
    1.32 +    }
    1.33 +}
    1.34 +
    1.35 +static int
    1.36 +X11_GetWMStateProperty(_THIS, SDL_Window * window, Atom atoms[3])
    1.37 +{
    1.38 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    1.39 +    int count = 0;
    1.40 +
    1.41 +    if (window->flags & SDL_WINDOW_FULLSCREEN) {
    1.42 +        atoms[count++] = data->_NET_WM_STATE_FULLSCREEN;
    1.43 +    }
    1.44 +    if (window->flags & SDL_WINDOW_MAXIMIZED) {
    1.45 +        atoms[count++] = data->_NET_WM_STATE_MAXIMIZED_VERT;
    1.46 +        atoms[count++] = data->_NET_WM_STATE_MAXIMIZED_HORZ;
    1.47 +    }
    1.48 +    return count;
    1.49 +}
    1.50 +
    1.51  static void
    1.52  X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
    1.53  {
    1.54 @@ -237,13 +267,11 @@
    1.55      SDL_bool oldstyle_fullscreen;
    1.56      Atom _NET_WM_WINDOW_TYPE;
    1.57      Atom _NET_WM_WINDOW_TYPE_NORMAL;
    1.58 +    int wmstate_count;
    1.59 +    Atom wmstate_atoms[3];
    1.60  
    1.61      /* ICCCM2.0-compliant window managers can handle fullscreen windows */
    1.62 -    if ((window->flags & SDL_WINDOW_FULLSCREEN) && !data->net_wm) {
    1.63 -        oldstyle_fullscreen = SDL_TRUE;
    1.64 -    } else {
    1.65 -        oldstyle_fullscreen = SDL_FALSE;
    1.66 -    }
    1.67 +    oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window);
    1.68  
    1.69  #if SDL_VIDEO_DRIVER_X11_XINERAMA
    1.70  /* FIXME
    1.71 @@ -665,21 +693,14 @@
    1.72          XFree(classhints);
    1.73      }
    1.74  
    1.75 -    /* FIXME: Why doesn't this work? */
    1.76 -    if (window->flags & SDL_WINDOW_FULLSCREEN) {
    1.77 -        Atom _NET_WM_STATE = data->_NET_WM_STATE;
    1.78 -        Atom _NET_WM_STATE_FULLSCREEN = data->_NET_WM_STATE_FULLSCREEN;
    1.79 -        XEvent e;
    1.80 -
    1.81 -        e.xany.type = ClientMessage;
    1.82 -        e.xclient.message_type = _NET_WM_STATE;
    1.83 -        e.xclient.format = 32;
    1.84 -        e.xclient.data.l[0] = _NET_WM_STATE_ADD;
    1.85 -        e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
    1.86 -        e.xclient.data.l[2] = 0l;
    1.87 -
    1.88 -        XSendEvent(display, RootWindow(display, screen), 0,
    1.89 -                   SubstructureNotifyMask | SubstructureRedirectMask, &e);
    1.90 +    /* Set the window manager state */
    1.91 +    wmstate_count = X11_GetWMStateProperty(_this, window, wmstate_atoms);
    1.92 +    if (wmstate_count > 0) {
    1.93 +        XChangeProperty(display, w, data->_NET_WM_STATE, XA_ATOM, 32,
    1.94 +                        PropModeReplace,
    1.95 +                        (unsigned char *)wmstate_atoms, wmstate_count);
    1.96 +    } else {
    1.97 +        XDeleteProperty(display, w, data->_NET_WM_STATE);
    1.98      }
    1.99  
   1.100      /* Let the window manager know we're a "normal" window */
   1.101 @@ -881,7 +902,7 @@
   1.102      int x, y;
   1.103  
   1.104      /* ICCCM2.0-compliant window managers can handle fullscreen windows */
   1.105 -    oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
   1.106 +    oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window);
   1.107  
   1.108      if (oldstyle_fullscreen
   1.109          || window->x == SDL_WINDOWPOS_CENTERED) {
   1.110 @@ -946,19 +967,41 @@
   1.111      Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
   1.112      Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
   1.113      Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
   1.114 -    XEvent e;
   1.115 +    Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
   1.116  
   1.117 -    e.xany.type = ClientMessage;
   1.118 -    e.xclient.message_type = _NET_WM_STATE;
   1.119 -    e.xclient.format = 32;
   1.120 -    e.xclient.data.l[0] =
   1.121 -        maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
   1.122 -    e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
   1.123 -    e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
   1.124 -    e.xclient.data.l[3] = 0l;
   1.125 +    if (X11_IsWindowMapped(_this, window)) {
   1.126 +        XEvent e;
   1.127  
   1.128 -    XSendEvent(display, RootWindow(display, displaydata->screen), 0,
   1.129 -               SubstructureNotifyMask | SubstructureRedirectMask, &e);
   1.130 +        e.xany.type = ClientMessage;
   1.131 +        e.xclient.message_type = _NET_WM_STATE;
   1.132 +        e.xclient.format = 32;
   1.133 +        e.xclient.window = data->xwindow;
   1.134 +        e.xclient.data.l[0] =
   1.135 +            maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
   1.136 +        e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
   1.137 +        e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
   1.138 +        e.xclient.data.l[3] = 0l;
   1.139 +
   1.140 +        XSendEvent(display, RootWindow(display, displaydata->screen), 0,
   1.141 +                   SubstructureNotifyMask | SubstructureRedirectMask, &e);
   1.142 +    } else {
   1.143 +        int count = 0;
   1.144 +        Atom atoms[3];
   1.145 +
   1.146 +        if (window->flags & SDL_WINDOW_FULLSCREEN) {
   1.147 +            atoms[count++] = _NET_WM_STATE_FULLSCREEN;
   1.148 +        }
   1.149 +        if (maximized) {
   1.150 +            atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT;
   1.151 +            atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
   1.152 +        }
   1.153 +        if (count > 0) {
   1.154 +            XChangeProperty(display, data->xwindow, _NET_WM_STATE, XA_ATOM, 32,
   1.155 +                            PropModeReplace, (unsigned char *)atoms, count);
   1.156 +        } else {
   1.157 +            XDeleteProperty(display, data->xwindow, _NET_WM_STATE);
   1.158 +        }
   1.159 +    }
   1.160  }
   1.161  
   1.162  void
   1.163 @@ -993,7 +1036,7 @@
   1.164      SDL_bool oldstyle_fullscreen;
   1.165  
   1.166      /* ICCCM2.0-compliant window managers can handle fullscreen windows */
   1.167 -    oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
   1.168 +    oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window);
   1.169  
   1.170      if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen)
   1.171          && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {