Undecorated window support on win/mac/linux.

This commit is contained in:
NathanSweet 2013-04-08 03:07:52 +02:00 committed by Camilla Berglund
parent 2f7cad5765
commit 8e2e7b37a1
6 changed files with 55 additions and 9 deletions

View File

@ -482,6 +482,7 @@ extern "C" {
#define GLFW_ICONIFIED 0x00020002 #define GLFW_ICONIFIED 0x00020002
#define GLFW_RESIZABLE 0x00022007 #define GLFW_RESIZABLE 0x00022007
#define GLFW_VISIBLE 0x00022008 #define GLFW_VISIBLE 0x00022008
#define GLFW_UNDECORATED 0x00022009
#define GLFW_CONTEXT_REVISION 0x00020004 #define GLFW_CONTEXT_REVISION 0x00020004
#define GLFW_RED_BITS 0x00021000 #define GLFW_RED_BITS 0x00021000

View File

@ -636,6 +636,14 @@ static GLboolean initializeAppKit(void)
return GL_TRUE; return GL_TRUE;
} }
@interface GLFWWindow : NSWindow {}
@end
@implementation GLFWWindow
- (BOOL)canBecomeKeyWindow {
return YES; // Required for NSBorderlessWindowMask windows.
}
@end
// Create the Cocoa window // Create the Cocoa window
// //
static GLboolean createWindow(_GLFWwindow* window, static GLboolean createWindow(_GLFWwindow* window,
@ -643,7 +651,7 @@ static GLboolean createWindow(_GLFWwindow* window,
{ {
unsigned int styleMask = 0; unsigned int styleMask = 0;
if (wndconfig->monitor) if (wndconfig->monitor || wndconfig->undecorated)
styleMask = NSBorderlessWindowMask; styleMask = NSBorderlessWindowMask;
else else
{ {
@ -654,7 +662,7 @@ static GLboolean createWindow(_GLFWwindow* window,
styleMask |= NSResizableWindowMask; styleMask |= NSResizableWindowMask;
} }
window->ns.object = [[NSWindow alloc] window->ns.object = [[GLFWWindow alloc]
initWithContentRect:NSMakeRect(0, 0, wndconfig->width, wndconfig->height) initWithContentRect:NSMakeRect(0, 0, wndconfig->width, wndconfig->height)
styleMask:styleMask styleMask:styleMask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered

View File

@ -145,6 +145,7 @@ struct _GLFWhints
int auxBuffers; int auxBuffers;
GLboolean stereo; GLboolean stereo;
GLboolean resizable; GLboolean resizable;
GLboolean undecorated;
GLboolean visible; GLboolean visible;
int samples; int samples;
GLboolean sRGB; GLboolean sRGB;
@ -170,6 +171,7 @@ struct _GLFWwndconfig
int height; int height;
const char* title; const char* title;
GLboolean resizable; GLboolean resizable;
GLboolean undecorated;
GLboolean visible; GLboolean visible;
int clientAPI; int clientAPI;
int glMajor; int glMajor;
@ -216,6 +218,7 @@ struct _GLFWwindow
// Window settings and state // Window settings and state
GLboolean iconified; GLboolean iconified;
GLboolean resizable; GLboolean resizable;
GLboolean undecorated;
GLboolean visible; GLboolean visible;
GLboolean closed; GLboolean closed;
void* userPointer; void* userPointer;

View File

@ -60,7 +60,7 @@ static void hideCursor(_GLFWwindow* window)
{ {
if (WindowFromPoint(pos) == window->win32.handle) if (WindowFromPoint(pos) == window->win32.handle)
SetCursor(NULL); SetCursor(NULL);
} }
} }
// Capture mouse cursor // Capture mouse cursor
@ -739,6 +739,11 @@ static int createWindow(_GLFWwindow* window,
window->win32.dwExStyle |= WS_EX_WINDOWEDGE; window->win32.dwExStyle |= WS_EX_WINDOWEDGE;
} }
if (wndconfig->undecorated) {
window->win32.dwStyle = WS_POPUP;
window->win32.dwExStyle = 0;
}
xpos = CW_USEDEFAULT; xpos = CW_USEDEFAULT;
ypos = CW_USEDEFAULT; ypos = CW_USEDEFAULT;
@ -938,7 +943,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
SetWindowPos(window->win32.handle, HWND_TOP, SetWindowPos(window->win32.handle, HWND_TOP,
0, 0, mode.width, mode.height, 0, 0, mode.width, mode.height,
SWP_NOMOVE); SWP_NOMOVE);
} }
else else
{ {
int fullWidth, fullHeight; int fullWidth, fullHeight;

View File

@ -126,7 +126,7 @@ void _glfwInputWindowDamage(_GLFWwindow* window)
void _glfwInputWindowCloseRequest(_GLFWwindow* window) void _glfwInputWindowCloseRequest(_GLFWwindow* window)
{ {
window->closed = GL_TRUE; window->closed = GL_TRUE;
if (window->callbacks.close) if (window->callbacks.close)
window->callbacks.close((GLFWwindow*) window); window->callbacks.close((GLFWwindow*) window);
@ -176,6 +176,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
wndconfig.height = height; wndconfig.height = height;
wndconfig.title = title; wndconfig.title = title;
wndconfig.resizable = _glfw.hints.resizable ? GL_TRUE : GL_FALSE; 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.visible = _glfw.hints.visible ? GL_TRUE : GL_FALSE;
wndconfig.clientAPI = _glfw.hints.clientAPI; wndconfig.clientAPI = _glfw.hints.clientAPI;
wndconfig.glMajor = _glfw.hints.glMajor; wndconfig.glMajor = _glfw.hints.glMajor;
@ -213,9 +214,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->videoMode.blueBits = fbconfig.blueBits; window->videoMode.blueBits = fbconfig.blueBits;
} }
window->monitor = wndconfig.monitor; window->monitor = wndconfig.monitor;
window->resizable = wndconfig.resizable; window->resizable = wndconfig.resizable;
window->cursorMode = GLFW_CURSOR_NORMAL; window->undecorated = wndconfig.undecorated;
window->cursorMode = GLFW_CURSOR_NORMAL;
// Save the currently current context so it can be restored later // Save the currently current context so it can be restored later
previous = (_GLFWwindow*) glfwGetCurrentContext(); previous = (_GLFWwindow*) glfwGetCurrentContext();
@ -278,6 +280,7 @@ void glfwDefaultWindowHints(void)
// The default is to show the window and allow window resizing // The default is to show the window and allow window resizing
_glfw.hints.resizable = GL_TRUE; _glfw.hints.resizable = GL_TRUE;
_glfw.hints.undecorated = GL_FALSE;
_glfw.hints.visible = GL_TRUE; _glfw.hints.visible = GL_TRUE;
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil // 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: case GLFW_RESIZABLE:
_glfw.hints.resizable = hint; _glfw.hints.resizable = hint;
break; break;
case GLFW_UNDECORATED:
_glfw.hints.undecorated = hint;
break;
case GLFW_VISIBLE: case GLFW_VISIBLE:
_glfw.hints.visible = hint; _glfw.hints.visible = hint;
break; break;
@ -540,6 +546,8 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow* handle, int param)
return window->iconified; return window->iconified;
case GLFW_RESIZABLE: case GLFW_RESIZABLE:
return window->resizable; return window->resizable;
case GLFW_UNDECORATED:
return window->undecorated;
case GLFW_VISIBLE: case GLFW_VISIBLE:
return window->visible; return window->visible;
case GLFW_CLIENT_API: case GLFW_CLIENT_API:

View File

@ -46,6 +46,16 @@
#define Button6 6 #define Button6 6
#define Button7 7 #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 // 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"); _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to create window");
return GL_FALSE; 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) if (window->monitor && !_glfw.x11.hasEWMH)
@ -471,7 +492,7 @@ static void processEvent(XEvent *event)
if (!(event->xkey.state & ControlMask) && if (!(event->xkey.state & ControlMask) &&
!(event->xkey.state & Mod1Mask /*Alt*/)) !(event->xkey.state & Mod1Mask /*Alt*/))
{ {
_glfwInputChar(window, translateChar(&event->xkey)); _glfwInputChar(window, translateChar(&event->xkey));
} }
break; break;