refactor code + add IDLE protocol listener

This commit is contained in:
DanyLE
2025-07-07 20:54:28 +02:00
parent a0456516b5
commit 6828400a77
11 changed files with 253 additions and 32 deletions

View File

@ -77,6 +77,7 @@ dm_src = [
'src/foreign.c',
'src/session-lock.c',
'src/session.c',
'src/idle.c',
'src/widgets/base-widgets.c',
'src/widgets/taskbar-widget.c',
'src/widgets/dashboard-widget.c',

View File

@ -154,8 +154,6 @@ static void diya_foreign_window_class_init(DiyaForeignWindowClass *class)
g_object_class_install_properties (gobject_class, N_PROPERTIES, win_properties);
}
static struct zwlr_foreign_toplevel_manager_v1 *g_toplevel_manager;
static void toplevel_handle_output_leave(void *data,
struct zwlr_foreign_toplevel_handle_v1 *handle,
struct wl_output *output)
@ -319,11 +317,10 @@ static const struct zwlr_foreign_toplevel_manager_v1_listener g_toplevel_manager
.finished = toplevel_manager_handle_finished,
};
void diya_session_shell_foreign_toplevel_register(struct wl_registry *registry, uint32_t name, DiyaShell *shell)
void diya_session_shell_foreign_toplevel_register(gpointer mngr, DiyaShell *shell)
{
DiyaSessionShell* session_shell = DIYA_SESSION_SHELL(shell);
g_toplevel_manager = wl_registry_bind(registry, name, &zwlr_foreign_toplevel_manager_v1_interface, 3);
zwlr_foreign_toplevel_manager_v1_add_listener(g_toplevel_manager, &g_toplevel_manager_impl, (void *)session_shell);
zwlr_foreign_toplevel_manager_v1_add_listener(mngr, &g_toplevel_manager_impl, (void *)session_shell);
}

View File

@ -24,7 +24,7 @@ enum diya_win_state
USE_CLASS(DiyaShell);
USE_CLASS(GAppInfo);
void diya_session_shell_foreign_toplevel_register(struct wl_registry *registry, uint32_t name, DiyaShell * shell);
void diya_session_shell_foreign_toplevel_register(gpointer mngr, DiyaShell * shell);
DiyaShell* diya_foreign_window_get_shell(DiyaForeignWindow* window);

129
src/idle.c Normal file
View File

