comparison src/video/x11/SDL_x11window.c @ 4522:a4da6b906abb

Fixed setting fullscreen and maximized states for windows that haven't been mapped yet.
author Sam Lantinga <slouken@libsdl.org>
date Wed, 14 Jul 2010 00:56:08 -0700
parents 50125e8aab94
children a256e1dadf3f
comparison
equal deleted inserted replaced
4521:50125e8aab94 4522:a4da6b906abb
41 #define _NET_WM_STATE_REMOVE 0l 41 #define _NET_WM_STATE_REMOVE 0l
42 #define _NET_WM_STATE_ADD 1l 42 #define _NET_WM_STATE_ADD 1l
43 #define _NET_WM_STATE_TOGGLE 2l 43 #define _NET_WM_STATE_TOGGLE 2l
44 44
45 static SDL_bool 45 static SDL_bool
46 X11_WindowIsOldstyleFullscreen(SDL_Window * window) 46 X11_IsWindowOldFullscreen(_THIS, SDL_Window * window)
47 { 47 {
48 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 48 SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
49 SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
50 49
51 /* ICCCM2.0-compliant window managers can handle fullscreen windows */ 50 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
52 if ((window->flags & SDL_WINDOW_FULLSCREEN) && !videodata->net_wm) { 51 if ((window->flags & SDL_WINDOW_FULLSCREEN) && !videodata->net_wm) {
53 return SDL_TRUE; 52 return SDL_TRUE;
54 } else { 53 } else {
55 return SDL_FALSE; 54 return SDL_FALSE;
56 } 55 }
56 }
57
58 static SDL_bool
59 X11_IsWindowMapped(_THIS, SDL_Window * window)
60 {
61 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
62 SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
63 XWindowAttributes attr;
64
65 XGetWindowAttributes(videodata->display, data->xwindow, &attr);
66 if (attr.map_state != IsUnmapped) {
67 return SDL_TRUE;
68 } else {
69 return SDL_FALSE;
70 }
71 }
72
73 static int
74 X11_GetWMStateProperty(_THIS, SDL_Window * window, Atom atoms[3])
75 {
76 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
77 int count = 0;
78
79 if (window->flags & SDL_WINDOW_FULLSCREEN) {
80 atoms[count++] = data->_NET_WM_STATE_FULLSCREEN;
81 }
82 if (window->flags & SDL_WINDOW_MAXIMIZED) {
83 atoms[count++] = data->_NET_WM_STATE_MAXIMIZED_VERT;
84 atoms[count++] = data->_NET_WM_STATE_MAXIMIZED_HORZ;
85 }
86 return count;
57 } 87 }
58 88
59 static void 89 static void
60 X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h) 90 X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
61 { 91 {
235 XWMHints *wmhints; 265 XWMHints *wmhints;
236 XClassHint *classhints; 266 XClassHint *classhints;
237 SDL_bool oldstyle_fullscreen; 267 SDL_bool oldstyle_fullscreen;
238 Atom _NET_WM_WINDOW_TYPE; 268 Atom _NET_WM_WINDOW_TYPE;
239 Atom _NET_WM_WINDOW_TYPE_NORMAL; 269 Atom _NET_WM_WINDOW_TYPE_NORMAL;
270 int wmstate_count;
271 Atom wmstate_atoms[3];
240 272
241 /* ICCCM2.0-compliant window managers can handle fullscreen windows */ 273 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
242 if ((window->flags & SDL_WINDOW_FULLSCREEN) && !data->net_wm) { 274 oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window);
243 oldstyle_fullscreen = SDL_TRUE;
244 } else {
245 oldstyle_fullscreen = SDL_FALSE;
246 }
247 275
248 #if SDL_VIDEO_DRIVER_X11_XINERAMA 276 #if SDL_VIDEO_DRIVER_X11_XINERAMA
249 /* FIXME 277 /* FIXME
250 if ( use_xinerama ) { 278 if ( use_xinerama ) {
251 x = xinerama_info.x_org; 279 x = xinerama_info.x_org;
663 classhints->res_class = data->classname; 691 classhints->res_class = data->classname;
664 XSetClassHint(display, w, classhints); 692 XSetClassHint(display, w, classhints);
665 XFree(classhints); 693 XFree(classhints);
666 } 694 }
667 695
668 /* FIXME: Why doesn't this work? */ 696 /* Set the window manager state */
669 if (window->flags & SDL_WINDOW_FULLSCREEN) { 697 wmstate_count = X11_GetWMStateProperty(_this, window, wmstate_atoms);
670 Atom _NET_WM_STATE = data->_NET_WM_STATE; 698 if (wmstate_count > 0) {
671 Atom _NET_WM_STATE_FULLSCREEN = data->_NET_WM_STATE_FULLSCREEN; 699 XChangeProperty(display, w, data->_NET_WM_STATE, XA_ATOM, 32,
672 XEvent e; 700 PropModeReplace,
673 701 (unsigned char *)wmstate_atoms, wmstate_count);
674 e.xany.type = ClientMessage; 702 } else {
675 e.xclient.message_type = _NET_WM_STATE; 703 XDeleteProperty(display, w, data->_NET_WM_STATE);
676 e.xclient.format = 32;
677 e.xclient.data.l[0] = _NET_WM_STATE_ADD;
678 e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
679 e.xclient.data.l[2] = 0l;
680
681 XSendEvent(display, RootWindow(display, screen), 0,
682 SubstructureNotifyMask | SubstructureRedirectMask, &e);
683 } 704 }
684 705
685 /* Let the window manager know we're a "normal" window */ 706 /* Let the window manager know we're a "normal" window */
686 _NET_WM_WINDOW_TYPE = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); 707 _NET_WM_WINDOW_TYPE = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
687 _NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(display, "_NET_WM_WINDOW_TYPE_NORMAL", False); 708 _NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
879 Display *display = data->videodata->display; 900 Display *display = data->videodata->display;
880 SDL_bool oldstyle_fullscreen; 901 SDL_bool oldstyle_fullscreen;
881 int x, y; 902 int x, y;
882 903
883 /* ICCCM2.0-compliant window managers can handle fullscreen windows */ 904 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
884 oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window); 905 oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window);
885 906
886 if (oldstyle_fullscreen 907 if (oldstyle_fullscreen
887 || window->x == SDL_WINDOWPOS_CENTERED) { 908 || window->x == SDL_WINDOWPOS_CENTERED) {
888 X11_GetDisplaySize(_this, window, &x, NULL); 909 X11_GetDisplaySize(_this, window, &x, NULL);
889 x = (x - window->w) / 2; 910 x = (x - window->w) / 2;
944 (SDL_DisplayData *) window->display->driverdata; 965 (SDL_DisplayData *) window->display->driverdata;
945 Display *display = data->videodata->display; 966 Display *display = data->videodata->display;
946 Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; 967 Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
947 Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; 968 Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
948 Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; 969 Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
949 XEvent e; 970 Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
950 971
951 e.xany.type = ClientMessage; 972 if (X11_IsWindowMapped(_this, window)) {
952 e.xclient.message_type = _NET_WM_STATE; 973 XEvent e;
953 e.xclient.format = 32; 974
954 e.xclient.data.l[0] = 975 e.xany.type = ClientMessage;
955 maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; 976 e.xclient.message_type = _NET_WM_STATE;
956 e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT; 977 e.xclient.format = 32;
957 e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ; 978 e.xclient.window = data->xwindow;
958 e.xclient.data.l[3] = 0l; 979 e.xclient.data.l[0] =
959 980 maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
960 XSendEvent(display, RootWindow(display, displaydata->screen), 0, 981 e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
961 SubstructureNotifyMask | SubstructureRedirectMask, &e); 982 e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
983 e.xclient.data.l[3] = 0l;
984
985 XSendEvent(display, RootWindow(display, displaydata->screen), 0,
986 SubstructureNotifyMask | SubstructureRedirectMask, &e);
987 } else {
988 int count = 0;
989 Atom atoms[3];
990
991 if (window->flags & SDL_WINDOW_FULLSCREEN) {
992 atoms[count++] = _NET_WM_STATE_FULLSCREEN;
993 }
994 if (maximized) {
995 atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT;
996 atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
997 }
998 if (count > 0) {
999 XChangeProperty(display, data->xwindow, _NET_WM_STATE, XA_ATOM, 32,
1000 PropModeReplace, (unsigned char *)atoms, count);
1001 } else {
1002 XDeleteProperty(display, data->xwindow, _NET_WM_STATE);
1003 }
1004 }
962 } 1005 }
963 1006
964 void 1007 void
965 X11_MaximizeWindow(_THIS, SDL_Window * window) 1008 X11_MaximizeWindow(_THIS, SDL_Window * window)
966 { 1009 {
991 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 1034 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
992 Display *display = data->videodata->display; 1035 Display *display = data->videodata->display;
993 SDL_bool oldstyle_fullscreen; 1036 SDL_bool oldstyle_fullscreen;
994 1037
995 /* ICCCM2.0-compliant window managers can handle fullscreen windows */ 1038 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
996 oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window); 1039 oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window);
997 1040
998 if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen) 1041 if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen)
999 && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { 1042 && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
1000 /* Try to grab the mouse */ 1043 /* Try to grab the mouse */
1001 for (;;) { 1044 for (;;) {