mirror of
https://github.com/glfw/glfw.git
synced 2025-09-03 20:41:49 +00:00
Compare commits
10 Commits
b4c6d510f5
...
bbe868d44e
Author | SHA1 | Date | |
---|---|---|---|
|
bbe868d44e | ||
|
63a7e8b7f8 | ||
|
acb92944d4 | ||
|
7ef6efeb66 | ||
|
3cf9f6726d | ||
|
bfa1c424e5 | ||
|
06f21df20e | ||
|
c31de75111 | ||
|
f269a6af97 | ||
|
f1f869acf7 |
@ -55,6 +55,7 @@ video tutorials.
|
||||
- Jason Daly
|
||||
- danhambleton
|
||||
- Jarrod Davis
|
||||
- decce
|
||||
- Olivier Delannoy
|
||||
- Paul R. Deppe
|
||||
- Michael Dickens
|
||||
@ -296,6 +297,7 @@ video tutorials.
|
||||
- Jonas Ådahl
|
||||
- Lasse Öörni
|
||||
- Leonard König
|
||||
- Alex Sanchez-Stern
|
||||
- All the unmentioned and anonymous contributors in the GLFW community, for bug
|
||||
reports, patches, feedback, testing and encouragement
|
||||
|
||||
|
13
README.md
13
README.md
@ -134,17 +134,25 @@ information on what to include when reporting a bug.
|
||||
- [Wayland] Bugfix: Ignore key repeat events when no window has keyboard focus (#2727)
|
||||
- [Wayland] Bugfix: Reset key repeat timer when window destroyed (#2741,#2727)
|
||||
- [Wayland] Bugfix: Memory would leak if reading a data offer failed midway
|
||||
- [Wayland] Bugfix: Keyboard leave event handler now processes key repeats (#2736)
|
||||
- [Wayland] Bugfix: Retrieved cursor position would be incorrect when hovering over
|
||||
fallback decorations
|
||||
- [Wayland] Bugfix: Fallback decorations would report scroll events
|
||||
- [Wayland] Bugfix: Keyboard repeat events halted when any key is released (#2568)
|
||||
- [Wayland] Bugfix: Fallback decorations would show menu at wrong position
|
||||
- [Wayland] Bugfix: The cursor was not updated when clicking through from
|
||||
a modal to a fallback decoration
|
||||
- [Wayland] Bugfix: The cursor position was not updated when clicking through
|
||||
from a modal to the content area
|
||||
- [X11] Bugfix: Running without a WM could trigger an assert (#2593,#2601,#2631)
|
||||
- [Null] Added Vulkan 'window' surface creation via `VK_EXT_headless_surface`
|
||||
- [Null] Added EGL context creation on Mesa via `EGL_MESA_platform_surfaceless`
|
||||
- [EGL] Allowed native access on Wayland with `GLFW_CONTEXT_CREATION_API` set to
|
||||
`GLFW_NATIVE_CONTEXT_API` (#2518)
|
||||
|
||||
- [X11] Added `getSelectionRequestHandler`, `setSelectionRequestHander`,
|
||||
`getGLFWDisplay`, and `getGLFWHelperWindow` functions. to allow
|
||||
clients to implement more X clipboard functionality than is
|
||||
built-in; with these primitives clients can add copy paste support
|
||||
for files, images, colors, and other non-text data types.
|
||||
|
||||
## Contact
|
||||
|
||||
@ -160,4 +168,3 @@ request, please file it in the
|
||||
|
||||
Finally, if you're interested in helping out with the development of GLFW or
|
||||
porting it to your favorite platform, join us on the forum or GitHub.
|
||||
|
||||
|
@ -973,6 +973,53 @@ The contents of the system clipboard can be set to a UTF-8 encoded string with
|
||||
glfwSetClipboardString(NULL, "A string with words in it");
|
||||
```
|
||||
|
||||
\par Advanced Usage
|
||||
While GLFW does not directly support using other data types with the
|
||||
system clipboard, on many platforms this is possible using platform
|
||||
specific code. If you are primarily targetting a small set of
|
||||
platforms, this may be viable for your application.
|
||||
|
||||
\par
|
||||
On Windows, you can do clipboard operations directly using <a
|
||||
href="https://learn.microsoft.com/en-us/windows/win32/api/winuser/">winuser.h</a>,
|
||||
allowing you to copy and paste datatypes other than text. On X11 you
|
||||
can also use the platform specific API to get this functionality, but
|
||||
you must hook into GLFW's X11 event handling code to allow copying
|
||||
<i>out</i> of your application. Example code for most of this functionality
|
||||
can be found in general X11 documentation like <a
|
||||
href="http://www.uninformativ.de/blog/postings/2017-04-02/0/POSTING-en.html">this
|
||||
page</a>; the GLFW-specific part is including
|
||||
|
||||
\par
|
||||
@code
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <X11/Xlib.h>
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#include <GLFW/glfw3native.h>
|
||||
@endcode
|
||||
|
||||
\par
|
||||
At the top of your file (guarded by platform), and then running
|
||||
|
||||
\par
|
||||
@code
|
||||
setSelectionRequestHandler(myHandler);
|
||||
@endcode
|
||||
|
||||
\par
|
||||
on initialization. Your selection handler must have the signature:
|
||||
|
||||
\par
|
||||
@code
|
||||
void myHandler(XEvent*);
|
||||
@endcode
|
||||
|
||||
\par
|
||||
and it will receive all X Selection events. To ensure compatibility
|
||||
use `getGLFWDisplay()` to get a display object instead of
|
||||
`XOpenDisplay()` and use the result of `getGLFWHelperWindow()` as the
|
||||
target window for the selection.
|
||||
|
||||
|
||||
## Path drop input {#path_drop}
|
||||
|
||||
|
@ -255,3 +255,7 @@ hardware gamma correction, which today is typically an approximation of sRGB
|
||||
gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will
|
||||
produce the default (usually sRGB-like) behavior.
|
||||
|
||||
@note @wayland An application cannot read or modify the monitor gamma ramp. The
|
||||
@ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions
|
||||
emit @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
|
||||
|
25
docs/news.md
25
docs/news.md
@ -14,6 +14,25 @@ values over 8. For compatibility with older versions, the
|
||||
@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of
|
||||
this.
|
||||
|
||||
|
||||
### Support for custom X11 clipboard functionality {#x11_custom_selection}
|
||||
|
||||
This change allows clients to implement custom X11 clipboard
|
||||
functionality like the copying and pasting of files across
|
||||
applications.
|
||||
|
||||
GLFW itself only allows plain text to be copied to the
|
||||
clipboard and back on all platforms. On some platforms, like Windows,
|
||||
you can use platform specific APIs to add extra clipboard
|
||||
functionality like copying of other data types. However, on X11, this
|
||||
was previously not fully possible due to the fact that GLFW internal
|
||||
code has full control over the X11 event queue.
|
||||
|
||||
This change exposes several new symbols that allow you to get and set
|
||||
the handler for X11 selection events that GLFW will use. It also
|
||||
allows getting the internal display connection and selection helper
|
||||
window, for use in that kind of code.
|
||||
|
||||
## Caveats {#caveats}
|
||||
|
||||
## Deprecations {#deprecations}
|
||||
@ -39,6 +58,12 @@ actively maintained and available on many platforms.
|
||||
|
||||
### New functions {#new_functions}
|
||||
|
||||
#### X11-specific
|
||||
- @ref getSelectionRequestHandler
|
||||
- @ref setSelectionRequestHanddler
|
||||
- @ref getGLFWDisplay
|
||||
- @ref getGLFWHelperWindow
|
||||
|
||||
### New types {#new_types}
|
||||
|
||||
### New constants {#new_constants}
|
||||
|
@ -893,6 +893,12 @@ int xpos, ypos;
|
||||
glfwGetWindowPos(window, &xpos, &ypos);
|
||||
```
|
||||
|
||||
@note @wayland An applications cannot know the positions of its windows or
|
||||
whether one has been moved. The @ref GLFW_POSITION_X and @ref GLFW_POSITION_Y
|
||||
window hints are ignored. The @ref glfwGetWindowPos and @ref glfwSetWindowPos
|
||||
functions emit @ref GLFW_FEATURE_UNAVAILABLE. The window position callback will
|
||||
not be called.
|
||||
|
||||
|
||||
### Window title {#window_title}
|
||||
|
||||
@ -1038,6 +1044,12 @@ You can also get the current iconification state with @ref glfwGetWindowAttrib.
|
||||
int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED);
|
||||
```
|
||||
|
||||
@note @wayland An application cannot know if any of its windows have been
|
||||
iconified or restore one from iconification. The @ref glfwRestoreWindow
|
||||
function can only restore windows from maximization and the iconify callback
|
||||
will not be called. The [GLFW_ICONIFIED](@ref GLFW_ICONIFIED_attrib) attribute
|
||||
will be false. The @ref glfwIconifyWindow function works normally.
|
||||
|
||||
|
||||
### Window maximization {#window_maximize}
|
||||
|
||||
|
@ -2915,8 +2915,8 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,
|
||||
* @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
* @remark @wayland Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -2939,8 +2939,8 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR
|
||||
* and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
|
||||
* @remark @wayland Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
|
||||
* returning `NULL`.
|
||||
*
|
||||
* @pointer_lifetime The returned structure and its arrays are allocated and
|
||||
@ -2983,8 +2983,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
|
||||
*
|
||||
* @remark @win32 The gamma ramp size must be 256.
|
||||
*
|
||||
* @remark @wayland Gamma handling is a privileged protocol, this function
|
||||
* will thus never be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
* @remark @wayland Monitor gamma is a privileged protocol, so this function
|
||||
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @pointer_lifetime The specified gamma ramp is copied before this function
|
||||
* returns.
|
||||
@ -3430,8 +3430,8 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland There is no way for an application to retrieve the global
|
||||
* position of its windows. This function will emit @ref
|
||||
* @remark @wayland Window positions are not currently part of any common
|
||||
* Wayland protocol, so this function cannot be implemented and will emit @ref
|
||||
* GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3464,8 +3464,8 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
|
||||
*
|
||||
* @remark @wayland There is no way for an application to set the global
|
||||
* position of its windows. This function will emit @ref
|
||||
* @remark @wayland Window positions are not currently part of any common
|
||||
* Wayland protocol, so this function cannot be implemented and will emit @ref
|
||||
* GLFW_FEATURE_UNAVAILABLE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
@ -3807,10 +3807,6 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Once a window is iconified, @ref glfwRestoreWindow won’t
|
||||
* be able to restore it. This is a design decision of the xdg-shell
|
||||
* protocol.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_iconify
|
||||
@ -3838,6 +3834,10 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @remark @wayland Restoring a window from maximization is not currently part
|
||||
* of any common Wayland protocol, so this function can only restore windows
|
||||
* from maximization.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_iconify
|
||||
@ -4058,8 +4058,8 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
|
||||
* affected by any resizing or mode switching, although you may need to update
|
||||
* your viewport if the framebuffer size has changed.
|
||||
*
|
||||
* @remark @wayland The desired window position is ignored, as there is no way
|
||||
* for an application to set this property.
|
||||
* @remark @wayland Window positions are not currently part of any common
|
||||
* Wayland protocol. The window position arguments are ignored.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -4096,8 +4096,9 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
|
||||
* errors. However, this function should not fail as long as it is passed
|
||||
* valid arguments and the library has been [initialized](@ref intro_init).
|
||||
*
|
||||
* @remark @wayland The Wayland protocol provides no way to check whether a
|
||||
* window is iconfied, so @ref GLFW_ICONIFIED always returns `GLFW_FALSE`.
|
||||
* @remark @wayland Checking whether a window is iconified is not currently
|
||||
* part of any common Wayland protocol, so the @ref GLFW_ICONIFIED attribute
|
||||
* cannot be implemented and is always `GLFW_FALSE`.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -4219,8 +4220,8 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @wayland This callback will never be called, as there is no way for
|
||||
* an application to know its global position.
|
||||
* @remark @wayland This callback will not be called. The Wayland protocol
|
||||
* provides no way to be notified of when a window is moved.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
@ -4395,6 +4396,10 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @remark @wayland This callback will not be called. The Wayland protocol
|
||||
* provides no way to be notified of when a window is iconified, and no way to
|
||||
* check whether a window is currently iconified.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref window_iconify
|
||||
|
@ -442,6 +442,13 @@ GLFWAPI void glfwSetX11SelectionString(const char* string);
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetX11SelectionString(void);
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
void (*getSelectionRequestHandler(void))(XEvent*);
|
||||
void setSelectionRequestHandler(void (*handler)(XEvent*));
|
||||
Display* getGLFWDisplay(void);
|
||||
Window getGLFWHelperWindow(void);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
|
@ -405,13 +405,19 @@ static void handleFallbackDecorationButton(_GLFWwindow* window,
|
||||
}
|
||||
else if (button == BTN_RIGHT)
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
{
|
||||
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
||||
_glfw.wl.seat, serial,
|
||||
window->wl.cursorPosX,
|
||||
window->wl.cursorPosY);
|
||||
}
|
||||
if (!window->wl.xdg.toplevel)
|
||||
return;
|
||||
|
||||
if (window->wl.fallback.focus != window->wl.fallback.top.surface)
|
||||
return;
|
||||
|
||||
if (ypos < GLFW_BORDER_SIZE)
|
||||
return;
|
||||
|
||||
xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
|
||||
_glfw.wl.seat, serial,
|
||||
xpos,
|
||||
ypos - GLFW_CAPTION_HEIGHT - GLFW_BORDER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1532,11 +1538,21 @@ static void pointerHandleEnter(void* userData,
|
||||
window->wl.hovered = GLFW_TRUE;
|
||||
_glfwSetCursorWayland(window, window->wl.currentCursor);
|
||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||
|
||||
if (window->cursorMode != GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||
_glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->wl.fallback.decorations)
|
||||
{
|
||||
window->wl.fallback.focus = surface;
|
||||
updateFallbackDecorationCursor(window, sx, sy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1315,6 +1315,8 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
|
||||
_glfw.x11.xlib.handle = module;
|
||||
|
||||
*platform = x11;
|
||||
|
||||
handleSelectionRequest = handleSelectionRequest_;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
|
@ -896,6 +896,8 @@ typedef struct _GLFWcursorX11
|
||||
Cursor handle;
|
||||
} _GLFWcursorX11;
|
||||
|
||||
extern void (*handleSelectionRequest)(XEvent*);
|
||||
void handleSelectionRequest_(XEvent* event);
|
||||
|
||||
GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform);
|
||||
int _glfwInitX11(void);
|
||||
|
@ -921,7 +921,8 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
||||
return None;
|
||||
}
|
||||
|
||||
static void handleSelectionRequest(XEvent* event)
|
||||
void (*handleSelectionRequest)(XEvent*);
|
||||
void handleSelectionRequest_(XEvent* event)
|
||||
{
|
||||
const XSelectionRequestEvent* request = &event->xselectionrequest;
|
||||
|
||||
@ -3356,6 +3357,18 @@ GLFWAPI const char* glfwGetX11SelectionString(void)
|
||||
|
||||
return getSelectionString(_glfw.x11.PRIMARY);
|
||||
}
|
||||
void (*getSelectionRequestHandler(void))(XEvent*) {
|
||||
return handleSelectionRequest;
|
||||
}
|
||||
void setSelectionRequestHandler(void (*handler)(XEvent*)) {
|
||||
handleSelectionRequest = handler;
|
||||
}
|
||||
Display* getGLFWDisplay(void) {
|
||||
return _glfw.x11.display;
|
||||
}
|
||||
|
||||
Window getGLFWHelperWindow(void) {
|
||||
return _glfw.x11.helperWindowHandle;
|
||||
}
|
||||
|
||||
#endif // _GLFW_X11
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user