Lots of prep for the "real" way to support fullscreen mode on modern window managers.
authorSam Lantinga
Tue, 13 Jul 2010 23:11:10 -0700
changeset 4518a956a315fe67
parent 4517 7b5e4396bcaa
child 4519 62d693e01a24
Lots of prep for the "real" way to support fullscreen mode on modern window managers.

Unfortunately, this doesn't work. I also noticed that maximizing doesn't work as well. Also xprop hangs when trying to list properties of SDL windows.... ???
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11modes.c
src/video/x11/SDL_x11sym.h
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	Tue Jul 13 23:05:14 2010 -0700
     1.2 +++ b/src/video/x11/SDL_x11events.c	Tue Jul 13 23:11:10 2010 -0700
     1.3 @@ -34,18 +34,19 @@
     1.4  #include "SDL_timer.h"
     1.5  #include "SDL_syswm.h"
     1.6  
     1.7 -/*#define DEBUG_XEVENTS*/
     1.8 +#define DEBUG_XEVENTS
     1.9  
    1.10  static void
    1.11  X11_DispatchEvent(_THIS)
    1.12  {
    1.13      SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
    1.14 +    Display *display = videodata->display;
    1.15      SDL_WindowData *data;
    1.16      XEvent xevent;
    1.17      int i;
    1.18  
    1.19      SDL_zero(xevent);           /* valgrind fix. --ryan. */
    1.20 -    XNextEvent(videodata->display, &xevent);
    1.21 +    XNextEvent(display, &xevent);
    1.22  
    1.23      /* filter events catchs XIM events and sends them to the correct
    1.24         handler */
    1.25 @@ -80,6 +81,7 @@
    1.26      if (!data) {
    1.27          return;
    1.28      }
    1.29 +
    1.30  #if 0
    1.31      printf("type = %d display = %d window = %d\n",
    1.32             xevent.type, xevent.xany.display, xevent.xany.window);
    1.33 @@ -182,9 +184,8 @@
    1.34  #if 0
    1.35              if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
    1.36                  int min_keycode, max_keycode;
    1.37 -                XDisplayKeycodes(videodata->display, &min_keycode,
    1.38 -                                 &max_keycode);
    1.39 -                keysym = XKeycodeToKeysym(videodata->display, keycode, 0);
    1.40 +                XDisplayKeycodes(display, &min_keycode, &max_keycode);
    1.41 +                keysym = XKeycodeToKeysym(display, keycode, 0);
    1.42                  fprintf(stderr,
    1.43                          "The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <sdl@libsdl.org> X11 KeyCode %d (%d), X11 KeySym 0x%X (%s).\n",
    1.44                          keycode, keycode - min_keycode, keysym,
    1.45 @@ -289,9 +290,58 @@
    1.46          }
    1.47          break;
    1.48  
    1.49 +    case PropertyNotify:{
    1.50 +#ifdef DEBUG_XEVENTS
    1.51 +            char *name = XGetAtomName(display, xevent.xproperty.atom);
    1.52 +            printf("PropertyNotify (atom = %s)\n", name ? name : "NULL");
    1.53 +            if (name) {
    1.54 +                XFree(name);
    1.55 +            }
    1.56 +#endif
    1.57 +            if (xevent.xproperty.atom == videodata->_NET_WM_STATE) {
    1.58 +                unsigned char *propdata;
    1.59 +                int status, real_format;
    1.60 +                Atom real_type;
    1.61 +                unsigned long items_read, items_left, i;
    1.62 +
    1.63 +#ifdef DEBUG_XEVENTS
    1.64 +                printf("_NET_WM_STATE: {");
    1.65 +#endif
    1.66 +                status = XGetWindowProperty(display, data->xwindow, videodata->_NET_WM_STATE, 0L, 8192L, False, XA_ATOM, &real_type, &real_format, &items_read, &items_left, &propdata);
    1.67 +                if (status == Success) {
    1.68 +                    Atom *atoms = (Atom *)propdata;
    1.69 +                    for (i = 0; i < items_read; i++) {
    1.70 +                        if (atoms[i] == videodata->_NET_WM_STATE_HIDDEN) {
    1.71 +#ifdef DEBUG_XEVENTS
    1.72 +                            printf(" _NET_WM_STATE_HIDDEN");
    1.73 +#endif
    1.74 +                        }
    1.75 +                        if (atoms[i] == videodata->_NET_WM_STATE_MAXIMIZED_HORZ) {
    1.76 +#ifdef DEBUG_XEVENTS
    1.77 +                            printf(" _NET_WM_STATE_MAXIMIZED_HORZ");
    1.78 +#endif
    1.79 +                        }
    1.80 +                        if (atoms[i] == videodata->_NET_WM_STATE_MAXIMIZED_VERT) {
    1.81 +#ifdef DEBUG_XEVENTS
    1.82 +                            printf(" _NET_WM_STATE_MAXIMIZED_VERT");
    1.83 +#endif
    1.84 +                        }
    1.85 +                        if (atoms[i] == videodata->_NET_WM_STATE_FULLSCREEN) {
    1.86 +#ifdef DEBUG_XEVENTS
    1.87 +                            printf(" _NET_WM_STATE_FULLSCREEN");
    1.88 +#endif
    1.89 +                        }
    1.90 +                    }
    1.91 +                }
    1.92 +#ifdef DEBUG_XEVENTS
    1.93 +                printf(" }\n");
    1.94 +#endif
    1.95 +            }
    1.96 +        }
    1.97 +        break;
    1.98 +
    1.99      /* Copy the selection from XA_CUT_BUFFER0 to the requested property */
   1.100      case SelectionRequest: {
   1.101 -            Display *display = videodata->display;
   1.102              XSelectionRequestEvent *req;
   1.103              XEvent sevent;
   1.104              int seln_format;
     2.1 --- a/src/video/x11/SDL_x11modes.c	Tue Jul 13 23:05:14 2010 -0700
     2.2 +++ b/src/video/x11/SDL_x11modes.c	Tue Jul 13 23:11:10 2010 -0700
     2.3 @@ -23,7 +23,7 @@
     2.4  
     2.5  #include "SDL_x11video.h"
     2.6  
     2.7 -//#define X11MODES_DEBUG
     2.8 +#define X11MODES_DEBUG
     2.9  #undef SDL_VIDEO_DRIVER_X11_XINERAMA
    2.10  #undef SDL_VIDEO_DRIVER_X11_XRANDR
    2.11  #undef SDL_VIDEO_DRIVER_X11_VIDMODE
    2.12 @@ -253,6 +253,7 @@
    2.13      return SDL_TRUE;
    2.14  }
    2.15  
    2.16 +static
    2.17  Bool SDL_NAME(XF86VidModeGetModeInfo) (Display * dpy, int scr,
    2.18                                         SDL_NAME(XF86VidModeModeInfo) * info)
    2.19  {
    2.20 @@ -296,6 +297,7 @@
    2.21                                        &data->saved_view.y);
    2.22  }
    2.23  
    2.24 +/*
    2.25  static void
    2.26  restore_mode(Display * display, SDL_DisplayData * data)
    2.27  {
    2.28 @@ -313,6 +315,7 @@
    2.29                                            data->saved_view.y);
    2.30      }
    2.31  }
    2.32 +*/
    2.33  #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
    2.34  
    2.35  void
     3.1 --- a/src/video/x11/SDL_x11sym.h	Tue Jul 13 23:05:14 2010 -0700
     3.2 +++ b/src/video/x11/SDL_x11sym.h	Tue Jul 13 23:11:10 2010 -0700
     3.3 @@ -67,12 +67,14 @@
     3.4  SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return)
     3.5  SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return)
     3.6  SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return)
     3.7 +SDL_X11_SYM(char*,XGetAtomName,(Display *a,Atom b),(a,b),return)
     3.8  SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return)
     3.9  SDL_X11_SYM(XImage*,XGetImage,(Display* a,Drawable b,int c,int d,unsigned int e,unsigned int f,unsigned long g, int h),(a,b,c,d,e,f,g,h),return)
    3.10  SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return)
    3.11  SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return)
    3.12  SDL_X11_SYM(int,XGetRGBColormaps,(Display* a,Window b,XStandardColormap **c,int *d,Atom e),(a,b,c,d,e),return)
    3.13  SDL_X11_SYM(Window,XGetSelectionOwner,(Display* a,Atom b),(a,b),return)
    3.14 +SDL_X11_SYM(Status,XGetTextProperty,(Display *a,Window b,XTextProperty *c,Atom d),(a,b,c,d),return)
    3.15  SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return)
    3.16  SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return)
    3.17  SDL_X11_SYM(int,XGetWindowProperty,(Display* a,Window b,Atom c,long d,long e,Bool f,Atom g,Atom* h,int* i,unsigned long* j,unsigned long *k,unsigned char **l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
     4.1 --- a/src/video/x11/SDL_x11video.c	Tue Jul 13 23:05:14 2010 -0700
     4.2 +++ b/src/video/x11/SDL_x11video.c	Tue Jul 13 23:11:10 2010 -0700
     4.3 @@ -242,6 +242,43 @@
     4.4  };
     4.5  
     4.6  
     4.7 +static void
     4.8 +X11_CheckWindowManager(_THIS)
     4.9 +{
    4.10 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    4.11 +    Display *display = data->display;
    4.12 +    Atom _NET_SUPPORTING_WM_CHECK;
    4.13 +    int status, real_format;
    4.14 +    Atom real_type;
    4.15 +    unsigned long items_read, items_left;
    4.16 +    unsigned char *propdata;
    4.17 +    Window wm_window = 0;
    4.18 +#ifdef DEBUG_WINDOW_MANAGER
    4.19 +    char *wm_name;
    4.20 +#endif
    4.21 +
    4.22 +    _NET_SUPPORTING_WM_CHECK = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
    4.23 +    status = XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
    4.24 +    if (status == Success && items_read) {
    4.25 +        wm_window = ((Window*)propdata)[0];
    4.26 +    }
    4.27 +    XFree(propdata);
    4.28 +
    4.29 +    if (!wm_window) {
    4.30 +#ifdef DEBUG_WINDOW_MANAGER
    4.31 +        printf("Couldn't get _NET_SUPPORTING_WM_CHECK property\n");
    4.32 +#endif
    4.33 +        return;
    4.34 +    }
    4.35 +    data->net_wm = SDL_TRUE;
    4.36 +
    4.37 +#ifdef DEBUG_WINDOW_MANAGER
    4.38 +    wm_name = X11_GetWindowTitle(_this, wm_window);
    4.39 +    printf("Window manager: %s\n", wm_name);
    4.40 +    SDL_free(wm_name);
    4.41 +#endif
    4.42 +}
    4.43 +
    4.44  int
    4.45  X11_VideoInit(_THIS)
    4.46  {
    4.47 @@ -259,8 +296,20 @@
    4.48  #endif
    4.49  
    4.50      /* Look up some useful Atoms */
    4.51 -    data->WM_DELETE_WINDOW =
    4.52 -        XInternAtom(data->display, "WM_DELETE_WINDOW", False);
    4.53 +#define GET_ATOM(X) data->X = XInternAtom(data->display, #X, False)
    4.54 +    GET_ATOM(WM_DELETE_WINDOW);
    4.55 +    GET_ATOM(_NET_WM_STATE);
    4.56 +    GET_ATOM(_NET_WM_STATE_HIDDEN);
    4.57 +    GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
    4.58 +    GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
    4.59 +    GET_ATOM(_NET_WM_STATE_FULLSCREEN);
    4.60 +    GET_ATOM(_NET_WM_NAME);
    4.61 +    GET_ATOM(_NET_WM_ICON_NAME);
    4.62 +    GET_ATOM(_NET_WM_ICON);
    4.63 +    GET_ATOM(UTF8_STRING);
    4.64 +
    4.65 +    /* Detect the window manager */
    4.66 +    X11_CheckWindowManager(_this);
    4.67  
    4.68      if (X11_InitModes(_this) < 0) {
    4.69          return -1;
     5.1 --- a/src/video/x11/SDL_x11video.h	Tue Jul 13 23:05:14 2010 -0700
     5.2 +++ b/src/video/x11/SDL_x11video.h	Tue Jul 13 23:11:10 2010 -0700
     5.3 @@ -68,7 +68,22 @@
     5.4      int numwindows;
     5.5      SDL_WindowData **windowlist;
     5.6      int windowlistlength;
     5.7 +
     5.8 +    /* This is true for ICCCM2.0-compliant window managers */
     5.9 +    SDL_bool net_wm;
    5.10 +
    5.11 +    /* Useful atoms */
    5.12      Atom WM_DELETE_WINDOW;
    5.13 +    Atom _NET_WM_STATE;
    5.14 +    Atom _NET_WM_STATE_HIDDEN;
    5.15 +    Atom _NET_WM_STATE_MAXIMIZED_VERT;
    5.16 +    Atom _NET_WM_STATE_MAXIMIZED_HORZ;
    5.17 +    Atom _NET_WM_STATE_FULLSCREEN;
    5.18 +    Atom _NET_WM_NAME;
    5.19 +    Atom _NET_WM_ICON_NAME;
    5.20 +    Atom _NET_WM_ICON;
    5.21 +    Atom UTF8_STRING;
    5.22 +
    5.23      SDL_scancode key_layout[256];
    5.24      SDL_bool selection_waiting;
    5.25  } SDL_VideoData;
     6.1 --- a/src/video/x11/SDL_x11window.c	Tue Jul 13 23:05:14 2010 -0700
     6.2 +++ b/src/video/x11/SDL_x11window.c	Tue Jul 13 23:11:10 2010 -0700
     6.3 @@ -42,6 +42,20 @@
     6.4  #define _NET_WM_STATE_ADD       1l
     6.5  #define _NET_WM_STATE_TOGGLE    2l
     6.6  
     6.7 +static SDL_bool
     6.8 +X11_WindowIsOldstyleFullscreen(SDL_Window * window)
     6.9 +{
    6.10 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    6.11 +    SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
    6.12 +
    6.13 +    /* ICCCM2.0-compliant window managers can handle fullscreen windows */
    6.14 +    if ((window->flags & SDL_WINDOW_FULLSCREEN) && !videodata->net_wm) {
    6.15 +        return SDL_TRUE;
    6.16 +    } else {
    6.17 +        return SDL_FALSE;
    6.18 +    }
    6.19 +}
    6.20 +
    6.21  static void
    6.22  X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
    6.23  {
    6.24 @@ -128,14 +142,10 @@
    6.25      }
    6.26  
    6.27      {
    6.28 -        Atom _NET_WM_STATE =
    6.29 -            XInternAtom(data->videodata->display, "_NET_WM_STATE", False);
    6.30 -        Atom _NET_WM_STATE_MAXIMIZED_VERT =
    6.31 -            XInternAtom(data->videodata->display,
    6.32 -                        "_NET_WM_STATE_MAXIMIZED_VERT", False);
    6.33 -        Atom _NET_WM_STATE_MAXIMIZED_HORZ =
    6.34 -            XInternAtom(data->videodata->display,
    6.35 -                        "_NET_WM_STATE_MAXIMIZED_HORZ", False);
    6.36 +        Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
    6.37 +        Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
    6.38 +        Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
    6.39 +        Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
    6.40          Atom actualType;
    6.41          int actualFormat;
    6.42          unsigned long i, numItems, bytesAfter;
    6.43 @@ -148,19 +158,21 @@
    6.44                                 &propertyValue) == Success) {
    6.45              Atom *atoms = (Atom *) propertyValue;
    6.46              int maximized = 0;
    6.47 +            int fullscreen = 0;
    6.48  
    6.49              for (i = 0; i < numItems; ++i) {
    6.50                  if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
    6.51                      maximized |= 1;
    6.52                  } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
    6.53                      maximized |= 2;
    6.54 +                } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) {
    6.55 +                    fullscreen = 1;
    6.56                  }
    6.57 -                /* Might also want to check the following properties:
    6.58 -                   _NET_WM_STATE_ABOVE, _NET_WM_STATE_FULLSCREEN
    6.59 -                 */
    6.60              }
    6.61              if (maximized == 3) {
    6.62                  window->flags |= SDL_WINDOW_MAXIMIZED;
    6.63 +            }  else if (fullscreen == 1) {
    6.64 +                window->flags |= SDL_WINDOW_FULLSCREEN;
    6.65              }
    6.66              XFree(propertyValue);
    6.67          }
    6.68 @@ -180,11 +192,6 @@
    6.69         } else {
    6.70         window->flags &= ~SDL_WINDOW_RESIZABLE;
    6.71         }
    6.72 -       if (style & WS_MAXIMIZE) {
    6.73 -       window->flags |= SDL_WINDOW_MAXIMIZED;
    6.74 -       } else {
    6.75 -       window->flags &= ~SDL_WINDOW_MAXIMIZED;
    6.76 -       }
    6.77         if (style & WS_MINIMIZE) {
    6.78         window->flags |= SDL_WINDOW_MINIMIZED;
    6.79         } else {
    6.80 @@ -225,6 +232,14 @@
    6.81      XSizeHints *sizehints;
    6.82      XWMHints *wmhints;
    6.83      XClassHint *classhints;
    6.84 +    SDL_bool oldstyle_fullscreen;
    6.85 +
    6.86 +    /* ICCCM2.0-compliant window managers can handle fullscreen windows */
    6.87 +    if ((window->flags & SDL_WINDOW_FULLSCREEN) && !data->net_wm) {
    6.88 +        oldstyle_fullscreen = SDL_TRUE;
    6.89 +    } else {
    6.90 +        oldstyle_fullscreen = SDL_FALSE;
    6.91 +    }
    6.92  
    6.93  #if SDL_VIDEO_DRIVER_X11_XINERAMA
    6.94  /* FIXME
    6.95 @@ -265,7 +280,7 @@
    6.96          depth = displaydata->depth;
    6.97      }
    6.98  
    6.99 -    if (window->flags & SDL_WINDOW_FULLSCREEN) {
   6.100 +    if (oldstyle_fullscreen) {
   6.101          xattr.override_redirect = True;
   6.102      } else {
   6.103          xattr.override_redirect = False;
   6.104 @@ -417,7 +432,6 @@
   6.105              }
   6.106  
   6.107              /* OK, we got a colormap, now fill it in as best as we can */
   6.108 -
   6.109              colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
   6.110              if (NULL == colorcells) {
   6.111                  SDL_SetError("out of memory in X11_CreateWindow");
   6.112 @@ -494,7 +508,7 @@
   6.113                              visual, AllocNone);
   6.114      }
   6.115  
   6.116 -    if ((window->flags & SDL_WINDOW_FULLSCREEN)
   6.117 +    if (oldstyle_fullscreen
   6.118          || window->x == SDL_WINDOWPOS_CENTERED) {
   6.119          X11_GetDisplaySize(_this, window, &x, NULL);
   6.120          x = (x - window->w) / 2;
   6.121 @@ -503,7 +517,7 @@
   6.122      } else {
   6.123          x = window->x;
   6.124      }
   6.125 -    if ((window->flags & SDL_WINDOW_FULLSCREEN)
   6.126 +    if (oldstyle_fullscreen
   6.127          || window->y == SDL_WINDOWPOS_CENTERED) {
   6.128          X11_GetDisplaySize(_this, window, NULL, &y);
   6.129          y = (y - window->h) / 2;
   6.130 @@ -539,12 +553,12 @@
   6.131      sizehints = XAllocSizeHints();
   6.132      if (sizehints) {
   6.133          if (!(window->flags & SDL_WINDOW_RESIZABLE)
   6.134 -            || (window->flags & SDL_WINDOW_FULLSCREEN)) {
   6.135 +            || oldstyle_fullscreen) {
   6.136              sizehints->min_width = sizehints->max_width = window->w;
   6.137              sizehints->min_height = sizehints->max_height = window->h;
   6.138              sizehints->flags = PMaxSize | PMinSize;
   6.139          }
   6.140 -        if (!(window->flags & SDL_WINDOW_FULLSCREEN)
   6.141 +        if (!oldstyle_fullscreen
   6.142              && window->x != SDL_WINDOWPOS_UNDEFINED
   6.143              && window->y != SDL_WINDOWPOS_UNDEFINED) {
   6.144              sizehints->x = x;
   6.145 @@ -555,7 +569,7 @@
   6.146          XFree(sizehints);
   6.147      }
   6.148  
   6.149 -    if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) {
   6.150 +    if ((window->flags & SDL_WINDOW_BORDERLESS) || oldstyle_fullscreen) {
   6.151          SDL_bool set;
   6.152          Atom WM_HINTS;
   6.153  
   6.154 @@ -643,23 +657,6 @@
   6.155          }
   6.156      }
   6.157  
   6.158 -    /* Tell KDE to keep fullscreen windows on top */
   6.159 -    if (window->flags & SDL_WINDOW_FULLSCREEN) {
   6.160 -        XEvent ev;
   6.161 -
   6.162 -        SDL_zero(ev);
   6.163 -        ev.xclient.type = ClientMessage;
   6.164 -        ev.xclient.window = RootWindow(data->display, displaydata->screen);
   6.165 -        ev.xclient.message_type =
   6.166 -            XInternAtom(data->display, "KWM_KEEP_ON_TOP", False);
   6.167 -        ev.xclient.format = 32;
   6.168 -        ev.xclient.data.l[0] = w;
   6.169 -        ev.xclient.data.l[1] = CurrentTime;
   6.170 -        XSendEvent(data->display,
   6.171 -                   RootWindow(data->display, displaydata->screen), False,
   6.172 -                   SubstructureRedirectMask, &ev);
   6.173 -    }
   6.174 -
   6.175      /* Set the input hints so we get keyboard input */
   6.176      wmhints = XAllocWMHints();
   6.177      if (wmhints) {
   6.178 @@ -678,6 +675,26 @@
   6.179          XFree(classhints);
   6.180      }
   6.181  
   6.182 +    /* FIXME: Why doesn't this work? */
   6.183 +    if (window->flags & SDL_WINDOW_FULLSCREEN) {
   6.184 +        Atom _NET_WM_STATE = data->_NET_WM_STATE;
   6.185 +        Atom _NET_WM_STATE_FULLSCREEN = data->_NET_WM_STATE_FULLSCREEN;
   6.186 +        XEvent e;
   6.187 +
   6.188 +        e.xany.type = ClientMessage;
   6.189 +        e.xclient.display = data->display;
   6.190 +        e.xclient.window = w;
   6.191 +        e.xclient.message_type = _NET_WM_STATE;
   6.192 +        e.xclient.format = 32;
   6.193 +        e.xclient.data.l[0] = _NET_WM_STATE_ADD;
   6.194 +        e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
   6.195 +        e.xclient.data.l[2] = 0l;
   6.196 +
   6.197 +        XSendEvent(data->display,
   6.198 +                   RootWindow(data->display, displaydata->screen), 0,
   6.199 +                   SubstructureNotifyMask | SubstructureRedirectMask, &e);
   6.200 +    }
   6.201 +
   6.202      /* Allow the window to be deleted by the window manager */
   6.203      XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
   6.204  
   6.205 @@ -716,7 +733,7 @@
   6.206  {
   6.207      Window w = (Window) data;
   6.208  
   6.209 -    /* FIXME: Query the title from the existing window */
   6.210 +    window->title = X11_GetWindowTitle(_this, w);
   6.211  
   6.212      if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
   6.213          return -1;
   6.214 @@ -724,6 +741,36 @@
   6.215      return 0;
   6.216  }
   6.217  
   6.218 +char *
   6.219 +X11_GetWindowTitle(_THIS, Window xwindow)
   6.220 +{
   6.221 +    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
   6.222 +    Display *display = data->display;
   6.223 +    int status, real_format;
   6.224 +    Atom real_type;
   6.225 +    unsigned long items_read, items_left;
   6.226 +    unsigned char *propdata;
   6.227 +    char *title = NULL;
   6.228 +
   6.229 +    status = XGetWindowProperty(display, xwindow, data->_NET_WM_NAME,
   6.230 +                0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format,
   6.231 +                &items_read, &items_left, &propdata);
   6.232 +    if (status == Success) {
   6.233 +        title = SDL_strdup(SDL_static_cast(char*, propdata));
   6.234 +        XFree(propdata);
   6.235 +    } else {
   6.236 +        status = XGetWindowProperty(display, xwindow, XA_WM_NAME,
   6.237 +                    0L, 8192L, False, XA_STRING, &real_type, &real_format,
   6.238 +                    &items_read, &items_left, &propdata);
   6.239 +        if (status == Success) {
   6.240 +            title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
   6.241 +        } else {
   6.242 +            title = SDL_strdup("");
   6.243 +        }
   6.244 +    }
   6.245 +    return title;
   6.246 +}
   6.247 +
   6.248  void
   6.249  X11_SetWindowTitle(_THIS, SDL_Window * window)
   6.250  {
   6.251 @@ -735,14 +782,8 @@
   6.252      const char *icon = NULL;
   6.253  
   6.254  #ifdef X_HAVE_UTF8_STRING
   6.255 -    Atom _NET_WM_NAME = 0;
   6.256 -    Atom _NET_WM_ICON_NAME = 0;
   6.257 -
   6.258 -    /* Look up some useful Atoms */
   6.259 -    if (SDL_X11_HAVE_UTF8) {
   6.260 -        _NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", False);
   6.261 -        _NET_WM_ICON_NAME = XInternAtom(display, "_NET_WM_ICON_NAME", False);
   6.262 -    }
   6.263 +    Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
   6.264 +    Atom _NET_WM_ICON_NAME = data->videodata->_NET_WM_ICON_NAME;
   6.265  #endif
   6.266  
   6.267      if (title != NULL) {
   6.268 @@ -803,7 +844,7 @@
   6.269  {
   6.270      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   6.271      Display *display = data->videodata->display;
   6.272 -    Atom _NET_WM_ICON = XInternAtom(display, "_NET_WM_ICON", False);
   6.273 +    Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON;
   6.274  
   6.275      if (icon) {
   6.276          SDL_PixelFormat format;
   6.277 @@ -842,16 +883,20 @@
   6.278  {
   6.279      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   6.280      Display *display = data->videodata->display;
   6.281 +    SDL_bool oldstyle_fullscreen;
   6.282      int x, y;
   6.283  
   6.284 -    if ((window->flags & SDL_WINDOW_FULLSCREEN)
   6.285 +    /* ICCCM2.0-compliant window managers can handle fullscreen windows */
   6.286 +    oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
   6.287 +
   6.288 +    if (oldstyle_fullscreen
   6.289          || window->x == SDL_WINDOWPOS_CENTERED) {
   6.290          X11_GetDisplaySize(_this, window, &x, NULL);
   6.291          x = (x - window->w) / 2;
   6.292      } else {
   6.293          x = window->x;
   6.294      }
   6.295 -    if ((window->flags & SDL_WINDOW_FULLSCREEN)
   6.296 +    if (oldstyle_fullscreen
   6.297          || window->y == SDL_WINDOWPOS_CENTERED) {
   6.298          X11_GetDisplaySize(_this, window, NULL, &y);
   6.299          y = (y - window->h) / 2;
   6.300 @@ -904,15 +949,14 @@
   6.301      SDL_DisplayData *displaydata =
   6.302          (SDL_DisplayData *) window->display->driverdata;
   6.303      Display *display = data->videodata->display;
   6.304 -    Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", False);
   6.305 -    Atom _NET_WM_STATE_MAXIMIZED_VERT =
   6.306 -        XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
   6.307 -    Atom _NET_WM_STATE_MAXIMIZED_HORZ =
   6.308 -        XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
   6.309 +    Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
   6.310 +    Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
   6.311 +    Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
   6.312      XEvent e;
   6.313  
   6.314      e.xany.type = ClientMessage;
   6.315 -    e.xany.window = data->xwindow;
   6.316 +    e.xclient.display = display;
   6.317 +    e.xclient.window = data->xwindow;
   6.318      e.xclient.message_type = _NET_WM_STATE;
   6.319      e.xclient.format = 32;
   6.320      e.xclient.data.l[0] =
   6.321 @@ -920,7 +964,6 @@
   6.322      e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
   6.323      e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
   6.324      e.xclient.data.l[3] = 0l;
   6.325 -    e.xclient.data.l[4] = 0l;
   6.326  
   6.327      XSendEvent(display, RootWindow(display, displaydata->screen), 0,
   6.328                 SubstructureNotifyMask | SubstructureRedirectMask, &e);
   6.329 @@ -935,7 +978,12 @@
   6.330  void
   6.331  X11_MinimizeWindow(_THIS, SDL_Window * window)
   6.332  {
   6.333 -    X11_HideWindow(_this, window);
   6.334 +    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   6.335 +    SDL_DisplayData *displaydata =
   6.336 +        (SDL_DisplayData *) window->display->driverdata;
   6.337 +    Display *display = data->videodata->display;
   6.338 + 
   6.339 +    XIconifyWindow(display, data->xwindow, displaydata->screen);
   6.340  }
   6.341  
   6.342  void
   6.343 @@ -950,8 +998,12 @@
   6.344  {
   6.345      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   6.346      Display *display = data->videodata->display;
   6.347 +    SDL_bool oldstyle_fullscreen;
   6.348  
   6.349 -    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
   6.350 +    /* ICCCM2.0-compliant window managers can handle fullscreen windows */
   6.351 +    oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
   6.352 +
   6.353 +    if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen)
   6.354          && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   6.355          /* Try to grab the mouse */
   6.356          for (;;) {
     7.1 --- a/src/video/x11/SDL_x11window.h	Tue Jul 13 23:05:14 2010 -0700
     7.2 +++ b/src/video/x11/SDL_x11window.h	Tue Jul 13 23:11:10 2010 -0700
     7.3 @@ -35,6 +35,7 @@
     7.4  
     7.5  extern int X11_CreateWindow(_THIS, SDL_Window * window);
     7.6  extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
     7.7 +extern char *X11_GetWindowTitle(_THIS, Window xwindow);
     7.8  extern void X11_SetWindowTitle(_THIS, SDL_Window * window);
     7.9  extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
    7.10  extern void X11_SetWindowPosition(_THIS, SDL_Window * window);