mirror of
https://github.com/glfw/glfw.git
synced 2026-09-19 07:05:49 +00:00
@@ -972,6 +972,9 @@ static GLboolean createWindow(_GLFWwindow* window,
|
||||
}
|
||||
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
||||
|
||||
if (wndconfig->floating)
|
||||
[window->ns.object setLevel:NSFloatingWindowLevel];
|
||||
|
||||
[window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];
|
||||
[window->ns.object setContentView:window->ns.view];
|
||||
[window->ns.object setDelegate:window->ns.delegate];
|
||||
|
||||
@@ -153,6 +153,7 @@ struct _GLFWwndconfig
|
||||
GLboolean visible;
|
||||
GLboolean decorated;
|
||||
GLboolean autoIconify;
|
||||
GLboolean floating;
|
||||
_GLFWmonitor* monitor;
|
||||
};
|
||||
|
||||
@@ -218,6 +219,7 @@ struct _GLFWwindow
|
||||
GLboolean resizable;
|
||||
GLboolean decorated;
|
||||
GLboolean autoIconify;
|
||||
GLboolean floating;
|
||||
GLboolean visible;
|
||||
GLboolean closed;
|
||||
void* userPointer;
|
||||
@@ -323,6 +325,7 @@ struct _GLFWlibrary
|
||||
int visible;
|
||||
int decorated;
|
||||
int autoIconify;
|
||||
int floating;
|
||||
int samples;
|
||||
int sRGB;
|
||||
int refreshRate;
|
||||
|
||||
@@ -951,6 +951,14 @@ static int createWindow(_GLFWwindow* window,
|
||||
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||
}
|
||||
|
||||
if (wndconfig->floating && !wndconfig->monitor)
|
||||
{
|
||||
SetWindowPos(window->win32.handle,
|
||||
HWND_TOPMOST,
|
||||
0, 0, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
|
||||
DragAcceptFiles(window->win32.handle, TRUE);
|
||||
|
||||
if (!_glfwCreateContext(window, ctxconfig, fbconfig))
|
||||
|
||||
@@ -167,6 +167,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
wndconfig.visible = _glfw.hints.visible ? GL_TRUE : GL_FALSE;
|
||||
wndconfig.decorated = _glfw.hints.decorated ? GL_TRUE : GL_FALSE;
|
||||
wndconfig.autoIconify = _glfw.hints.autoIconify ? GL_TRUE : GL_FALSE;
|
||||
wndconfig.floating = _glfw.hints.floating ? GL_TRUE : GL_FALSE;
|
||||
wndconfig.monitor = (_GLFWmonitor*) monitor;
|
||||
|
||||
// Set up desired context config
|
||||
@@ -205,6 +206,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
window->resizable = wndconfig.resizable;
|
||||
window->decorated = wndconfig.decorated;
|
||||
window->autoIconify = wndconfig.autoIconify;
|
||||
window->floating = wndconfig.floating;
|
||||
window->cursorMode = GLFW_CURSOR_NORMAL;
|
||||
|
||||
// Save the currently current context so it can be restored later
|
||||
@@ -335,6 +337,9 @@ GLFWAPI void glfwWindowHint(int target, int hint)
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
_glfw.hints.autoIconify = hint;
|
||||
break;
|
||||
case GLFW_FLOATING:
|
||||
_glfw.hints.floating = hint;
|
||||
break;
|
||||
case GLFW_VISIBLE:
|
||||
_glfw.hints.visible = hint;
|
||||
break;
|
||||
@@ -585,6 +590,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
return window->resizable;
|
||||
case GLFW_DECORATED:
|
||||
return window->decorated;
|
||||
case GLFW_FLOATING:
|
||||
return window->floating;
|
||||
case GLFW_VISIBLE:
|
||||
return window->visible;
|
||||
case GLFW_CLIENT_API:
|
||||
|
||||
@@ -419,6 +419,8 @@ static void detectEWMH(void)
|
||||
// See which of the atoms we support that are supported by the WM
|
||||
_glfw.x11.NET_WM_STATE =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||
_glfw.x11.NET_WM_STATE_ABOVE =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
|
||||
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
|
||||
_glfw.x11.NET_WM_NAME =
|
||||
|
||||
@@ -122,6 +122,7 @@ typedef struct _GLFWlibraryX11
|
||||
Atom NET_WM_PID;
|
||||
Atom NET_WM_PING;
|
||||
Atom NET_WM_STATE;
|
||||
Atom NET_WM_STATE_ABOVE;
|
||||
Atom NET_WM_STATE_FULLSCREEN;
|
||||
Atom NET_WM_BYPASS_COMPOSITOR;
|
||||
Atom NET_ACTIVE_WINDOW;
|
||||
|
||||
+39
-34
@@ -108,6 +108,29 @@ static int translateChar(XKeyEvent* event)
|
||||
return (int) _glfwKeySym2Unicode(keysym);
|
||||
}
|
||||
|
||||
// Adds or removes an EWMH state to a window
|
||||
//
|
||||
static void changeWindowState(_GLFWwindow* window, Atom state, int action)
|
||||
{
|
||||
XEvent event;
|
||||
memset(&event, 0, sizeof(event));
|
||||
|
||||
event.type = ClientMessage;
|
||||
event.xclient.window = window->x11.handle;
|
||||
event.xclient.format = 32; // Data is 32-bit longs
|
||||
event.xclient.message_type = _glfw.x11.NET_WM_STATE;
|
||||
event.xclient.data.l[0] = action;
|
||||
event.xclient.data.l[1] = state;
|
||||
event.xclient.data.l[2] = 0; // No secondary property
|
||||
event.xclient.data.l[3] = 1; // Sender is a normal application
|
||||
|
||||
XSendEvent(_glfw.x11.display,
|
||||
_glfw.x11.root,
|
||||
False,
|
||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
&event);
|
||||
}
|
||||
|
||||
// Splits and translates a text/uri-list into separate file paths
|
||||
//
|
||||
static char** parseUriList(char* text, int* count)
|
||||
@@ -382,6 +405,16 @@ static GLboolean createWindow(_GLFWwindow* window,
|
||||
XIfEvent(_glfw.x11.display, &event, isFrameExtentsEvent, (XPointer) window);
|
||||
}
|
||||
|
||||
if (wndconfig->floating && !wndconfig->monitor)
|
||||
{
|
||||
if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE)
|
||||
{
|
||||
changeWindowState(window,
|
||||
_glfw.x11.NET_WM_STATE_ABOVE,
|
||||
_NET_WM_STATE_ADD);
|
||||
}
|
||||
}
|
||||
|
||||
_glfwPlatformSetWindowTitle(window, wndconfig->title);
|
||||
|
||||
XRRSelectInput(_glfw.x11.display, window->x11.handle,
|
||||
@@ -490,23 +523,9 @@ static void enterFullscreenMode(_GLFWwindow* window)
|
||||
// Fullscreen windows are undecorated and, when focused, are kept
|
||||
// on top of all other windows
|
||||
|
||||
XEvent event;
|
||||
memset(&event, 0, sizeof(event));
|
||||
|
||||
event.type = ClientMessage;
|
||||
event.xclient.window = window->x11.handle;
|
||||
event.xclient.format = 32; // Data is 32-bit longs
|
||||
event.xclient.message_type = _glfw.x11.NET_WM_STATE;
|
||||
event.xclient.data.l[0] = _NET_WM_STATE_ADD;
|
||||
event.xclient.data.l[1] = _glfw.x11.NET_WM_STATE_FULLSCREEN;
|
||||
event.xclient.data.l[2] = 0; // No secondary property
|
||||
event.xclient.data.l[3] = 1; // Sender is a normal application
|
||||
|
||||
XSendEvent(_glfw.x11.display,
|
||||
_glfw.x11.root,
|
||||
False,
|
||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
&event);
|
||||
changeWindowState(window,
|
||||
_glfw.x11.NET_WM_STATE_FULLSCREEN,
|
||||
_NET_WM_STATE_ADD);
|
||||
}
|
||||
else if (window->x11.overrideRedirect)
|
||||
{
|
||||
@@ -557,23 +576,9 @@ static void leaveFullscreenMode(_GLFWwindow* window)
|
||||
// Ask the window manager to make the GLFW window a normal window
|
||||
// Normal windows usually have frames and other decorations
|
||||
|
||||
XEvent event;
|
||||
memset(&event, 0, sizeof(event));
|
||||
|
||||
event.type = ClientMessage;
|
||||
event.xclient.window = window->x11.handle;
|
||||
event.xclient.format = 32; // Data is 32-bit longs
|
||||
event.xclient.message_type = _glfw.x11.NET_WM_STATE;
|
||||
event.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
|
||||
event.xclient.data.l[1] = _glfw.x11.NET_WM_STATE_FULLSCREEN;
|
||||
event.xclient.data.l[2] = 0; // No secondary property
|
||||
event.xclient.data.l[3] = 1; // Sender is a normal application
|
||||
|
||||
XSendEvent(_glfw.x11.display,
|
||||
_glfw.x11.root,
|
||||
False,
|
||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
&event);
|
||||
changeWindowState(window,
|
||||
_glfw.x11.NET_WM_STATE_FULLSCREEN,
|
||||
_NET_WM_STATE_REMOVE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user