impl fixes

This commit is contained in:
vaxerski 2023-03-26 16:16:56 +01:00
parent d16feeefbd
commit 828b16bffb
2 changed files with 42 additions and 13 deletions

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <stdbool.h>
#include "protocols/hyprland-global-shortcuts-v1-client-protocol.h" #include "protocols/hyprland-global-shortcuts-v1-client-protocol.h"
struct xdpw_state; struct xdpw_state;
@ -10,6 +12,7 @@ struct globalShortcut {
char* description; char* description;
struct wl_list link; struct wl_list link;
struct hyprland_global_shortcut_v1* hlShortcut; struct hyprland_global_shortcut_v1* hlShortcut;
bool bound;
}; };
struct globalShortcutsClient { struct globalShortcutsClient {

View file

@ -7,7 +7,7 @@
static void wlr_registry_handle_add(void *data, struct wl_registry *reg, uint32_t id, const char *interface, uint32_t ver) { static void wlr_registry_handle_add(void *data, struct wl_registry *reg, uint32_t id, const char *interface, uint32_t ver) {
struct globalShortcutsInstance *instance = data; struct globalShortcutsInstance *instance = data;
if (!strcmp(interface, hyprland_global_shortcuts_manager_v1_interface.name) && !instance->manager) { if (!strcmp(interface, hyprland_global_shortcuts_manager_v1_interface.name) && instance->manager == NULL) {
uint32_t version = ver; uint32_t version = ver;
logprint(DEBUG, "hyprland: |-- registered to interface %s (Version %u)", interface, version); logprint(DEBUG, "hyprland: |-- registered to interface %s (Version %u)", interface, version);
@ -28,6 +28,10 @@ static const struct wl_registry_listener wlr_registry_listener = {
static const char object_path[] = "/org/freedesktop/portal/desktop"; static const char object_path[] = "/org/freedesktop/portal/desktop";
static const char interface_name[] = "org.freedesktop.impl.portal.GlobalShortcuts"; static const char interface_name[] = "org.freedesktop.impl.portal.GlobalShortcuts";
static int method_gs_create_session(sd_bus_message *msg, void *data, sd_bus_error *ret_error);
static int method_gs_bind_shortcuts(sd_bus_message *msg, void *data, sd_bus_error *ret_error);
static int method_gs_list_shortcuts(sd_bus_message *msg, void *data, sd_bus_error *ret_error);
static const sd_bus_vtable gs_vtable[] = { static const sd_bus_vtable gs_vtable[] = {
SD_BUS_VTABLE_START(0), SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("CreateSession", "oosa{sv}", "ua{sv}", method_gs_create_session, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("CreateSession", "oosa{sv}", "ua{sv}", method_gs_create_session, SD_BUS_VTABLE_UNPRIVILEGED),
@ -42,17 +46,22 @@ static void handleActivated(void *data, struct hyprland_global_shortcut_v1 *hypr
uint32_t tv_nsec) { uint32_t tv_nsec) {
struct xdpw_state *state = data; struct xdpw_state *state = data;
bool found = false;
struct globalShortcut *curr; struct globalShortcut *curr;
struct globalShortcutClient *currc; struct globalShortcutsClient *currc;
wl_list_for_each(currc, &state->shortcutsInstance.shortcutClients, link) { wl_list_for_each(currc, &state->shortcutsInstance.shortcutClients, link) {
wl_list_for_each(curr, &currc->shortcuts, link) { wl_list_for_each(curr, &currc->shortcuts, link) {
if (curr->hlShortcut == hyprland_global_shortcut_v1) { if (curr->hlShortcut == hyprland_global_shortcut_v1) {
found = true;
goto found; goto found;
} }
} }
} }
found: found:
if (!found) return;
sd_bus_emit_signal(state->bus, object_path, interface_name, "Activated", "osta{sv}", currc->session->session_handle, curr->name, sd_bus_emit_signal(state->bus, object_path, interface_name, "Activated", "osta{sv}", currc->session->session_handle, curr->name,
((uint64_t)tv_sec_hi << 32) | (uint64_t)(tv_sec_lo), 0); ((uint64_t)tv_sec_hi << 32) | (uint64_t)(tv_sec_lo), 0);
} }
@ -61,17 +70,22 @@ static void handleDeactivated(void *data, struct hyprland_global_shortcut_v1 *hy
uint32_t tv_nsec) { uint32_t tv_nsec) {
struct xdpw_state *state = data; struct xdpw_state *state = data;
bool found = false;
struct globalShortcut *curr; struct globalShortcut *curr;
struct globalShortcutClient *currc; struct globalShortcutsClient *currc;
wl_list_for_each(currc, &state->shortcutsInstance.shortcutClients, link) { wl_list_for_each(currc, &state->shortcutsInstance.shortcutClients, link) {
wl_list_for_each(curr, &currc->shortcuts, link) { wl_list_for_each(curr, &currc->shortcuts, link) {
if (curr->hlShortcut == hyprland_global_shortcut_v1) { if (curr->hlShortcut == hyprland_global_shortcut_v1) {
found = true;
goto found; goto found;
} }
} }
} }
found: found:
if (!found) return;
sd_bus_emit_signal(state->bus, object_path, interface_name, "Deactivated", "osta{sv}", currc->session->session_handle, curr->name, sd_bus_emit_signal(state->bus, object_path, interface_name, "Deactivated", "osta{sv}", currc->session->session_handle, curr->name,
((uint64_t)tv_sec_hi << 32) | (uint64_t)(tv_sec_lo), 0); ((uint64_t)tv_sec_hi << 32) | (uint64_t)(tv_sec_lo), 0);
} }
@ -107,6 +121,7 @@ static int method_gs_create_session(sd_bus_message *msg, void *data, sd_bus_erro
logprint(INFO, "dbus: app_id: %s", app_id); logprint(INFO, "dbus: app_id: %s", app_id);
char *key; char *key;
char *option_token;
int innerRet = 0; int innerRet = 0;
while ((ret = sd_bus_message_enter_container(msg, 'e', "sv")) > 0) { while ((ret = sd_bus_message_enter_container(msg, 'e', "sv")) > 0) {
innerRet = sd_bus_message_read(msg, "s", &key); innerRet = sd_bus_message_read(msg, "s", &key);
@ -115,9 +130,8 @@ static int method_gs_create_session(sd_bus_message *msg, void *data, sd_bus_erro
} }
if (strcmp(key, "session_handle_token") == 0) { if (strcmp(key, "session_handle_token") == 0) {
char *token; sd_bus_message_read(msg, "v", "s", &option_token);
sd_bus_message_read(msg, "v", "s", &token); logprint(INFO, "dbus: option token: %s", option_token);
logprint(INFO, "dbus: option token: %s", token);
} else if (strcmp(key, "shortcuts") == 0) { } else if (strcmp(key, "shortcuts") == 0) {
// init shortcuts // init shortcuts
client->sentShortcuts = true; client->sentShortcuts = true;
@ -198,6 +212,8 @@ static int method_gs_create_session(sd_bus_message *msg, void *data, sd_bus_erro
return -ENOMEM; return -ENOMEM;
} }
client->session = sess;
sess->app_id = malloc(strlen(app_id) + 1); sess->app_id = malloc(strlen(app_id) + 1);
strcpy(sess->app_id, app_id); strcpy(sess->app_id, app_id);
@ -221,6 +237,10 @@ static int method_gs_create_session(sd_bus_message *msg, void *data, sd_bus_erro
struct globalShortcut *curr; struct globalShortcut *curr;
wl_list_for_each(curr, &client->shortcuts, link) { wl_list_for_each(curr, &client->shortcuts, link) {
sd_bus_message_append(reply, "(sa{sv})", curr->name, 1, "description", "s", curr->description); sd_bus_message_append(reply, "(sa{sv})", curr->name, 1, "description", "s", curr->description);
curr->hlShortcut = hyprland_global_shortcuts_manager_v1_register_shortcut(
state->shortcutsInstance.manager, curr->name, (strlen(app_id) == 0 ? option_token : app_id), curr->description, "");
hyprland_global_shortcut_v1_add_listener(curr->hlShortcut, &shortcutListener, state);
curr->bound = true;
} }
ret = sd_bus_message_close_container(reply); ret = sd_bus_message_close_container(reply);
@ -266,7 +286,7 @@ static int method_gs_bind_shortcuts(sd_bus_message *msg, void *data, sd_bus_erro
struct globalShortcutsClient *client, *tmp_client; struct globalShortcutsClient *client, *tmp_client;
wl_list_for_each_reverse_safe(client, tmp_client, &state->shortcutsInstance.shortcutClients, link) { wl_list_for_each_reverse_safe(client, tmp_client, &state->shortcutsInstance.shortcutClients, link) {
if (strcmp(client->session, session_handle) == 0) { if (strcmp(client->session, session_handle) == 0) {
logprint(DEBUG, "dbus: bind shortcuts: found matching client %s", client->session_handle); logprint(DEBUG, "dbus: bind shortcuts: found matching client %s", client->session);
break; break;
} }
} }
@ -351,10 +371,12 @@ static int method_gs_bind_shortcuts(sd_bus_message *msg, void *data, sd_bus_erro
struct globalShortcut *curr; struct globalShortcut *curr;
wl_list_for_each(curr, &client->shortcuts, link) { wl_list_for_each(curr, &client->shortcuts, link) {
sd_bus_message_append(reply, "(sa{sv})", curr->name, 1, "description", "s", curr->description); sd_bus_message_append(reply, "(sa{sv})", curr->name, 1, "description", "s", curr->description);
curr->hlShortcut = hyprland_global_shortcuts_manager_v1_register_shortcut(state->shortcutsInstance.manager, curr->name, client->parent_window, if (!curr->bound) {
curr->hlShortcut = hyprland_global_shortcuts_manager_v1_register_shortcut(state->shortcutsInstance.manager, curr->name, parent_window,
curr->description, ""); curr->description, "");
hyprland_global_shortcut_v1_add_listener(curr->hlShortcut, &shortcutListener, state); hyprland_global_shortcut_v1_add_listener(curr->hlShortcut, &shortcutListener, state);
} }
}
ret = sd_bus_message_close_container(reply); ret = sd_bus_message_close_container(reply);
ret = sd_bus_message_close_container(reply); ret = sd_bus_message_close_container(reply);
@ -387,14 +409,18 @@ static int method_gs_list_shortcuts(sd_bus_message *msg, void *data, sd_bus_erro
logprint(INFO, "dbus: request_handle: %s", request_handle); logprint(INFO, "dbus: request_handle: %s", request_handle);
logprint(INFO, "dbus: session_handle: %s", session_handle); logprint(INFO, "dbus: session_handle: %s", session_handle);
bool foundClient = false;
struct globalShortcutsClient *client, *tmp_client; struct globalShortcutsClient *client, *tmp_client;
wl_list_for_each_reverse_safe(client, tmp_client, &state->shortcutsInstance.shortcutClients, link) { wl_list_for_each(client, &state->shortcutsInstance.shortcutClients, link) {
if (strcmp(client->session, session_handle) == 0) { if (strcmp(client->session, session_handle) == 0) {
logprint(DEBUG, "dbus: bind shortcuts: found matching client %s", client->session_handle); logprint(DEBUG, "dbus: bind shortcuts: found matching client %s", client->session);
foundClient = true;
break; break;
} }
} }
if (!foundClient || !client->sentShortcuts) return 0;
sd_bus_message *reply = NULL; sd_bus_message *reply = NULL;
ret = sd_bus_message_new_method_return(msg, &reply); ret = sd_bus_message_new_method_return(msg, &reply);
if (ret < 0) { if (ret < 0) {
@ -441,7 +467,7 @@ void initShortcutsInstance(struct xdpw_state *state, struct globalShortcutsInsta
wl_display_roundtrip(state->wl_display); wl_display_roundtrip(state->wl_display);
if (!instance->manager) { if (instance->manager == NULL) {
logprint(ERROR, "hyprland shortcut protocol unavailable!"); logprint(ERROR, "hyprland shortcut protocol unavailable!");
return; return;
} }