GHOST/wayland: get cursor settings via D-Bus
This commit is contained in:
@@ -575,6 +575,7 @@ if(WITH_GHOST_WAYLAND)
|
||||
pkg_check_modules(wayland-scanner REQUIRED wayland-scanner)
|
||||
pkg_check_modules(xkbcommon REQUIRED xkbcommon)
|
||||
pkg_check_modules(wayland-cursor REQUIRED wayland-cursor)
|
||||
pkg_check_modules(dbus REQUIRED dbus-1)
|
||||
|
||||
set(WITH_GL_EGL ON)
|
||||
|
||||
@@ -583,6 +584,7 @@ if(WITH_GHOST_WAYLAND)
|
||||
${wayland-egl_LINK_LIBRARIES}
|
||||
${xkbcommon_LINK_LIBRARIES}
|
||||
${wayland-cursor_LINK_LIBRARIES}
|
||||
${dbus_LINK_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@@ -282,6 +282,7 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
|
||||
${wayland-egl_INCLUDE_DIRS}
|
||||
${xkbcommon_INCLUDE_DIRS}
|
||||
${wayland-cursor_INCLUDE_DIRS}
|
||||
${dbus_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
list(APPEND SRC
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "GHOST_WaylandCursorSettings.h"
|
||||
#include <pointer-constraints-client-protocol.h>
|
||||
#include <relative-pointer-client-protocol.h>
|
||||
#include <wayland-cursor.h>
|
||||
@@ -1336,11 +1337,14 @@ GHOST_SystemWayland::GHOST_SystemWayland() : GHOST_System(), d(new display_t)
|
||||
}
|
||||
}
|
||||
|
||||
const char *theme = std::getenv("XCURSOR_THEME");
|
||||
const char *size = std::getenv("XCURSOR_SIZE");
|
||||
const int sizei = size ? std::stoi(size) : default_cursor_size;
|
||||
std::string theme;
|
||||
int size;
|
||||
if (!get_cursor_settings(theme, size)) {
|
||||
theme = std::string();
|
||||
size = default_cursor_size;
|
||||
}
|
||||
|
||||
d->cursor_theme = wl_cursor_theme_load(theme, sizei, d->shm);
|
||||
d->cursor_theme = wl_cursor_theme_load(theme.c_str(), size, d->shm);
|
||||
if (!d->cursor_theme) {
|
||||
display_destroy(d);
|
||||
throw std::runtime_error("Wayland: unable to access cursor themes!");
|
||||
|
130
intern/ghost/intern/GHOST_WaylandCursorSettings.h
Normal file
130
intern/ghost/intern/GHOST_WaylandCursorSettings.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <dbus/dbus.h>
|
||||
#include <string>
|
||||
|
||||
static DBusMessage *get_setting_sync(DBusConnection *const connection,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
DBusError error;
|
||||
dbus_bool_t success;
|
||||
DBusMessage *message;
|
||||
DBusMessage *reply;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
message = dbus_message_new_method_call("org.freedesktop.portal.Desktop",
|
||||
"/org/freedesktop/portal/desktop",
|
||||
"org.freedesktop.portal.Settings",
|
||||
"Read");
|
||||
|
||||
success = dbus_message_append_args(
|
||||
message, DBUS_TYPE_STRING, &key, DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID);
|
||||
|
||||
if (!success) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(
|
||||
connection, message, DBUS_TIMEOUT_USE_DEFAULT, &error);
|
||||
|
||||
dbus_message_unref(message);
|
||||
|
||||
if (dbus_error_is_set(&error)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static bool parse_type(DBusMessage *const reply, const int type, void *value)
|
||||
{
|
||||
DBusMessageIter iter[3];
|
||||
|
||||
dbus_message_iter_init(reply, &iter[0]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_iter_recurse(&iter[0], &iter[1]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_iter_recurse(&iter[1], &iter[2]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[2]) != type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_iter_get_basic(&iter[2], value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool get_cursor_settings(std::string &theme, int &size)
|
||||
{
|
||||
static const char name[] = "org.gnome.desktop.interface";
|
||||
static const char key_theme[] = "cursor-theme";
|
||||
static const char key_size[] = "cursor-size";
|
||||
|
||||
DBusError error;
|
||||
DBusConnection *connection;
|
||||
DBusMessage *reply;
|
||||
const char *value_theme = NULL;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
||||
|
||||
if (dbus_error_is_set(&error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
reply = get_setting_sync(connection, name, key_theme);
|
||||
if (!reply) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_type(reply, DBUS_TYPE_STRING, &value_theme)) {
|
||||
dbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
theme = std::string(value_theme);
|
||||
|
||||
dbus_message_unref(reply);
|
||||
|
||||
reply = get_setting_sync(connection, name, key_size);
|
||||
if (!reply) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_type(reply, DBUS_TYPE_INT32, &size)) {
|
||||
dbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_unref(reply);
|
||||
|
||||
return true;
|
||||
}
|
Reference in New Issue
Block a user