Compare commits

...

13 Commits

Author SHA1 Message Date
Camilla Löwy d9d6f0f1f9 Start 3.5.1
Due to a misconfigured tool, an incorrect 3.5.0 tag was briefly made
available in the main Git repository.  Thanks to the manual intervention
of many packaging volunteers this has been almost entirely rolled back.
To make sure this release supersedes the incorrect tag everywhere, the
first release of GLFW 3.5 is named 3.5.1.

There are no code changes other than the version patch number.

Fixes #2758
2026-07-31 14:46:04 +02:00
Camilla Löwy deeadd3c30 Tag remaining Git and CI plumbing export-ignore 2026-07-28 17:39:40 +02:00
Camilla Löwy 0984b4354a Update changelog and add credit
Related to #2713
Related to #2810
2026-07-28 17:39:33 +02:00
road2react b7ef2919b0 Wayland: Fix rounding of fractional scale sizes
The framebuffer size for fractional scale surfaces should be rounded to
the closest integer, not truncated as is currently done.

This implements the rounding formula that the discussions over at
wayland-protocols item 132 and MR 309 appear to be converging on.

Fixes #2713
Closes #2810
2026-07-28 17:18:05 +02:00
Camilla Löwy 463cf73610 Win32: Fix scancode for media keys
Media key events were incorrectly reported with a scancode of 0x100.

This is based on a snippet by dougbinks in #2625.

Fixes #1768
Closes #2417
Fixes #2625
2026-07-09 21:51:02 +02:00
Jonas Ådahl ed6452b13c Wayland: Set the correct min/max size when non-resizable
Libdecor is a thin wrapper around xdg_toplevel, and expects the same
kind of information passed to it as if it was a xdg_toplevel. This
includes the min/max size when non-resizable, which was set when using
xdg_toplevel directly, but not when using libdecor. This fixes issues
with min/max size missing when mapping a non-resizable window.

Related to #2842
2026-06-26 16:30:12 +02:00
Camilla Löwy e94108d9db Wayland: Fix undecorated libdecor frame creation
In order to safely call libdecor_frame_set_visibility during window
creation, a libdecor frame state was synthesized and committed.

This commit instead postpones the call to libdecor_frame_set_visibility
until after the frame state received by the frame configure event has
been committed.  This appears to be a more polite approach.

Related to #2842
2026-06-26 16:30:12 +02:00
Camilla Löwy dc86d02ff1 Wayland: Fix some event types not being processed
If there was already an event available in the Wayland queue, that event
would be processed but other kinds of events (libdecor, key repeat,
joystick connection, etc.) would not be.

This commit restores the processing of all available events on every
call to glfw*Events.  It is partially based on #2842 by jadahl.

Because some libdecor plugins also process non-Wayland events, without
providing an fd for them, libdecor_dispatch is now called
unconditionally.

Fixes #2793
Closes #2795
Related to #2842
2026-06-26 16:26:43 +02:00
Camilla Löwy 06406a00a0 Wayland: Remove unused struct member 2026-06-10 01:07:02 +02:00
Tomáš Mráz de0c378aa2 Wayland: Conditionally define _GNU_SOURCE
This fixes a re-definition warning for the _GNU_SOURCE macro.

Edited by elmindreda: code formatting, author credit

Related to go-gl/glfw#359
Fixes #2833
2026-06-10 01:07:02 +02:00
Camilla Löwy 567b1ec244 Cocoa: Fix some key events not being emitted
The key combinations Cmd+Period, Ctrl+Tab and Ctrl+Esc are not passed to
the first responder as key events.

This commit catches and claims these specific key events via the key
equivalents mechanism and emits them from there instead.

