Mercurial > sdl-ios-xcode
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, |