@ -0,0 +1,129 @@
#include "idle.h"
#include "wayland.h"
#include "ext-idle-notify-v1.h"
#include "shell.h"
struct _DiyaIdleNotification
{
DiyaShellObject parent;
struct ext_idle_notification_v1* notification;
guint timeout;
};
G_DEFINE_FINAL_TYPE(DiyaIdleNotification, diya_idle_notification, DIYA_TYPE_SHELL_OBJECT)
static void diya_idle_notification_finalize(GObject* object)
{
(void) object;
DiyaIdleNotification * self = DIYA_IDLE_NOTIFICATION(object);
if(self->notification)
{
ext_idle_notification_v1_destroy(self->notification);
self->notification = NULL;
}
g_debug("diya_idle_notification_finalize: %s", diya_object_to_string(object));
G_OBJECT_CLASS(diya_idle_notification_parent_class)->finalize(object);
}
static void diya_idle_notification_dispose(GObject* object)
{
(void) object;
// DiyaIdleNotification * self = DIYA_IDLE_NOTIFICATION(object);
g_debug("diya_idle_notification_dispose: %s", diya_object_to_string(object));
G_OBJECT_CLASS(diya_idle_notification_parent_class)->dispose(object);
}
static void diya_idle_notification_init(DiyaIdleNotification * self)
{
self->notification = NULL;
}
static const gchar* diya_idle_notification_to_string(DiyaObject* object)
{
(void) object;
return "DiyaIdleNotification - wayland client handle object";
}
static void diya_idle_notification_class_init(DiyaIdleNotificationClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
gobject_class->dispose = diya_idle_notification_dispose;
gobject_class->finalize = diya_idle_notification_finalize;
base_class->to_string = diya_idle_notification_to_string;
g_signal_new(DIYA_SIGNAL_IDLE_NOTIF_IDLE,
DIYA_TYPE_IDLE_NOTIFICATION,
G_SIGNAL_DETAILED |
G_SIGNAL_ACTION |
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
g_signal_new(DIYA_SIGNAL_IDLE_NOTIF_RESUME,
DIYA_TYPE_IDLE_NOTIFICATION,
G_SIGNAL_DETAILED |
G_SIGNAL_ACTION |
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
}
void diya_idle(void *data, struct ext_idle_notification_v1 *notification)
{
(void) notification;
DiyaIdleNotification* self = data;
g_signal_emit_by_name(self, DIYA_SIGNAL_IDLE_NOTIF_IDLE);
}
void diya_resume(void *data, struct ext_idle_notification_v1 *notification)
{
(void) notification;
DiyaIdleNotification* self = data;
g_signal_emit_by_name(self, DIYA_SIGNAL_IDLE_NOTIF_RESUME);
}
static const struct ext_idle_notification_v1_listener g_idle_listener_impl =
{
.idled = diya_idle,
.resumed = diya_resume
};
void diya_idle_manager_register(gpointer mngr, DiyaShell *shell)
{
(void) mngr;
(void) shell;
}
DiyaIdleNotification* diya_shell_get_idle_notification(DiyaShell* shell, guint timeout_ms)
{
DiyaWayland *wayland = diya_shell_get_wayland(shell);
struct ext_idle_notifier_v1* mngr = diya_wayland_get_idle_mngr(wayland);
if(!mngr)
{
return NULL;
}
DiyaIdleNotification* self = g_object_new(DIYA_TYPE_IDLE_NOTIFICATION, "shell", shell, NULL);
struct wl_seat *seat = diya_wayland_get_seat(wayland);
self->timeout = timeout_ms;
self->notification = ext_idle_notifier_v1_get_idle_notification(mngr, timeout_ms, seat);
ext_idle_notification_v1_add_listener(self->notification, &g_idle_listener_impl, self);
return self;
}
guint diya_shell_notification_get_timeout(DiyaIdleNotification* self)
{
return self->timeout;
}

17
src/idle.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef DIYAC_IDLE_H
#define DIYAC_IDLE_H
#include "base.h"
#define DIYA_SIGNAL_IDLE_NOTIF_IDLE "idle"
#define DIYA_SIGNAL_IDLE_NOTIF_RESUME "resume"
#define DIYA_TYPE_IDLE_NOTIFICATION (diya_idle_notification_get_type ())
G_DECLARE_FINAL_TYPE (DiyaIdleNotification, diya_idle_notification, DIYA, IDLE_NOTIFICATION, DiyaShellObject)
USE_CLASS(DiyaShell);
void diya_idle_manager_register(gpointer mngr, DiyaShell *shell);
DiyaIdleNotification* diya_shell_get_idle_notification(DiyaShell* shell, guint timeout_ms);
guint diya_shell_notification_get_timeout(DiyaIdleNotification* self);
#endif /* DIYAC_IDLE_H */

View File

@ -9,7 +9,7 @@
#include "background.h"
#include "launcher.h"
#include "session-lock.h"
#include "idle.h"
enum
{
NO_PROP,
@ -29,6 +29,7 @@ struct _DiyaSessionShell
DiyaLauncher *launcher;
GHashTable *windows;
GtkSessionLockInstance *lock;
DiyaIdleNotification* idle_notif;
};
G_DEFINE_FINAL_TYPE(DiyaSessionShell, diya_session_shell, DIYA_TYPE_SHELL)
@ -57,6 +58,11 @@ static void diya_session_shell_dispose(GObject *object)
{
g_object_unref(self->launcher);
}
if (self->idle_notif)
{
g_object_unref(self->idle_notif);
self->idle_notif = NULL;
}
G_OBJECT_CLASS(diya_session_shell_parent_class)->dispose(object);
}
@ -136,11 +142,35 @@ static void diya_session_on_key_pressed(DiyaShell* shell, struct xkb_keymap *xkb
*/
}
static void diya_session_shell_idle(DiyaIdleNotification* notif, DiyaSessionShell* shell)
{
assert(DIYA_IS_IDLE_NOTIFICATION(notif));
assert(DIYA_IS_SESSION_SHELL(shell));
g_debug("Shell IDLE");
}
static void diya_session_shell_resume(DiyaIdleNotification* notif, DiyaSessionShell* shell)
{
assert(DIYA_IS_IDLE_NOTIFICATION(notif));
assert(DIYA_IS_SESSION_SHELL(shell));
g_critical("Shell RESUME");
}
static void diya_session_shell_startup(DiyaShell *shell)
{
diya_session_shell_init_background(DIYA_SESSION_SHELL(shell));
diya_session_shell_launcher_init(DIYA_SESSION_SHELL(shell));
DiyaSessionShell* self = DIYA_SESSION_SHELL(shell);
diya_session_shell_init_background(self);
diya_session_shell_launcher_init(self);
g_signal_connect(shell, DIYA_SIGNAL_SHELL_KEY_PRESSED, G_CALLBACK(diya_session_on_key_pressed), NULL);
/**
* TODO:
* - read timeout from setting
* - implement widget that handle idle (turn off display + lock)
*/
self->idle_notif = diya_shell_get_idle_notification(shell, 5000);
g_signal_connect(self->idle_notif, DIYA_SIGNAL_IDLE_NOTIF_IDLE, G_CALLBACK(diya_session_shell_idle), self);
g_signal_connect(self->idle_notif, DIYA_SIGNAL_IDLE_NOTIF_RESUME, G_CALLBACK(diya_session_shell_resume), self);
}
static void diya_session_shell_active(DiyaShell *shell)
@ -155,6 +185,7 @@ static void diya_session_shell_class_init(DiyaSessionShellClass *class)
DiyaShellClass *base_shell_class = DIYA_SHELL_CLASS(class);
base_shell_class->foreign_register = diya_session_shell_foreign_toplevel_register;
base_shell_class->idle_notifier_register = diya_idle_manager_register;
base_shell_class->startup_handle = diya_session_shell_startup;
base_shell_class->active_handle = diya_session_shell_active;
@ -266,6 +297,7 @@ static void diya_session_shell_init(DiyaSessionShell *self)
self->background = NULL;
self->launcher = NULL;
self->lock = gtk_session_lock_instance_new();
self->idle_notif = NULL;
g_signal_connect(self->lock, "locked", G_CALLBACK(on_session_locked), self);
// g_signal_connect(lock, "failed", G_CALLBACK(failed), NULL);
g_signal_connect(self->lock, "unlocked", G_CALLBACK(on_session_unlocked), self);

View File

@ -24,7 +24,7 @@ G_DECLARE_DERIVABLE_TYPE(DiyaShell, diya_shell, DIYA, SHELL, DiyaObject)
struct wl_registry;
typedef void (*wl_protocol_manager_register_t)(struct wl_registry*, uint32_t,DiyaShell*);
typedef void (*wl_protocol_manager_register_t)(gpointer,DiyaShell*);
struct _DiyaShellClass
{

View File

@ -136,7 +136,6 @@ gboolean diya_vkb_key_is_modifier(DiyaVkbKey* self)
*
*/
static struct zwp_virtual_keyboard_manager_v1 *g_virtual_keyboard_manager = NULL;
struct _DiyaVirtualKeyboard
{
@ -385,16 +384,21 @@ DiyaVirtualKeyboard *diya_virtual_keyboard_new(DiyaShell *shell, const gchar *ke
vkb->vkb_keymap = vkb_keymap;
DiyaWayland *wayland = diya_shell_get_wayland(shell);
struct wl_seat *seat = diya_wayland_get_seat(wayland);
vkb->keyboard = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(g_virtual_keyboard_manager, seat);
struct zwp_virtual_keyboard_manager_v1* mngr = diya_wayland_get_virtual_keyboard_mngr(wayland);
if(!mngr)
{
return NULL;
}
vkb->keyboard = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(mngr, seat);
zwp_virtual_keyboard_v1_keymap(vkb->keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, fd, len);
return vkb;
}
void diya_virtual_keyboard_register(struct wl_registry *registry, uint32_t name, DiyaShell *shell)
void diya_virtual_keyboard_register(gpointer mngr, DiyaShell *shell)
{
(void)shell;
g_virtual_keyboard_manager = wl_registry_bind(registry, name, &zwp_virtual_keyboard_manager_v1_interface, 1);
(void) shell;
(void) mngr;
}
void diya_virtual_keyboard_send_key(DiyaVirtualKeyboard *self, DiyaVkbKey* key, diya_vkb_state_t state)
@ -439,7 +443,7 @@ void diya_virtual_keyboard_send_key(DiyaVirtualKeyboard *self, DiyaVkbKey* key,
}
if(old_mods != self->key_mods)
{
g_signal_emit_by_name(self,DIYA_SIGNAL_VKB_MODIFIER_CHANGED, NULL);
g_signal_emit_by_name(self,DIYA_SIGNAL_VKB_MODIFIER_CHANGED);
}
}

View File

@ -26,7 +26,7 @@ gboolean diya_vkb_key_is_modifier(DiyaVkbKey* key);
DiyaVirtualKeyboard* diya_virtual_keyboard_new(DiyaShell* shell, const gchar* keymap_file);
void diya_virtual_keyboard_register(struct wl_registry *registry, uint32_t name, DiyaShell *shell);
void diya_virtual_keyboard_register(gpointer mngr, DiyaShell *shell);
void diya_virtual_keyboard_send_key(DiyaVirtualKeyboard* vkb, DiyaVkbKey* key, diya_vkb_state_t state);
DiyaVkbKey* diya_virtual_keyboard_get_key(DiyaVirtualKeyboard* vkb, uint32_t key);

View File

@ -13,13 +13,40 @@ struct _DiyaWayland
struct wl_compositor * compositor;
struct wl_shm * shm;
struct wl_seat * seat;
// protocol manager
struct zwlr_foreign_toplevel_manager_v1 * foreign_toplevel_mngr;
struct zwp_virtual_keyboard_manager_v1 * virtual_keyboard_mngr;
struct ext_idle_notifier_v1 * idle_notifier_mngr;
};
G_DEFINE_FINAL_TYPE(DiyaWayland, diya_wayland, DIYA_TYPE_SHELL_OBJECT)
static void diya_wayland_finalize(GObject* object)
{
(void) object;
DiyaWayland * self = DIYA_WAYLAND(object);
if(self->foreign_toplevel_mngr)
{
zwlr_foreign_toplevel_manager_v1_destroy(self->foreign_toplevel_mngr);
self->foreign_toplevel_mngr = NULL;
}
if(self->virtual_keyboard_mngr)
{
zwp_virtual_keyboard_manager_v1_destroy(self->virtual_keyboard_mngr);
self->virtual_keyboard_mngr = NULL;
}
if(self->idle_notifier_mngr)
{
ext_idle_notifier_v1_destroy(self->idle_notifier_mngr);
self->idle_notifier_mngr = NULL;
}
g_debug("diya_wayland_finalize: %s", diya_object_to_string(object));
G_OBJECT_CLASS(diya_wayland_parent_class)->finalize(object);
}
static void diya_wayland_dispose(GObject* object)
{
(void) object;
//DiyaWayland * self = DIYA_WAYLAND(object);
// DiyaWayland * self = DIYA_WAYLAND(object);
g_debug("diya_wayland_dispose: %s", diya_object_to_string(object));
G_OBJECT_CLASS(diya_wayland_parent_class)->dispose(object);
}
@ -29,6 +56,9 @@ static void diya_wayland_init(DiyaWayland * self)
self->compositor = NULL;
self->shm = NULL;
self->seat = NULL;
self->foreign_toplevel_mngr = NULL;
self->virtual_keyboard_mngr = NULL;
self->idle_notifier_mngr = NULL;
}
static const gchar* diya_wayland_to_string(DiyaObject* object)
@ -43,6 +73,7 @@ static void diya_wayland_class_init(DiyaWaylandClass *class)
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
gobject_class->dispose = diya_wayland_dispose;
gobject_class->finalize = diya_wayland_finalize;
//gobject_class->set_property = diya_lock_session_set_property;
//gobject_class->get_property = diya_lock_session_get_property;
base_class->to_string = diya_wayland_to_string;
@ -74,7 +105,8 @@ static void handle_global(void *data, struct wl_registry *registry, uint32_t nam
{
//diya_session_shell_foreign_toplevel_register(registry, name, data);
g_debug("Wayland: register shell foreign top level manager");
class->foreign_register(registry, name, data);
wayland->foreign_toplevel_mngr = wl_registry_bind(registry, name, &zwlr_foreign_toplevel_manager_v1_interface, 3);
class->foreign_register(wayland->foreign_toplevel_mngr, shell);
}
}
if (g_strcmp0(interface, zwp_virtual_keyboard_manager_v1_interface.name) == 0)
@ -83,7 +115,8 @@ static void handle_global(void *data, struct wl_registry *registry, uint32_t nam
{
//diya_session_shell_foreign_toplevel_register(registry, name, data);
g_debug("Wayland: register virtual keyboard manager");
class->virtual_keyboard_register(registry, name, data);
wayland->virtual_keyboard_mngr = wl_registry_bind(registry, name, &zwp_virtual_keyboard_manager_v1_interface, 1);
class->virtual_keyboard_register(wayland->virtual_keyboard_mngr, shell);
}
}
/*
@ -92,29 +125,30 @@ static void handle_global(void *data, struct wl_registry *registry, uint32_t nam
diya_session_shell_session_lock_register(registry, name);
}
*/
else if (strcmp(interface, wl_compositor_interface.name) == 0)
else if (g_strcmp0(interface, wl_compositor_interface.name) == 0)
{
wayland->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 4);
}
else if (strcmp(interface, wl_shm_interface.name) == 0)
else if (g_strcmp0(interface, wl_shm_interface.name) == 0)
{
wayland->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1);
}
else if (strcmp(interface, wl_seat_interface.name) == 0)
else if (g_strcmp0(interface, wl_seat_interface.name) == 0)
{
wayland->seat = wl_registry_bind(registry, name, &wl_seat_interface, 7);
}
else if(strcmp(interface, ext_idle_notifier_v1_interface.name) == 0)
else if(g_strcmp0(interface, ext_idle_notifier_v1_interface.name) == 0)
{
if(class->idle_notifier_register)
{
class->idle_notifier_register(registry, name, data);
g_debug("Wayland: register ext_idle_notifier_v1_interface");
wayland->idle_notifier_mngr = wl_registry_bind(registry, name, &ext_idle_notifier_v1_interface, 1);;
class->idle_notifier_register(wayland->idle_notifier_mngr, shell);
}
}
}
static void handle_global_remove(void *data, struct wl_registry *registry,
uint32_t name)
static void handle_global_remove(void *data, struct wl_registry *registry,uint32_t name)
{
(void) data;
(void) registry;
@ -185,4 +219,14 @@ struct wl_seat* diya_wayland_get_seat(DiyaWayland* self)
{
assert(self->seat);
return self->seat;
}
struct zwp_virtual_keyboard_manager_v1* diya_wayland_get_virtual_keyboard_mngr(DiyaWayland* self)
{
return self->virtual_keyboard_mngr;
}
struct ext_idle_notifier_v1* diya_wayland_get_idle_mngr(DiyaWayland* self)
{
return self->idle_notifier_mngr;
}

View File

@ -5,17 +5,14 @@
USE_CLASS(DiyaShell);
//#define DIYA_TYPE_WAYLAND_PROTOCOL_MANAGER (diya_wayland_protocol_manager_get_type())
//G_DECLARE_DERIVABLE_TYPE(DiyaWaylandProtocolManager, diya_wayland_protocol_manager, DIYA, WAYLAND_PROTOCOL_MANAGER, DiyaObject)
#define DIYA_TYPE_WAYLAND (diya_wayland_get_type ())
G_DECLARE_FINAL_TYPE (DiyaWayland, diya_wayland, DIYA, WAYLAND, DiyaShellObject)
struct wl_surface* diya_wayland_create_surface(DiyaWayland * self);
struct wl_output* diya_wayland_get_output(DiyaWayland * self, int index);
struct wl_shm_pool * diya_wayland_create_shm_pool(DiyaWayland * self, int fd, guint size);
struct wl_seat* diya_wayland_get_seat(DiyaWayland* self);
struct zwp_virtual_keyboard_manager_v1* diya_wayland_get_virtual_keyboard_mngr(DiyaWayland* self);
struct ext_idle_notifier_v1* diya_wayland_get_idle_mngr(DiyaWayland* self);
DiyaWayland* diya_wayland_new(DiyaShell *shell);
#endif