comparison src/video/x11/SDL_x11window.c @ 4518:a956a315fe67

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.... ???
author Sam Lantinga <slouken@libsdl.org>
date Tue, 13 Jul 2010 23:11:10 -0700
parents 6f8175ad0335
children 0c67c4328678
comparison
equal deleted inserted replaced
4517:7b5e4396bcaa 4518:a956a315fe67
39 #include "SDL_syswm.h" 39 #include "SDL_syswm.h"
40 40
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
45 static SDL_bool
46 X11_WindowIsOldstyleFullscreen(SDL_Window * window)
47 {
48 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
49 SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
50
51 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
52 if ((window->flags & SDL_WINDOW_FULLSCREEN) && !videodata->net_wm) {
53 return SDL_TRUE;
54 } else {
55 return SDL_FALSE;
56 }
57 }
44 58
45 static void 59 static void
46 X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h) 60 X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
47 { 61 {
48 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 62 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
126 window->flags &= ~SDL_WINDOW_SHOWN; 140 window->flags &= ~SDL_WINDOW_SHOWN;
127 } 141 }
128 } 142 }
129 143
130 { 144 {
131 Atom _NET_WM_STATE = 145 Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
132 XInternAtom(data->videodata->display, "_NET_WM_STATE", False); 146 Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
133 Atom _NET_WM_STATE_MAXIMIZED_VERT = 147 Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
134 XInternAtom(data->videodata->display, 148 Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
135 "_NET_WM_STATE_MAXIMIZED_VERT", False);
136 Atom _NET_WM_STATE_MAXIMIZED_HORZ =
137 XInternAtom(data->videodata->display,
138 "_NET_WM_STATE_MAXIMIZED_HORZ", False);
139 Atom actualType; 149 Atom actualType;
140 int actualFormat; 150 int actualFormat;
141 unsigned long i, numItems, bytesAfter; 151 unsigned long i, numItems, bytesAfter;
142 unsigned char *propertyValue = NULL; 152 unsigned char *propertyValue = NULL;
143 long maxLength = 1024; 153 long maxLength = 1024;
146 0l, maxLength, False, XA_ATOM, &actualType, 156 0l, maxLength, False, XA_ATOM, &actualType,
147 &actualFormat, &numItems, &bytesAfter, 157 &actualFormat, &numItems, &bytesAfter,
148 &propertyValue) == Success) { 158 &propertyValue) == Success) {
149 Atom *atoms = (Atom *) propertyValue; 159 Atom *atoms = (Atom *) propertyValue;
150 int maximized = 0; 160 int maximized = 0;
161 int fullscreen = 0;
151 162
152 for (i = 0; i < numItems; ++i) { 163 for (i = 0; i < numItems; ++i) {
153 if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) { 164 if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
154 maximized |= 1; 165 maximized |= 1;
155 } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) { 166 } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
156 maximized |= 2; 167 maximized |= 2;
168 } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) {
169 fullscreen = 1;
157 } 170 }
158 /* Might also want to check the following properties:
159 _NET_WM_STATE_ABOVE, _NET_WM_STATE_FULLSCREEN
160 */
161 } 171 }
162 if (maximized == 3) { 172 if (maximized == 3) {
163 window->flags |= SDL_WINDOW_MAXIMIZED; 173 window->flags |= SDL_WINDOW_MAXIMIZED;
174 } else if (fullscreen == 1) {
175 window->flags |= SDL_WINDOW_FULLSCREEN;
164 } 176 }
165 XFree(propertyValue); 177 XFree(propertyValue);
166 } 178 }
167 } 179 }
168 180
178 if (style & WS_THICKFRAME) { 190 if (style & WS_THICKFRAME) {
179 window->flags |= SDL_WINDOW_RESIZABLE; 191 window->flags |= SDL_WINDOW_RESIZABLE;
180 } else { 192 } else {
181 window->flags &= ~SDL_WINDOW_RESIZABLE; 193 window->flags &= ~SDL_WINDOW_RESIZABLE;
182 } 194 }
183 if (style & WS_MAXIMIZE) {
184 window->flags |= SDL_WINDOW_MAXIMIZED;
185 } else {
186 window->flags &= ~SDL_WINDOW_MAXIMIZED;
187 }
188 if (style & WS_MINIMIZE) { 195 if (style & WS_MINIMIZE) {
189 window->flags |= SDL_WINDOW_MINIMIZED; 196 window->flags |= SDL_WINDOW_MINIMIZED;
190 } else { 197 } else {
191 window->flags &= ~SDL_WINDOW_MINIMIZED; 198 window->flags &= ~SDL_WINDOW_MINIMIZED;
192 } 199 }
223 int x, y; 230 int x, y;
224 Window w; 231 Window w;
225 XSizeHints *sizehints; 232 XSizeHints *sizehints;
226 XWMHints *wmhints; 233 XWMHints *wmhints;
227 XClassHint *classhints; 234 XClassHint *classhints;
235 SDL_bool oldstyle_fullscreen;
236
237 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
238 if ((window->flags & SDL_WINDOW_FULLSCREEN) && !data->net_wm) {
239 oldstyle_fullscreen = SDL_TRUE;
240 } else {
241 oldstyle_fullscreen = SDL_FALSE;
242 }
228 243
229 #if SDL_VIDEO_DRIVER_X11_XINERAMA 244 #if SDL_VIDEO_DRIVER_X11_XINERAMA
230 /* FIXME 245 /* FIXME
231 if ( use_xinerama ) { 246 if ( use_xinerama ) {
232 x = xinerama_info.x_org; 247 x = xinerama_info.x_org;
263 { 278 {
264 visual = displaydata->visual; 279 visual = displaydata->visual;
265 depth = displaydata->depth; 280 depth = displaydata->depth;
266 } 281 }
267 282
268 if (window->flags & SDL_WINDOW_FULLSCREEN) { 283 if (oldstyle_fullscreen) {
269 xattr.override_redirect = True; 284 xattr.override_redirect = True;
270 } else { 285 } else {
271 xattr.override_redirect = False; 286 xattr.override_redirect = False;
272 } 287 }
273 xattr.background_pixel = 0; 288 xattr.background_pixel = 0;
415 ("Couldn't create window: Could not create writable colormap"); 430 ("Couldn't create window: Could not create writable colormap");
416 return -1; 431 return -1;
417 } 432 }
418 433
419 /* OK, we got a colormap, now fill it in as best as we can */ 434 /* OK, we got a colormap, now fill it in as best as we can */
420
421 colorcells = SDL_malloc(visual->map_entries * sizeof(XColor)); 435 colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
422 if (NULL == colorcells) { 436 if (NULL == colorcells) {
423 SDL_SetError("out of memory in X11_CreateWindow"); 437 SDL_SetError("out of memory in X11_CreateWindow");
424 return -1; 438 return -1;
425 } 439 }
492 XCreateColormap(data->display, 506 XCreateColormap(data->display,
493 RootWindow(data->display, displaydata->screen), 507 RootWindow(data->display, displaydata->screen),
494 visual, AllocNone); 508 visual, AllocNone);
495 } 509 }
496 510
497 if ((window->flags & SDL_WINDOW_FULLSCREEN) 511 if (oldstyle_fullscreen
498 || window->x == SDL_WINDOWPOS_CENTERED) { 512 || window->x == SDL_WINDOWPOS_CENTERED) {
499 X11_GetDisplaySize(_this, window, &x, NULL); 513 X11_GetDisplaySize(_this, window, &x, NULL);
500 x = (x - window->w) / 2; 514 x = (x - window->w) / 2;
501 } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { 515 } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
502 x = 0; 516 x = 0;
503 } else { 517 } else {
504 x = window->x; 518 x = window->x;
505 } 519 }
506 if ((window->flags & SDL_WINDOW_FULLSCREEN) 520 if (oldstyle_fullscreen
507 || window->y == SDL_WINDOWPOS_CENTERED) { 521 || window->y == SDL_WINDOWPOS_CENTERED) {
508 X11_GetDisplaySize(_this, window, NULL, &y); 522 X11_GetDisplaySize(_this, window, NULL, &y);
509 y = (y - window->h) / 2; 523 y = (y - window->h) / 2;
510 } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { 524 } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
511 y = 0; 525 y = 0;
537 #endif 551 #endif
538 552
539 sizehints = XAllocSizeHints(); 553 sizehints = XAllocSizeHints();
540 if (sizehints) { 554 if (sizehints) {
541 if (!(window->flags & SDL_WINDOW_RESIZABLE) 555 if (!(window->flags & SDL_WINDOW_RESIZABLE)
542 || (window->flags & SDL_WINDOW_FULLSCREEN)) { 556 || oldstyle_fullscreen) {
543 sizehints->min_width = sizehints->max_width = window->w; 557 sizehints->min_width = sizehints->max_width = window->w;
544 sizehints->min_height = sizehints->max_height = window->h; 558 sizehints->min_height = sizehints->max_height = window->h;
545 sizehints->flags = PMaxSize | PMinSize; 559 sizehints->flags = PMaxSize | PMinSize;
546 } 560 }
547 if (!(window->flags & SDL_WINDOW_FULLSCREEN) 561 if (!oldstyle_fullscreen
548 && window->x != SDL_WINDOWPOS_UNDEFINED 562 && window->x != SDL_WINDOWPOS_UNDEFINED
549 && window->y != SDL_WINDOWPOS_UNDEFINED) { 563 && window->y != SDL_WINDOWPOS_UNDEFINED) {
550 sizehints->x = x; 564 sizehints->x = x;
551 sizehints->y = y; 565 sizehints->y = y;
552 sizehints->flags |= USPosition; 566 sizehints->flags |= USPosition;
553 } 567 }
554 XSetWMNormalHints(data->display, w, sizehints); 568 XSetWMNormalHints(data->display, w, sizehints);
555 XFree(sizehints); 569 XFree(sizehints);
556 } 570 }
557 571
558 if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) { 572 if ((window->flags & SDL_WINDOW_BORDERLESS) || oldstyle_fullscreen) {
559 SDL_bool set; 573 SDL_bool set;
560 Atom WM_HINTS; 574 Atom WM_HINTS;
561 575
562 /* We haven't modified the window manager hints yet */ 576 /* We haven't modified the window manager hints yet */
563 set = SDL_FALSE; 577 set = SDL_FALSE;
641 /* NOTE: Does this work? */ 655 /* NOTE: Does this work? */
642 XSetTransientForHint(data->display, w, None); 656 XSetTransientForHint(data->display, w, None);
643 } 657 }
644 } 658 }
645 659
646 /* Tell KDE to keep fullscreen windows on top */
647 if (window->flags & SDL_WINDOW_FULLSCREEN) {
648 XEvent ev;
649
650 SDL_zero(ev);
651 ev.xclient.type = ClientMessage;
652 ev.xclient.window = RootWindow(data->display, displaydata->screen);
653 ev.xclient.message_type =
654 XInternAtom(data->display, "KWM_KEEP_ON_TOP", False);
655 ev.xclient.format = 32;
656 ev.xclient.data.l[0] = w;
657 ev.xclient.data.l[1] = CurrentTime;
658 XSendEvent(data->display,
659 RootWindow(data->display, displaydata->screen), False,
660 SubstructureRedirectMask, &ev);
661 }
662
663 /* Set the input hints so we get keyboard input */ 660 /* Set the input hints so we get keyboard input */
664 wmhints = XAllocWMHints(); 661 wmhints = XAllocWMHints();
665 if (wmhints) { 662 if (wmhints) {
666 wmhints->input = True; 663 wmhints->input = True;
667 wmhints->flags = InputHint; 664 wmhints->flags = InputHint;
674 if (classhints != NULL) { 671 if (classhints != NULL) {
675 classhints->res_name = data->classname; 672 classhints->res_name = data->classname;
676 classhints->res_class = data->classname; 673 classhints->res_class = data->classname;
677 XSetClassHint(data->display, w, classhints); 674 XSetClassHint(data->display, w, classhints);
678 XFree(classhints); 675 XFree(classhints);
676 }
677
678 /* FIXME: Why doesn't this work? */
679 if (window->flags & SDL_WINDOW_FULLSCREEN) {
680 Atom _NET_WM_STATE = data->_NET_WM_STATE;
681 Atom _NET_WM_STATE_FULLSCREEN = data->_NET_WM_STATE_FULLSCREEN;
682 XEvent e;
683
684 e.xany.type = ClientMessage;
685 e.xclient.display = data->display;
686 e.xclient.window = w;
687 e.xclient.message_type = _NET_WM_STATE;
688 e.xclient.format = 32;
689 e.xclient.data.l[0] = _NET_WM_STATE_ADD;
690 e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
691 e.xclient.data.l[2] = 0l;
692
693 XSendEvent(data->display,
694 RootWindow(data->display, displaydata->screen), 0,
695 SubstructureNotifyMask | SubstructureRedirectMask, &e);
679 } 696 }
680 697
681 /* Allow the window to be deleted by the window manager */ 698 /* Allow the window to be deleted by the window manager */
682 XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1); 699 XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
683 700
714 int 731 int
715 X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) 732 X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
716 { 733 {
717 Window w = (Window) data; 734 Window w = (Window) data;
718 735
719 /* FIXME: Query the title from the existing window */ 736 window->title = X11_GetWindowTitle(_this, w);
720 737
721 if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) { 738 if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
722 return -1; 739 return -1;
723 } 740 }
724 return 0; 741 return 0;
742 }
743
744 char *
745 X11_GetWindowTitle(_THIS, Window xwindow)
746 {
747 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
748 Display *display = data->display;
749 int status, real_format;
750 Atom real_type;
751 unsigned long items_read, items_left;
752 unsigned char *propdata;
753 char *title = NULL;
754
755 status = XGetWindowProperty(display, xwindow, data->_NET_WM_NAME,
756 0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format,
757 &items_read, &items_left, &propdata);
758 if (status == Success) {
759 title = SDL_strdup(SDL_static_cast(char*, propdata));
760 XFree(propdata);
761 } else {
762 status = XGetWindowProperty(display, xwindow, XA_WM_NAME,
763 0L, 8192L, False, XA_STRING, &real_type, &real_format,
764 &items_read, &items_left, &propdata);
765 if (status == Success) {
766 title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
767 } else {
768 title = SDL_strdup("");
769 }
770 }
771 return title;
725 } 772 }
726 773
727 void 774 void
728 X11_SetWindowTitle(_THIS, SDL_Window * window) 775 X11_SetWindowTitle(_THIS, SDL_Window * window)
729 { 776 {
733 Status status; 780 Status status;
734 const char *title = window->title; 781 const char *title = window->title;
735 const char *icon = NULL; 782 const char *icon = NULL;
736 783
737 #ifdef X_HAVE_UTF8_STRING 784 #ifdef X_HAVE_UTF8_STRING
738 Atom _NET_WM_NAME = 0; 785 Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
739 Atom _NET_WM_ICON_NAME = 0; 786 Atom _NET_WM_ICON_NAME = data->videodata->_NET_WM_ICON_NAME;
740
741 /* Look up some useful Atoms */
742 if (SDL_X11_HAVE_UTF8) {
743 _NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", False);
744 _NET_WM_ICON_NAME = XInternAtom(display, "_NET_WM_ICON_NAME", False);
745 }
746 #endif 787 #endif
747 788
748 if (title != NULL) { 789 if (title != NULL) {
749 char *title_locale = SDL_iconv_utf8_locale(title); 790 char *title_locale = SDL_iconv_utf8_locale(title);
750 if (!title_locale) { 791 if (!title_locale) {
801 void 842 void
802 X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) 843 X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
803 { 844 {
804 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 845 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
805 Display *display = data->videodata->display; 846 Display *display = data->videodata->display;
806 Atom _NET_WM_ICON = XInternAtom(display, "_NET_WM_ICON", False); 847 Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON;
807 848
808 if (icon) { 849 if (icon) {
809 SDL_PixelFormat format; 850 SDL_PixelFormat format;
810 SDL_Surface *surface; 851 SDL_Surface *surface;
811 int propsize; 852 int propsize;
840 void 881 void
841 X11_SetWindowPosition(_THIS, SDL_Window * window) 882 X11_SetWindowPosition(_THIS, SDL_Window * window)
842 { 883 {
843 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 884 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
844 Display *display = data->videodata->display; 885 Display *display = data->videodata->display;
886 SDL_bool oldstyle_fullscreen;
845 int x, y; 887 int x, y;
846 888
847 if ((window->flags & SDL_WINDOW_FULLSCREEN) 889 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
890 oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
891
892 if (oldstyle_fullscreen
848 || window->x == SDL_WINDOWPOS_CENTERED) { 893 || window->x == SDL_WINDOWPOS_CENTERED) {
849 X11_GetDisplaySize(_this, window, &x, NULL); 894 X11_GetDisplaySize(_this, window, &x, NULL);
850 x = (x - window->w) / 2; 895 x = (x - window->w) / 2;
851 } else { 896 } else {
852 x = window->x; 897 x = window->x;
853 } 898 }
854 if ((window->flags & SDL_WINDOW_FULLSCREEN) 899 if (oldstyle_fullscreen
855 || window->y == SDL_WINDOWPOS_CENTERED) { 900 || window->y == SDL_WINDOWPOS_CENTERED) {
856 X11_GetDisplaySize(_this, window, NULL, &y); 901 X11_GetDisplaySize(_this, window, NULL, &y);
857 y = (y - window->h) / 2; 902 y = (y - window->h) / 2;
858 } else { 903 } else {
859 y = window->y; 904 y = window->y;
902 { 947 {
903 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 948 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
904 SDL_DisplayData *displaydata = 949 SDL_DisplayData *displaydata =
905 (SDL_DisplayData *) window->display->driverdata; 950 (SDL_DisplayData *) window->display->driverdata;
906 Display *display = data->videodata->display; 951 Display *display = data->videodata->display;
907 Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", False); 952 Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
908 Atom _NET_WM_STATE_MAXIMIZED_VERT = 953 Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
909 XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", False); 954 Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
910 Atom _NET_WM_STATE_MAXIMIZED_HORZ =
911 XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
912 XEvent e; 955 XEvent e;
913 956
914 e.xany.type = ClientMessage; 957 e.xany.type = ClientMessage;
915 e.xany.window = data->xwindow; 958 e.xclient.display = display;
959 e.xclient.window = data->xwindow;
916 e.xclient.message_type = _NET_WM_STATE; 960 e.xclient.message_type = _NET_WM_STATE;
917 e.xclient.format = 32; 961 e.xclient.format = 32;
918 e.xclient.data.l[0] = 962 e.xclient.data.l[0] =
919 maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; 963 maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
920 e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT; 964 e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
921 e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ; 965 e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
922 e.xclient.data.l[3] = 0l; 966 e.xclient.data.l[3] = 0l;
923 e.xclient.data.l[4] = 0l;
924 967
925 XSendEvent(display, RootWindow(display, displaydata->screen), 0, 968 XSendEvent(display, RootWindow(display, displaydata->screen), 0,
926 SubstructureNotifyMask | SubstructureRedirectMask, &e); 969 SubstructureNotifyMask | SubstructureRedirectMask, &e);
927 } 970 }
928 971
933 } 976 }
934 977
935 void 978 void
936 X11_MinimizeWindow(_THIS, SDL_Window * window) 979 X11_MinimizeWindow(_THIS, SDL_Window * window)
937 { 980 {
938 X11_HideWindow(_this, window); 981 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
982 SDL_DisplayData *displaydata =
983 (SDL_DisplayData *) window->display->driverdata;
984 Display *display = data->videodata->display;
985
986 XIconifyWindow(display, data->xwindow, displaydata->screen);
939 } 987 }
940 988
941 void 989 void
942 X11_RestoreWindow(_THIS, SDL_Window * window) 990 X11_RestoreWindow(_THIS, SDL_Window * window)
943 { 991 {
948 void 996 void
949 X11_SetWindowGrab(_THIS, SDL_Window * window) 997 X11_SetWindowGrab(_THIS, SDL_Window * window)
950 { 998 {
951 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 999 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
952 Display *display = data->videodata->display; 1000 Display *display = data->videodata->display;
953 1001 SDL_bool oldstyle_fullscreen;
954 if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) 1002
1003 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
1004 oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
1005
1006 if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen)
955 && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { 1007 && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
956 /* Try to grab the mouse */ 1008 /* Try to grab the mouse */
957 for (;;) { 1009 for (;;) {
958 int result = 1010 int result =
959 XGrabPointer(display, data->xwindow, True, 0, GrabModeAsync, 1011 XGrabPointer(display, data->xwindow, True, 0, GrabModeAsync,