Fixed setting fullscreen and maximized states for windows that haven't been mapped yet.
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 + if (X11_IsWindowMapped(_this, window)) {
1.118 + XEvent e;
1.119 +
1.120 + e.xany.type = ClientMessage;
1.121 + e.xclient.message_type = _NET_WM_STATE;
1.122 + e.xclient.format = 32;
1.123 + e.xclient.window = data->xwindow;
1.124 + e.xclient.data.l[0] =
1.125 + maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1.126 + e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
1.127 + e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
1.128 + e.xclient.data.l[3] = 0l;
1.129
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.data.l[0] =
1.134 - maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1.135 - e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
1.136 - e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
1.137 - e.xclient.data.l[3] = 0l;
1.138 + XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1.139 + SubstructureNotifyMask | SubstructureRedirectMask, &e);
1.140 + } else {
1.141 + int count = 0;
1.142 + Atom atoms[3];
1.143
1.144 - XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1.145 - SubstructureNotifyMask | SubstructureRedirectMask, &e);
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)) {