From 87693ef0a84f29fd3ad9050b0d5b7c0ee62df89a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 19 Feb 2009 06:48:25 +0000 Subject: [PATCH] Implemented X11 maximized state control --- src/video/x11/SDL_x11sym.h | 1 + src/video/x11/SDL_x11window.c | 67 ++++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index 68c9fb415..dc1933d39 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -70,6 +70,7 @@ SDL_X11_SYM(int,XGetRGBColormaps,(Display* a,Window b,XStandardColormap **c,int SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return) SDL_X11_SYM(XWMHints*,XGetWMHints,(Display* a,Window b),(a,b),return) SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return) +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) SDL_X11_SYM(int,XGrabKeyboard,(Display* a,Window b,Bool c,int d,int e,Time f),(a,b,c,d,e,f),return) SDL_X11_SYM(int,XGrabPointer,(Display* a,Window b,Bool c,unsigned int d,int e,int f,Window g,Cursor h,Time i),(a,b,c,d,e,f,g,h,i),return) SDL_X11_SYM(int,XGrabServer,(Display* a),(a),return) diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index c59f674cf..dbb85b860 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -31,6 +31,10 @@ #include "SDL_x11gamma.h" #include "../Xext/extensions/StdCmap.h" +#define _NET_WM_STATE_REMOVE 0l +#define _NET_WM_STATE_ADD 1l +#define _NET_WM_STATE_TOGGLE 2l + static void X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h) { @@ -116,6 +120,40 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) window->flags &= ~SDL_WINDOW_SHOWN; } } + + { + Atom _NET_WM_STATE = XInternAtom(data->videodata->display, "_NET_WM_STATE", False); + Atom _NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(data->videodata->display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + Atom _NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(data->videodata->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + Atom actualType; + int actualFormat; + unsigned long i, numItems, bytesAfter; + unsigned char *propertyValue = NULL; + long maxLength = 1024; + + if (XGetWindowProperty(data->videodata->display, w, _NET_WM_STATE, + 0l, maxLength, False, XA_ATOM, &actualType, &actualFormat, + &numItems, &bytesAfter, &propertyValue) == Success) { + Atom *atoms = (Atom *)propertyValue; + int maximized = 0; + + for (i = 0; i < numItems; ++i) { + if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) { + maximized |= 1; + } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) { + maximized |= 2; + } + /* Might also want to check the following properties: + _NET_WM_STATE_ABOVE, _NET_WM_STATE_FULLSCREEN + */ + } + if (maximized == 3) { + window->flags |= SDL_WINDOW_MAXIMIZED; + } + XFree(propertyValue); + } + } + /* FIXME: How can I tell? { DWORD style = GetWindowLong(hwnd, GWL_STYLE); @@ -857,10 +895,36 @@ X11_RaiseWindow(_THIS, SDL_Window * window) XRaiseWindow(display, data->window); } +static void +X11_SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_DisplayData *displaydata = + (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", False); + Atom _NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", False); + Atom _NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + XEvent e; + + e.xany.type = ClientMessage; + e.xany.window = data->window; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.data.l[0] = maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT; + e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ; + e.xclient.data.l[3] = 0l; + e.xclient.data.l[4] = 0l; + + XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask|SubstructureRedirectMask, &e); +} + void X11_MaximizeWindow(_THIS, SDL_Window * window) { - /* FIXME: is this even possible? */ + X11_SetWindowMaximized(_this, window, SDL_TRUE); } void @@ -872,6 +936,7 @@ X11_MinimizeWindow(_THIS, SDL_Window * window) void X11_RestoreWindow(_THIS, SDL_Window * window) { + X11_SetWindowMaximized(_this, window, SDL_FALSE); X11_ShowWindow(_this, window); }