mirror of
https://github.com/glfw/glfw.git
synced 2026-09-19 15:25:50 +00:00
Add glfwSetWindowAttrib
This function allows updating the GLFW_DECORATED, GLFW_RESIZABLE, GLFW_FLOATING and GLFW_AUTO_ICONIFY attributes for existing windows. Fixes #537.
This commit is contained in:
@@ -1385,6 +1385,25 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
return [window->ns.object isZoomed];
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
[window->ns.object setStyleMask:getStyleMask(window)];
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
[window->ns.object setStyleMask:getStyleMask(window)];
|
||||
[window->ns.object makeFirstResponder:window->ns.view];
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
[window->ns.object setLevel:NSFloatingWindowLevel];
|
||||
else
|
||||
[window->ns.object setLevel:NSNormalWindowLevel];
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
for (;;)
|
||||
|
||||
@@ -757,6 +757,21 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
||||
*/
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
||||
|
||||
/*! @brief Sets whether the window is resizable by the user.
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||
|
||||
/*! @brief Sets whether the window is decorated.
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||
|
||||
/*! @brief Sets whether the window is floating.
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||
|
||||
/*! @copydoc glfwPollEvents
|
||||
* @ingroup platform
|
||||
*/
|
||||
|
||||
@@ -595,6 +595,24 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
return mir_surface_get_state(window->mir.surface) == mir_surface_state_maximized;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
EventNode* node = NULL;
|
||||
|
||||
@@ -280,6 +280,26 @@ static void updateClipRect(_GLFWwindow* window)
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
|
||||
// Update native window styles to match attributes
|
||||
//
|
||||
static void updateWindowStyles(const _GLFWwindow* window)
|
||||
{
|
||||
RECT rect;
|
||||
DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
|
||||
style &= ~(WS_OVERLAPPEDWINDOW | WS_POPUP);
|
||||
style |= getWindowStyle(window);
|
||||
|
||||
GetClientRect(window->win32.handle, &rect);
|
||||
AdjustWindowRectEx(&rect, style, FALSE, getWindowExStyle(window));
|
||||
ClientToScreen(window->win32.handle, (POINT*) &rect.left);
|
||||
ClientToScreen(window->win32.handle, (POINT*) &rect.right);
|
||||
SetWindowLongW(window->win32.handle, GWL_STYLE, style);
|
||||
SetWindowPos(window->win32.handle, HWND_TOP,
|
||||
rect.left, rect.top,
|
||||
rect.right - rect.left, rect.bottom - rect.top,
|
||||
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
}
|
||||
|
||||
// Translates a GLFW standard cursor to a resource ID
|
||||
//
|
||||
static LPWSTR translateCursorShape(int shape)
|
||||
@@ -1346,6 +1366,23 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
return IsZoomed(window->win32.handle);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
updateWindowStyles(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
updateWindowStyles(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
const HWND after = enabled ? HWND_TOPMOST : HWND_NOTOPMOST;
|
||||
SetWindowPos(window->win32.handle, after, 0, 0, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
@@ -704,6 +704,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
return window->decorated;
|
||||
case GLFW_FLOATING:
|
||||
return window->floating;
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
return window->autoIconify;
|
||||
case GLFW_CLIENT_API:
|
||||
return window->context.client;
|
||||
case GLFW_CONTEXT_CREATION_API:
|
||||
@@ -732,6 +734,52 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
|
||||
switch (attrib)
|
||||
{
|
||||
case GLFW_RESIZABLE:
|
||||
if (window->resizable != value)
|
||||
{
|
||||
window->resizable = value;
|
||||
if (!window->monitor)
|
||||
_glfwPlatformSetWindowResizable(window, value);
|
||||
}
|
||||
return;
|
||||
|
||||
case GLFW_DECORATED:
|
||||
if (window->decorated != value)
|
||||
{
|
||||
window->decorated = value;
|
||||
if (!window->monitor)
|
||||
_glfwPlatformSetWindowDecorated(window, value);
|
||||
}
|
||||
return;
|
||||
|
||||
case GLFW_FLOATING:
|
||||
if (window->floating != value)
|
||||
{
|
||||
window->floating = value;
|
||||
if (!window->monitor)
|
||||
_glfwPlatformSetWindowFloating(window, value);
|
||||
}
|
||||
return;
|
||||
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
window->autoIconify = value;
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute %i", attrib);
|
||||
}
|
||||
|
||||
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
|
||||
@@ -634,6 +634,27 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
return window->wl.maximized;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Window attribute setting not implemented yet");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Window attribute setting not implemented yet");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Window attribute setting not implemented yet");
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
handleEvents(0);
|
||||
|
||||
+102
-20
@@ -520,26 +520,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
if (!wndconfig->decorated)
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long functions;
|
||||
unsigned long decorations;
|
||||
long input_mode;
|
||||
unsigned long status;
|
||||
} hints;
|
||||
|
||||
hints.flags = 2; // Set decorations
|
||||
hints.decorations = 0; // No decorations
|
||||
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.MOTIF_WM_HINTS,
|
||||
_glfw.x11.MOTIF_WM_HINTS, 32,
|
||||
PropModeReplace,
|
||||
(unsigned char*) &hints,
|
||||
sizeof(hints) / sizeof(long));
|
||||
}
|
||||
_glfwPlatformSetWindowDecorated(window, GLFW_FALSE);
|
||||
|
||||
if (_glfw.x11.NET_WM_STATE && !window->monitor)
|
||||
{
|
||||
@@ -2065,6 +2046,107 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
return maximized;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
updateNormalHints(window, width, height);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
XDeleteProperty(_glfw.x11.display,
|
||||
window->x11.handle,
|
||||
_glfw.x11.MOTIF_WM_HINTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long functions;
|
||||
unsigned long decorations;
|
||||
long input_mode;
|
||||
unsigned long status;
|
||||
} hints;
|
||||
|
||||
hints.flags = 2; // Set decorations
|
||||
hints.decorations = 0; // No decorations
|
||||
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.MOTIF_WM_HINTS,
|
||||
_glfw.x11.MOTIF_WM_HINTS, 32,
|
||||
PropModeReplace,
|
||||
(unsigned char*) &hints,
|
||||
sizeof(hints) / sizeof(long));
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE)
|
||||
return;
|
||||
|
||||
if (_glfwPlatformWindowVisible(window))
|
||||
{
|
||||
const Atom action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
|
||||
sendEventToWM(window,
|
||||
_glfw.x11.NET_WM_STATE,
|
||||
action,
|
||||
_glfw.x11.NET_WM_STATE_ABOVE,
|
||||
0, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Atom* states;
|
||||
unsigned long i, count;
|
||||
|
||||
count = _glfwGetWindowPropertyX11(window->x11.handle,
|
||||
_glfw.x11.NET_WM_STATE,
|
||||
XA_ATOM,
|
||||
(unsigned char**) &states);
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == count)
|
||||
{
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||
PropModeAppend,
|
||||
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
|
||||
1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
|
||||
{
|
||||
states[i] = states[count - 1];
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) &states, count);
|
||||
}
|
||||
|
||||
XFree(states);
|
||||
}
|
||||
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
_glfwPollJoystickEvents();
|
||||
|
||||
Reference in New Issue
Block a user