aboutsummaryrefslogtreecommitdiffstats
path: root/src/x11.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-05-21 16:05:28 -0400
committerDavid Robillard <d@drobilla.net>2022-05-21 16:24:53 -0400
commitc6238d974edbb5ce41f99d8457fe7ce09dd26abf (patch)
tree48f19e2a9f3b91a65f10f7d52a84a281e1c0b441 /src/x11.c
parent2b6dd4c37f40496741cf69fe315f47b3032b16fa (diff)
downloadpugl-c6238d974edbb5ce41f99d8457fe7ce09dd26abf.tar.gz
pugl-c6238d974edbb5ce41f99d8457fe7ce09dd26abf.tar.bz2
pugl-c6238d974edbb5ce41f99d8457fe7ce09dd26abf.zip
X11: Use cursor themes
This changes to getting cursors by name from the cursor theme, which makes the cursor match the ones used in modern desktop environments. As far as I can tell, there is no real standard for names, these ones seem to work for me in GNOME, KDE, and Xfce. I am not sure about the compatibility concerns here, but X11 without Xcursor themes strikes me as either too esoteric or too ancient to worry about, especially since cursor switching isn't critical functionality anyway.
Diffstat (limited to 'src/x11.c')
-rw-r--r--src/x11.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/src/x11.c b/src/x11.c
index cce1f8c..ca23a76 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -28,7 +28,6 @@
#ifdef HAVE_XCURSOR
# include <X11/Xcursor/Xcursor.h>
-# include <X11/cursorfont.h>
#endif
#include <sys/select.h>
@@ -65,6 +64,18 @@ enum WmClientStateMessageAction {
WM_STATE_TOGGLE
};
+#define NUM_CURSORS ((unsigned)PUGL_CURSOR_UP_DOWN + 1u)
+
+static const char* const cursor_names[NUM_CURSORS] = {
+ "default", // ARROW
+ "text", // CARET
+ "crosshair", // CROSSHAIR
+ "pointer", // HAND
+ "not-allowed", // NO
+ "sb_h_double_arrow", // LEFT_RIGHT
+ "sb_v_double_arrow" // UP_DOWN
+};
+
static bool
initXSync(PuglWorldInternals* const impl)
{
@@ -150,7 +161,7 @@ puglInitViewInternals(void)
PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
#ifdef HAVE_XCURSOR
- impl->cursorShape = XC_arrow;
+ impl->cursorName = cursor_names[PUGL_CURSOR_ARROW];
#endif
return impl;
@@ -246,20 +257,36 @@ updateSizeHints(const PuglView* const view)
#ifdef HAVE_XCURSOR
static PuglStatus
-defineCursorShape(PuglView* const view, const unsigned shape)
+defineCursorName(PuglView* const view, const char* const name)
{
PuglInternals* const impl = view->impl;
PuglWorld* const world = view->world;
Display* const display = world->impl->display;
- const Cursor cur = XcursorShapeLoadCursor(display, shape);
- if (cur) {
- XDefineCursor(display, impl->win, cur);
- XFreeCursor(display, cur);
- return PUGL_SUCCESS;
+ // Load cursor theme
+ char* const theme = XcursorGetTheme(display);
+ if (!theme) {
+ return PUGL_FAILURE;
}
- return PUGL_FAILURE;
+ // Get the default size and cursor image from it
+ const int size = XcursorGetDefaultSize(display);
+ XcursorImage* const image = XcursorLibraryLoadImage(name, theme, size);
+ if (!image) {
+ return PUGL_BAD_PARAMETER;
+ }
+
+ // Load a cursor from the image
+ const Cursor cur = XcursorImageLoadCursor(display, image);
+ XcursorImageDestroy(image);
+ if (!cur) {
+ return PUGL_UNKNOWN_ERROR;
+ }
+
+ // Set the view's cursor to the new loaded one
+ XDefineCursor(display, impl->win, cur);
+ XFreeCursor(display, cur);
+ return PUGL_SUCCESS;
}
#endif
@@ -1436,37 +1463,25 @@ puglSetClipboard(PuglView* const view,
return st;
}
-#ifdef HAVE_XCURSOR
-static const unsigned cursor_nums[] = {
- XC_arrow, // ARROW
- XC_xterm, // CARET
- XC_crosshair, // CROSSHAIR
- XC_hand2, // HAND
- XC_pirate, // NO
- XC_sb_h_double_arrow, // LEFT_RIGHT
- XC_sb_v_double_arrow, // UP_DOWN
-};
-#endif
-
PuglStatus
puglSetCursor(PuglView* const view, const PuglCursor cursor)
{
#ifdef HAVE_XCURSOR
PuglInternals* const impl = view->impl;
const unsigned index = (unsigned)cursor;
- const unsigned count = sizeof(cursor_nums) / sizeof(cursor_nums[0]);
+ const unsigned count = sizeof(cursor_names) / sizeof(cursor_names[0]);
if (index >= count) {
return PUGL_BAD_PARAMETER;
}
- const unsigned shape = cursor_nums[index];
- if (!impl->win || impl->cursorShape == shape) {
+ const char* const name = cursor_names[index];
+ if (!impl->win || impl->cursorName == name) {
return PUGL_SUCCESS;
}
- impl->cursorShape = cursor_nums[index];
+ impl->cursorName = cursor_names[index];
- return defineCursorShape(view, impl->cursorShape);
+ return defineCursorName(view, impl->cursorName);
#else
(void)view;
(void)cursor;