Mercurial > sdl-ios-xcode
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 (;;) { |