From 8e2e7b37a16f3d9b8de730f74864c91b9bc68089 Mon Sep 17 00:00:00 2001 From: NathanSweet Date: Mon, 8 Apr 2013 03:07:52 +0200 Subject: [PATCH] Undecorated window support on win/mac/linux. --- include/GL/glfw3.h | 1 + src/cocoa_window.m | 12 ++++++++++-- src/internal.h | 3 +++ src/win32_window.c | 9 +++++++-- src/window.c | 16 ++++++++++++---- src/x11_window.c | 23 ++++++++++++++++++++++- 6 files changed, 55 insertions(+), 9 deletions(-) diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 28048b2a..fb33ebaf 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -482,6 +482,7 @@ extern "C" { #define GLFW_ICONIFIED 0x00020002 #define GLFW_RESIZABLE 0x00022007 #define GLFW_VISIBLE 0x00022008 +#define GLFW_UNDECORATED 0x00022009 #define GLFW_CONTEXT_REVISION 0x00020004 #define GLFW_RED_BITS 0x00021000 diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 2c2698bc..30edae51 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -636,6 +636,14 @@ static GLboolean initializeAppKit(void) return GL_TRUE; } +@interface GLFWWindow : NSWindow {} +@end +@implementation GLFWWindow +- (BOOL)canBecomeKeyWindow { + return YES; // Required for NSBorderlessWindowMask windows. +} +@end + // Create the Cocoa window // static GLboolean createWindow(_GLFWwindow* window, @@ -643,7 +651,7 @@ static GLboolean createWindow(_GLFWwindow* window, { unsigned int styleMask = 0; - if (wndconfig->monitor) + if (wndconfig->monitor || wndconfig->undecorated) styleMask = NSBorderlessWindowMask; else { @@ -654,7 +662,7 @@ static GLboolean createWindow(_GLFWwindow* window, styleMask |= NSResizableWindowMask; } - window->ns.object = [[NSWindow alloc] + window->ns.object = [[GLFWWindow alloc] initWithContentRect:NSMakeRect(0, 0, wndconfig->width, wndconfig->height) styleMask:styleMask backing:NSBackingStoreBuffered diff --git a/src/internal.h b/src/internal.h index c7b45afb..58f6c234 100644 --- a/src/internal.h +++ b/src/internal.h @@ -145,6 +145,7 @@ struct _GLFWhints int auxBuffers; GLboolean stereo; GLboolean resizable; + GLboolean undecorated; GLboolean visible; int samples; GLboolean sRGB; @@ -170,6 +171,7 @@ struct _GLFWwndconfig int height; const char* title; GLboolean resizable; + GLboolean undecorated; GLboolean visible; int clientAPI; int glMajor; @@ -216,6 +218,7 @@ struct _GLFWwindow // Window settings and state GLboolean iconified; GLboolean resizable; + GLboolean undecorated; GLboolean visible; GLboolean closed; void* userPointer; diff --git a/src/win32_window.c b/src/win32_window.c index fb1b9a2e..8d717ac5 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -60,7 +60,7 @@ static void hideCursor(_GLFWwindow* window) { if (WindowFromPoint(pos) == window->win32.handle) SetCursor(NULL); - } +} } // Capture mouse cursor @@ -739,6 +739,11 @@ static int createWindow(_GLFWwindow* window, window->win32.dwExStyle |= WS_EX_WINDOWEDGE; } + if (wndconfig->undecorated) { + window->win32.dwStyle = WS_POPUP; + window->win32.dwExStyle = 0; + } + xpos = CW_USEDEFAULT; ypos = CW_USEDEFAULT; @@ -938,7 +943,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) SetWindowPos(window->win32.handle, HWND_TOP, 0, 0, mode.width, mode.height, SWP_NOMOVE); - } + } else { int fullWidth, fullHeight; diff --git a/src/window.c b/src/window.c index 57907eaf..781f67e9 100644 --- a/src/window.c +++ b/src/window.c @@ -126,7 +126,7 @@ void _glfwInputWindowDamage(_GLFWwindow* window) void _glfwInputWindowCloseRequest(_GLFWwindow* window) { - window->closed = GL_TRUE; + window->closed = GL_TRUE; if (window->callbacks.close) window->callbacks.close((GLFWwindow*) window); @@ -176,6 +176,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, wndconfig.height = height; wndconfig.title = title; wndconfig.resizable = _glfw.hints.resizable ? GL_TRUE : GL_FALSE; + wndconfig.undecorated = _glfw.hints.undecorated ? GL_TRUE : GL_FALSE; wndconfig.visible = _glfw.hints.visible ? GL_TRUE : GL_FALSE; wndconfig.clientAPI = _glfw.hints.clientAPI; wndconfig.glMajor = _glfw.hints.glMajor; @@ -213,9 +214,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->videoMode.blueBits = fbconfig.blueBits; } - window->monitor = wndconfig.monitor; - window->resizable = wndconfig.resizable; - window->cursorMode = GLFW_CURSOR_NORMAL; + window->monitor = wndconfig.monitor; + window->resizable = wndconfig.resizable; + window->undecorated = wndconfig.undecorated; + window->cursorMode = GLFW_CURSOR_NORMAL; // Save the currently current context so it can be restored later previous = (_GLFWwindow*) glfwGetCurrentContext(); @@ -278,6 +280,7 @@ void glfwDefaultWindowHints(void) // The default is to show the window and allow window resizing _glfw.hints.resizable = GL_TRUE; + _glfw.hints.undecorated = GL_FALSE; _glfw.hints.visible = GL_TRUE; // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil @@ -333,6 +336,9 @@ GLFWAPI void glfwWindowHint(int target, int hint) case GLFW_RESIZABLE: _glfw.hints.resizable = hint; break; + case GLFW_UNDECORATED: + _glfw.hints.undecorated = hint; + break; case GLFW_VISIBLE: _glfw.hints.visible = hint; break; @@ -540,6 +546,8 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow* handle, int param) return window->iconified; case GLFW_RESIZABLE: return window->resizable; + case GLFW_UNDECORATED: + return window->undecorated; case GLFW_VISIBLE: return window->visible; case GLFW_CLIENT_API: diff --git a/src/x11_window.c b/src/x11_window.c index bdebae37..37dcc889 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -46,6 +46,16 @@ #define Button6 6 #define Button7 7 +typedef struct +{ + unsigned long flags; + unsigned long functions; + unsigned long decorations; + long input_mode; + unsigned long status; +} MotifWmHints; + +#define MWM_HINTS_DECORATIONS (1L << 1) // Translates an X Window key to internal coding // @@ -129,6 +139,17 @@ static GLboolean createWindow(_GLFWwindow* window, _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to create window"); return GL_FALSE; } + + if (wndconfig->undecorated) { + Atom motif_hints_atom = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); + MotifWmHints motif_hints; + motif_hints.flags = MWM_HINTS_DECORATIONS; + motif_hints.decorations = 0; + XChangeProperty(_glfw.x11.display, window->x11.handle, + motif_hints_atom, motif_hints_atom, 32, + PropModeReplace, + (unsigned char *)&motif_hints, sizeof(MotifWmHints) / sizeof(long)); + } } if (window->monitor && !_glfw.x11.hasEWMH) @@ -471,7 +492,7 @@ static void processEvent(XEvent *event) if (!(event->xkey.state & ControlMask) && !(event->xkey.state & Mod1Mask /*Alt*/)) { - _glfwInputChar(window, translateChar(&event->xkey)); + _glfwInputChar(window, translateChar(&event->xkey)); } break;