Closes #1362
Fixes #2278
2026-06-09 21:56:04 +02:00
Camilla Löwy 0136febb1e Add credit
Related to #2863
2026-06-09 21:56:04 +02:00
halx99 6c397996b8 Fix Windows CI
Closes #2863
2026-06-09 21:55:55 +02:00
12 changed files with 121 additions and 50 deletions
+2
View File
@@ -3,3 +3,5 @@
.gitattributes export-ignore .gitattributes export-ignore
.travis.yml export-ignore .travis.yml export-ignore
.appveyor.yml export-ignore .appveyor.yml export-ignore
.mailmap export-ignore
.github export-ignore
+5 -5
View File
@@ -74,8 +74,8 @@ jobs:
- name: Build Cocoa shared library - name: Build Cocoa shared library
run: cmake --build build-cocoa-shared --parallel run: cmake --build build-cocoa-shared --parallel
build-windows-vs2022: build-windows-msvc:
name: Windows (VS2022) name: Windows (MSVC)
runs-on: windows-latest runs-on: windows-latest
timeout-minutes: 4 timeout-minutes: 4
env: env:
@@ -84,17 +84,17 @@ jobs:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
- name: Configure Win32 shared x86 library - name: Configure Win32 shared x86 library
run: cmake -B build-win32-shared-x86 -G "Visual Studio 17 2022" -A Win32 -D BUILD_SHARED_LIBS=ON run: cmake -B build-win32-shared-x86 -A Win32 -D BUILD_SHARED_LIBS=ON
- name: Build Win32 shared x86 library - name: Build Win32 shared x86 library
run: cmake --build build-win32-shared-x86 --parallel run: cmake --build build-win32-shared-x86 --parallel
- name: Configure Win32 static x64 library - name: Configure Win32 static x64 library
run: cmake -B build-win32-static-x64 -G "Visual Studio 17 2022" -A x64 run: cmake -B build-win32-static-x64 -A x64
- name: Build Win32 static x64 library - name: Build Win32 static x64 library
run: cmake --build build-win32-static-x64 --parallel run: cmake --build build-win32-static-x64 --parallel
- name: Configure Win32 shared x64 library - name: Configure Win32 shared x64 library
run: cmake -B build-win32-shared-x64 -G "Visual Studio 17 2022" -A x64 -D BUILD_SHARED_LIBS=ON run: cmake -B build-win32-shared-x64 -A x64 -D BUILD_SHARED_LIBS=ON
- name: Build Win32 shared x64 library - name: Build Win32 shared x64 library
run: cmake --build build-win32-shared-x64 --parallel run: cmake --build build-win32-shared-x64 --parallel
+1 -1
View File
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.16...3.28 FATAL_ERROR) cmake_minimum_required(VERSION 3.16...3.28 FATAL_ERROR)
project(GLFW VERSION 3.5.0 LANGUAGES C HOMEPAGE_URL "https://www.glfw.org/") project(GLFW VERSION 3.5.1 LANGUAGES C HOMEPAGE_URL "https://www.glfw.org/")
set_property(GLOBAL PROPERTY USE_FOLDERS ON) set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+6
View File
@@ -6,6 +6,7 @@ excludes other invaluable contributions like language bindings and text and
video tutorials. video tutorials.
- Bobyshev Alexander - Bobyshev Alexander
- Alzathar
- Laurent Aphecetche - Laurent Aphecetche
- Matt Arsenault - Matt Arsenault
- Takuro Ashie - Takuro Ashie
@@ -56,6 +57,7 @@ video tutorials.
- Bill Currie - Bill Currie
- Jason Daly - Jason Daly
- danhambleton - danhambleton
- danijel1023
- Jarrod Davis - Jarrod Davis
- Aaron Day - Aaron Day
- decce - decce
@@ -98,6 +100,7 @@ video tutorials.
- Andrew Gutekanst - Andrew Gutekanst
- Stephen Gutekanst - Stephen Gutekanst
- Jonathan Hale - Jonathan Hale
- halx99
- Daniel Hauser - Daniel Hauser
- hdf89shfdfs - hdf89shfdfs
- Moritz Heinemann - Moritz Heinemann
@@ -181,6 +184,7 @@ video tutorials.
- Jon Morton - Jon Morton
- Pierre Moulon - Pierre Moulon
- Martins Mozeiko - Martins Mozeiko
- Tomáš Mráz
- Pascal Muetschard - Pascal Muetschard
- James Murphy - James Murphy
- Julian Møller - Julian Møller
@@ -227,6 +231,7 @@ video tutorials.
- Philip Rideout - Philip Rideout
- Eddie Ringle - Eddie Ringle
- Max Risuhin - Max Risuhin
- road2react
- Joe Roback - Joe Roback
- Jorge Rodriguez - Jorge Rodriguez
- Jari Ronkainen - Jari Ronkainen
@@ -234,6 +239,7 @@ video tutorials.
- Ed Ropple - Ed Ropple
- Aleksey Rybalkin - Aleksey Rybalkin
- Mikko Rytkönen - Mikko Rytkönen
- saikyun
- Riku Salminen - Riku Salminen
- Yoshinori Sano - Yoshinori Sano
- Brandon Schaefer - Brandon Schaefer
+10
View File
@@ -118,6 +118,10 @@ guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
information on what to include when reporting a bug. information on what to include when reporting a bug.
## Changelog since 3.5
None.
## Changelog since 3.4 ## Changelog since 3.4
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
@@ -127,8 +131,11 @@ information on what to include when reporting a bug.
- Updated minimum CMake version to 3.16 (#2541) - Updated minimum CMake version to 3.16 (#2541)
- Removed support for building with original MinGW (#2540) - Removed support for building with original MinGW (#2540)
- [Win32] Removed support for Windows XP and Vista (#2505) - [Win32] Removed support for Windows XP and Vista (#2505)
- [Win32] Bugfix: Media keys were reported with a scancode of 256 (#1768,#2417,#2625)
- [Cocoa] Added `QuartzCore` framework as link-time dependency - [Cocoa] Added `QuartzCore` framework as link-time dependency
- [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506) - [Cocoa] Removed support for OS X 10.10 Yosemite and earlier (#2506)
- [Cocoa] Bugfix: Cmd+Period, Ctrl+Tab and Ctrl+Esc key events were not emitted
(#1362,#2278)
- [Wayland] Bugfix: The fractional scaling related objects were not destroyed - [Wayland] Bugfix: The fractional scaling related objects were not destroyed
- [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517) - [Wayland] Bugfix: `glfwInit` would segfault on compositor with no seat (#2517)
- [Wayland] Bugfix: A drag entering a non-GLFW surface could cause a segfault - [Wayland] Bugfix: A drag entering a non-GLFW surface could cause a segfault
@@ -157,6 +164,9 @@ information on what to include when reporting a bug.
was suspended (#1350,#2582,#2640,#2719,#2723,#2800,#2827) was suspended (#1350,#2582,#2640,#2719,#2723,#2800,#2827)
- [Wayland] Bugfix: `glfwPostEmptyEvent` would leak a callback proxy (#2836) - [Wayland] Bugfix: `glfwPostEmptyEvent` would leak a callback proxy (#2836)
- [Wayland] Bugfix: `glfwHideWindow` did not always send its request immediately - [Wayland] Bugfix: `glfwHideWindow` did not always send its request immediately
- [Wayland] Bugfix: Some event types were not always processed by `glfwPollEvents` or
`glfwWait*Events` (#2793,#2795)
- [Wayland] Bugfix: Scaled framebuffer size was sometimes incorect (#2713,#2810)
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631) - [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
- [X11] Bugfix: Occasional crash when an idle display awakes (#2766) - [X11] Bugfix: Occasional crash when an idle display awakes (#2766)
- [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale - [X11] Bugfix: Prevent BadWindow when creating small windows with a content scale
+8
View File
@@ -3,6 +3,14 @@
[TOC] [TOC]
## Why was there no 3.5.0 release?
Due to a misconfigured tool, an incorrect `3.5.0` tag was briefly made available in the
main Git repository. Thanks to the manual intervention of many packaging volunteers this
has been almost entirely rolled back. To make sure the first actual release of GLFW 3.5
replaces the incorrect tag everywhere, the first release is named 3.5.1.
## New features {#features} ## New features {#features}
### Unlimited mouse buttons {#unlimited_mouse_buttons} ### Unlimited mouse buttons {#unlimited_mouse_buttons}
+1 -1
View File
@@ -298,7 +298,7 @@ extern "C" {
* release is made that does not contain any API changes. * release is made that does not contain any API changes.
* @ingroup init * @ingroup init
*/ */
#define GLFW_VERSION_REVISION 0 #define GLFW_VERSION_REVISION 1
/*! @} */ /*! @} */
/*! @brief One. /*! @brief One.
+28
View File
@@ -599,6 +599,34 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
_glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods); _glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);
} }
- (BOOL)performKeyEquivalent:(NSEvent *)event
{
// HACK: Some key combinations are consumed before reaching keyDown:
// so we claim those events and emit them here
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
if (mods & GLFW_MOD_CONTROL)
{
if (key == GLFW_KEY_TAB || key == GLFW_KEY_ESCAPE)
{
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
return YES;
}
}
if (mods & GLFW_MOD_SUPER)
{
if (key == GLFW_KEY_PERIOD)
{
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
return YES;
}
}
return [super performKeyEquivalent:event];
}
- (void)scrollWheel:(NSEvent *)event - (void)scrollWheel:(NSEvent *)event
{ {
double deltaX = [event scrollingDeltaX]; double deltaX = [event scrollingDeltaX];
+5 -4
View File
@@ -711,11 +711,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
const int mods = getKeyMods(); const int mods = getKeyMods();
scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff)); scancode = (HIWORD(lParam) & (KF_EXTENDED | 0xff));
if (!scancode) if (!(scancode & 0xff))
{ {
// NOTE: Some synthetic key messages have a scancode of zero // NOTE: Both media keys and the synthetic key messages from Windows
// HACK: Map the virtual key back to a usable scancode // Clipboard History are reported with a scancode of zero
scancode = MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC); // HACK: Map the virtual key to a scancode but preserve extended bit
scancode |= MapVirtualKeyW((UINT) wParam, MAPVK_VK_TO_VSC);
} }
// HACK: Alt+PrtSc has a different scancode than just PrtSc // HACK: Alt+PrtSc has a different scancode than just PrtSc
+3
View File
@@ -798,6 +798,8 @@ int _glfwInitWayland(void)
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities"); _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities");
_glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility) _glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility)
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility"); _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility");
_glfw.wl.libdecor.libdecor_frame_is_visible_ = (PFN_libdecor_frame_is_visible)
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_is_visible");
_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel) _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel)
_glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel"); _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel");
_glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size) _glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size)
@@ -829,6 +831,7 @@ int _glfwInitWayland(void)
!_glfw.wl.libdecor.libdecor_frame_set_capabilities_ || !_glfw.wl.libdecor.libdecor_frame_set_capabilities_ ||
!_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ || !_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ ||
!_glfw.wl.libdecor.libdecor_frame_set_visibility_ || !_glfw.wl.libdecor.libdecor_frame_set_visibility_ ||
!_glfw.wl.libdecor.libdecor_frame_is_visible_ ||
!_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ || !_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ ||
!_glfw.wl.libdecor.libdecor_configuration_get_content_size_ || !_glfw.wl.libdecor.libdecor_configuration_get_content_size_ ||
!_glfw.wl.libdecor.libdecor_configuration_get_window_state_ || !_glfw.wl.libdecor.libdecor_configuration_get_window_state_ ||
+3 -1
View File
@@ -311,6 +311,7 @@ typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities); typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities); typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible); typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible);
typedef bool (* PFN_libdecor_frame_is_visible)(struct libdecor_frame*);
typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*); typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*);
typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*); typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*);
typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*); typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*);
@@ -336,6 +337,7 @@ typedef void (* PFN_libdecor_state_free)(struct libdecor_state*);
#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_ #define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_
#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ #define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_
#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_ #define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_
#define libdecor_frame_is_visible _glfw.wl.libdecor.libdecor_frame_is_visible_
#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ #define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_
#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_ #define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_
#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_ #define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_
@@ -375,7 +377,6 @@ typedef struct _GLFWwindowWayland
GLFWbool transparent; GLFWbool transparent;
GLFWbool scaleFramebuffer; GLFWbool scaleFramebuffer;
struct wl_surface* surface; struct wl_surface* surface;
struct wl_callback* callback;
struct { struct {
struct wl_event_queue* queue; struct wl_event_queue* queue;
@@ -616,6 +617,7 @@ typedef struct _GLFWlibraryWayland
PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_; PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_;
PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_; PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_;
PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_; PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_;
PFN_libdecor_frame_is_visible libdecor_frame_is_visible_;
PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_; PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_;
PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_; PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_;
PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_; PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_;
+37 -26
View File
@@ -24,7 +24,9 @@
// //
//======================================================================== //========================================================================
#define _GNU_SOURCE #if !defined(_GNU_SOURCE)
#define _GNU_SOURCE
#endif
#include "internal.h" #include "internal.h"
@@ -476,8 +478,9 @@ static void resizeFramebuffer(_GLFWwindow* window)
{ {
if (window->wl.fractionalScale) if (window->wl.fractionalScale)
{ {
window->wl.fbWidth = (window->wl.width * window->wl.scalingNumerator) / 120; // Round halfway away from zero per fractional-scale-v1 protocol spec
window->wl.fbHeight = (window->wl.height * window->wl.scalingNumerator) / 120; window->wl.fbWidth = (window->wl.width * window->wl.scalingNumerator + 60) / 120;
window->wl.fbHeight = (window->wl.height * window->wl.scalingNumerator + 60) / 120;
} }
else else
{ {
@@ -894,6 +897,10 @@ void libdecorFrameHandleConfigure(struct libdecor_frame* frame,
libdecor_frame_commit(frame, frameState, config); libdecor_frame_commit(frame, frameState, config);
libdecor_state_free(frameState); libdecor_state_free(frameState);
// NOTE: Frame visibility must only be set after a frame state has been committed
if (window->decorated != libdecor_frame_is_visible(window->wl.libdecor.frame))
libdecor_frame_set_visibility(window->wl.libdecor.frame, window->decorated);
if (window->wl.activated != activated) if (window->wl.activated != activated)
{ {
window->wl.activated = activated; window->wl.activated = activated;
@@ -975,16 +982,13 @@ static GLFWbool createLibdecorFrame(_GLFWwindow* window)
return GLFW_FALSE; return GLFW_FALSE;
} }
struct libdecor_state* frameState =
libdecor_state_new(window->wl.width, window->wl.height);
libdecor_frame_commit(window->wl.libdecor.frame, frameState, NULL);
libdecor_state_free(frameState);
if (strlen(window->wl.appId)) if (strlen(window->wl.appId))
libdecor_frame_set_app_id(window->wl.libdecor.frame, window->wl.appId); libdecor_frame_set_app_id(window->wl.libdecor.frame, window->wl.appId);
libdecor_frame_set_title(window->wl.libdecor.frame, window->title); libdecor_frame_set_title(window->wl.libdecor.frame, window->title);
if (window->resizable)
{
if (window->minwidth != GLFW_DONT_CARE && if (window->minwidth != GLFW_DONT_CARE &&
window->minheight != GLFW_DONT_CARE) window->minheight != GLFW_DONT_CARE)
{ {
@@ -1000,11 +1004,17 @@ static GLFWbool createLibdecorFrame(_GLFWwindow* window)
window->maxwidth, window->maxwidth,
window->maxheight); window->maxheight);
} }
}
if (!window->resizable) else
{ {
libdecor_frame_unset_capabilities(window->wl.libdecor.frame, libdecor_frame_unset_capabilities(window->wl.libdecor.frame,
LIBDECOR_ACTION_RESIZE); LIBDECOR_ACTION_RESIZE);
libdecor_frame_set_min_content_size(window->wl.libdecor.frame,
window->wl.width,
window->wl.height);
libdecor_frame_set_max_content_size(window->wl.libdecor.frame,
window->wl.width,
window->wl.height);
} }
if (window->monitor) if (window->monitor)
@@ -1015,12 +1025,11 @@ static GLFWbool createLibdecorFrame(_GLFWwindow* window)
} }
else else
{ {
// Frame visibility is applied in libdecorFrameHandleConfigure
if (window->wl.maximized) if (window->wl.maximized)
libdecor_frame_set_maximized(window->wl.libdecor.frame); libdecor_frame_set_maximized(window->wl.libdecor.frame);
if (!window->decorated)
libdecor_frame_set_visibility(window->wl.libdecor.frame, false);
setIdleInhibitor(window, GLFW_FALSE); setIdleInhibitor(window, GLFW_FALSE);
} }
@@ -1373,24 +1382,27 @@ static void handleEvents(double* timeout)
#endif #endif
GLFWbool event = GLFW_FALSE; GLFWbool event = GLFW_FALSE;
enum { DISPLAY_FD, KEYREPEAT_FD, CURSOR_FD, LIBDECOR_FD }; enum { DISPLAY_FD, KEYREPEAT_FD, CURSOR_FD };
struct pollfd fds[] = struct pollfd fds[] =
{ {
[DISPLAY_FD] = { wl_display_get_fd(_glfw.wl.display), POLLIN }, [DISPLAY_FD] = { wl_display_get_fd(_glfw.wl.display), POLLIN },
[KEYREPEAT_FD] = { _glfw.wl.keyRepeatTimerfd, POLLIN }, [KEYREPEAT_FD] = { _glfw.wl.keyRepeatTimerfd, POLLIN },
[CURSOR_FD] = { _glfw.wl.cursorTimerfd, POLLIN }, [CURSOR_FD] = { _glfw.wl.cursorTimerfd, POLLIN }
[LIBDECOR_FD] = { -1, POLLIN }
}; };
if (_glfw.wl.libdecor.context)
fds[LIBDECOR_FD].fd = libdecor_get_fd(_glfw.wl.libdecor.context);
while (!event) while (!event)
{ {
if (_glfw.wl.libdecor.context)
{
// Dispatch unconditionally because it also processes non-Wayland events
if (libdecor_dispatch(_glfw.wl.libdecor.context, 0) > 0)
event = GLFW_TRUE;
}
while (wl_display_prepare_read(_glfw.wl.display) != 0) while (wl_display_prepare_read(_glfw.wl.display) != 0)
{ {
if (wl_display_dispatch_pending(_glfw.wl.display) > 0) if (wl_display_dispatch_pending(_glfw.wl.display) > 0)
return; event = GLFW_TRUE;
} }
// If an error other than EAGAIN happens, we have likely been disconnected // If an error other than EAGAIN happens, we have likely been disconnected
@@ -1409,6 +1421,11 @@ static void handleEvents(double* timeout)
return; return;
} }
double immediate = 0.0;
if (event)
timeout = &immediate;
if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout)) if (!_glfwPollPOSIX(fds, sizeof(fds) / sizeof(fds[0]), timeout))
{ {
wl_display_cancel_read(_glfw.wl.display); wl_display_cancel_read(_glfw.wl.display);
@@ -1455,12 +1472,6 @@ static void handleEvents(double* timeout)
if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8) if (read(_glfw.wl.cursorTimerfd, &repeats, sizeof(repeats)) == 8)
incrementCursorImage(); incrementCursorImage();
} }
if (fds[LIBDECOR_FD].revents & POLLIN)
{
if (libdecor_dispatch(_glfw.wl.libdecor.context, 0) > 0)
event = GLFW_TRUE;
}
} }
} }