refactor: move shell lock feature to base Shell class

This commit is contained in:
Dany LE
2025-11-03 22:02:31 +01:00
parent 6c66e0f758
commit 37fec9f359
11 changed files with 215 additions and 225 deletions

View File

@@ -33,7 +33,7 @@ lua = dependency('lua')
# pkg_config = import('pkgconfig')
# gnome = import('gnome')
gtk_layer_shell = dependency('gtk4-layer-shell-0', version: '>=1.1.0')
gtk_layer_shell = dependency('gtk4-layer-shell-0', version: '>=1.3.0')
wayland_targets=[]
wl_protocols = [

View File

@@ -1,20 +1,22 @@
@import url("resource:///dev/iohub/diya/shell/css/virtual-keyboard.css");
#diya_login_shell
.diya-login-shell
{
background-color: white;
opacity: 0.9;
}
#diya_login_shell label.diya-login-header {
.diya-login-shell label.diya-login-header {
font-size: 16px;
font-weight: bold;
}
#diya_login_shell label.diya-login-status {
.diya-login-shell label.diya-login-status {
font-size: 12px;
color: red;
}
#diya_login_shell button.diya-btn-show-vkb
.diya-login-shell button.diya-btn-show-vkb
{
color: gray;
min-width: 0px;

View File

@@ -8,19 +8,18 @@
#define DBUS_SERVER_NAME "dev.iohub.diya.SessionManager"
#define DBUS_SERVER_PATH "/dev/iohub/diya/SessionManager"
#define DBUS_SERVER_ERROR_NAME "dev.iohub.diya.SessionManager.Error"
#define NAMESPACE "diya_login_shell"
#define NAMESPACE "diya-login-shell"
struct _DiyaLoginShell
{
DiyaShell parent_object;
GtkSessionLockInstance *lock;
GtkWidget *username;
GtkWidget *password;
GtkWidget *status;
guint bus_watch_id;
GtkWidget *vkb_widget;
GtkWidget *revealer;
GList *windows;
};
G_DEFINE_FINAL_TYPE(DiyaLoginShell, diya_login_shell, DIYA_TYPE_SHELL);
@@ -29,10 +28,6 @@ static void diya_login_shell_finalize(GObject *object)
{
DiyaLoginShell *self = DIYA_LOGIN_SHELL(object);
g_debug("diya_login_shell_finalize: %s", diya_object_to_string(self));
if (self->windows)
{
g_list_free(self->windows);
}
G_OBJECT_CLASS(diya_login_shell_parent_class)->finalize(object);
}
@@ -40,27 +35,6 @@ static void diya_login_shell_dispose(GObject *object)
{
DiyaLoginShell *self = DIYA_LOGIN_SHELL(object);
g_debug("diya_login_shell_dispose: %s", diya_object_to_string(self));
if (self->lock)
{
if (gtk_session_lock_instance_is_locked(self->lock))
{
gtk_session_lock_instance_unlock(self->lock);
}
g_object_unref(self->lock);
}
if (self->windows)
{
// destroyed all windows and free list
GList *it = NULL;
for (it = self->windows; it; it = it->next)
{
if (it->data)
{
gtk_window_destroy(GTK_WINDOW(it->data));
}
}
// g_list_free(self->windows);
}
if (self->bus_watch_id > 0)
{
g_bus_unwatch_name(self->bus_watch_id);
@@ -71,11 +45,9 @@ static void diya_login_shell_dispose(GObject *object)
static void diya_login_shell_init(DiyaLoginShell *self)
{
g_debug("diya_login_shell_init");
self->lock = gtk_session_lock_instance_new();
self->username = NULL;
self->password = NULL;
self->status = NULL;
self->windows = NULL;
self->bus_watch_id = 0;
}
@@ -178,14 +150,44 @@ static void do_login(GtkButton *button, DiyaLoginShell *self)
// g_application_quit(G_APPLICATION(self->app));
}
static void add_new_monitor(DiyaLoginShell *self, GdkMonitor *monitor, gint position)
static void diya_login_on_shell_idle(DiyaShell* shell)
{
GtkWindow *window = GTK_WINDOW(gtk_application_window_new(diya_shell_get_application(DIYA_SHELL(self))));
gtk_session_lock_instance_assign_window_to_monitor(self->lock, window, monitor);
gtk_widget_set_name(GTK_WIDGET(window), NAMESPACE);
(void) shell;
g_debug("diya_login_on_shell_idle");
diya_shell_power_display(shell, false);
}
static void diya_login_on_shell_resume(DiyaShell* shell)
{
(void) shell;
g_debug("diya_login_on_shell_resume");
diya_shell_power_display(shell, true);
}
static void diya_login_shell_active(DiyaShell *shell)
{
g_object_set(shell, DIYA_PROP_SHELL_IDLE_TIMEOUT, DEFAULT_IDLE_TIMEOUT, NULL);
}
static void diya_login_shell_startup(DiyaShell *shell)
{
g_warning("diya_login_shell_startup");
g_signal_connect(shell, DIYA_SIGNAL_SHELL_IDLE, G_CALLBACK(diya_login_on_shell_idle), NULL);
g_signal_connect(shell, DIYA_SIGNAL_SHELL_RESUME, G_CALLBACK(diya_login_on_shell_resume), NULL);
diya_shell_lock(shell);
}
static GtkWindow* diya_login_shell_create_window(DiyaShell* shell)
{
DiyaLoginShell* self = DIYA_LOGIN_SHELL(shell);
GtkApplication * app;
g_object_get(shell, DIYA_PROP_SHELL_APPLICATION, &app, NULL);
assert(app);
GtkWindow *window = GTK_WINDOW(gtk_application_window_new(app));
gtk_widget_add_css_class(GTK_WIDGET(window), NAMESPACE);
GtkWidget *grid = gtk_grid_new();
gtk_window_set_child(window, grid);
gtk_grid_set_row_homogeneous(GTK_GRID(grid), false);
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
@@ -230,14 +232,14 @@ static void add_new_monitor(DiyaLoginShell *self, GdkMonitor *monitor, gint posi
gtk_widget_set_can_focus(GTK_WIDGET(button), false);
gtk_grid_attach(GTK_GRID(child_grid), button, 0, 0, 1, 1);
// Not displayed, but allows testing that creating popups doesn't crash GTK
gtk_widget_set_tooltip_text(button, "Login");
//gtk_widget_set_tooltip_text(button, "Login");
gtk_widget_set_hexpand(button, true);
button = gtk_toggle_button_new_with_label("");
gtk_widget_add_css_class(button, "diya-btn-show-vkb");
gtk_grid_attach(GTK_GRID(child_grid), button, 1, 0, 1, 1);
gtk_box_append(GTK_BOX(box), child_grid);
gtk_widget_set_tooltip_text(button, "Show virtual keyboard");
//gtk_widget_set_tooltip_text(button, "Show virtual keyboard");
gtk_widget_set_can_focus(GTK_WIDGET(button), false);
self->status = gtk_label_new(NULL);
@@ -265,73 +267,8 @@ static void add_new_monitor(DiyaLoginShell *self, GdkMonitor *monitor, gint posi
gtk_widget_set_hexpand(box, true);
gtk_widget_set_vexpand(box, false);
gtk_window_present(window);
self->windows = g_list_insert(self->windows, window, position);
}
static void on_monitor_changed(GListModel *monitor_lists, guint position, guint removed, guint added, gpointer object)
{
g_debug("Monitor list changed at %d: added %d, removed %d", position, added, removed);
DiyaLoginShell *self = DIYA_LOGIN_SHELL(object);
if (removed > 0)
{
for (guint i = 0; i < removed; i++)
{
GtkWindow *win = GTK_WINDOW(g_list_nth(self->windows, position));
if (win)
{
gtk_window_destroy(win);
self->windows = g_list_remove(self->windows, win);
}
}
}
if (added > 0)
{
for (guint i = 0; i < added; i++)
{
GdkMonitor *monitor = g_list_model_get_item(monitor_lists, position + i);
add_new_monitor(self, monitor, position + i);
}
}
}
static void diya_login_on_shell_idle(DiyaShell* shell)
{
(void) shell;
g_debug("diya_login_on_shell_idle");
diya_shell_power_display(shell, false);
}
static void diya_login_on_shell_resume(DiyaShell* shell)
{
(void) shell;
g_debug("diya_login_on_shell_resume");
diya_shell_power_display(shell, true);
}
static void diya_login_shell_active(DiyaShell *shell)
{
g_object_set(shell, DIYA_PROP_SHELL_IDLE_TIMEOUT, DEFAULT_IDLE_TIMEOUT, NULL);
}
static void diya_login_shell_startup(DiyaShell *shell)
{
DiyaLoginShell *self = DIYA_LOGIN_SHELL(shell);
if (!gtk_session_lock_instance_lock(self->lock))
{
g_object_unref(self);
g_error("gtk_session_lock_instance_lock: Unable to lock the display");
return;
}
GListModel *list = gdk_display_get_monitors(gdk_display_get_default());
for (guint i = 0; i < g_list_model_get_n_items(list); i++)
{
GdkMonitor *monitor = g_list_model_get_item(list, i);
add_new_monitor(self, monitor, -1);
}
g_signal_connect(shell, DIYA_SIGNAL_SHELL_IDLE, G_CALLBACK(diya_login_on_shell_idle), NULL);
g_signal_connect(shell, DIYA_SIGNAL_SHELL_RESUME, G_CALLBACK(diya_login_on_shell_resume), NULL);
gtk_window_set_child(window, grid);
return window;
}
static void diya_login_shell_class_init(DiyaLoginShellClass *class)
@@ -343,7 +280,7 @@ static void diya_login_shell_class_init(DiyaLoginShellClass *class)
// gobject_class->get_property = diya_lock_session_get_property;
DiyaShellClass *base_shell_class = DIYA_SHELL_CLASS(class);
base_shell_class->monitor_changed_handle = on_monitor_changed;
base_shell_class->build_lock_window = diya_login_shell_create_window;
base_shell_class->startup_handle = diya_login_shell_startup;
base_shell_class->active_handle = diya_login_shell_active;
// base_shell_class->foreign_register = diya_session_shell_foreign_toplevel_register;

View File

@@ -3,69 +3,38 @@
#include <gtk/gtk.h>
#include "session-lock.h"
static void unlock_session(GtkButton *button, DiyaSessionShell *shell)
static void unlock_session(GtkButton *button, DiyaShell *shell)
{
(void)button;
assert(shell);
diya_session_shell_unlock(shell);
diya_shell_unlock(shell);
}
void diya_session_shell_lock(DiyaSessionShell* shell)
GtkWindow* diya_session_lock_create(DiyaShell* shell)
{
assert(shell);
GtkSessionLockInstance * lock;
g_object_get(shell, DIYA_PROP_SESSION_LOCK, &lock, NULL);
assert(lock);
if(gtk_session_lock_instance_is_locked(lock))
{
g_warning("Shell session is already locked, doing nothing");
return;
}
if(!gtk_session_lock_instance_lock(lock))
{
g_error("gtk_session_lock_instance_lock:Unable to lock the current session");
return;
}
GtkApplication * app;
g_object_get(shell, DIYA_PROP_SHELL_APPLICATION, &app, NULL);
assert(app);
GdkDisplay *display = gdk_display_get_default();
GListModel *monitors = gdk_display_get_monitors(display);
guint n_monitors = g_list_model_get_n_items(monitors);
GtkWindow *gtk_window = GTK_WINDOW(gtk_application_window_new(app));
for (guint i = 0; i < n_monitors; ++i)
{
GdkMonitor *monitor = g_list_model_get_item(monitors, i);
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign(box, GTK_ALIGN_CENTER);
gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
gtk_box_set_spacing(GTK_BOX (box), 10);
GtkWindow *gtk_window = GTK_WINDOW(gtk_application_window_new(app));
gtk_session_lock_instance_assign_window_to_monitor(lock, gtk_window, monitor);
GtkWidget *label = gtk_label_new("GTK Session Lock example");
gtk_box_append(GTK_BOX(box), label);
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign(box, GTK_ALIGN_CENTER);
gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
gtk_box_set_spacing(GTK_BOX (box), 10);
GtkWidget *button = gtk_button_new_with_label("Unlock");
g_signal_connect(button, "clicked", G_CALLBACK(unlock_session), shell);
gtk_box_append(GTK_BOX(box), button);
GtkWidget *label = gtk_label_new("GTK Session Lock example");
gtk_box_append(GTK_BOX(box), label);
// Not displayed, but allows testing that creating popups doesn't crash GTK
gtk_widget_set_tooltip_text(button, "Foo Bar Baz");
GtkWidget *button = gtk_button_new_with_label("Unlock");
g_signal_connect(button, "clicked", G_CALLBACK(unlock_session), shell);
gtk_box_append(GTK_BOX(box), button);
gtk_window_set_child(GTK_WINDOW(gtk_window), box);
// Not displayed, but allows testing that creating popups doesn't crash GTK
gtk_widget_set_tooltip_text(button, "Foo Bar Baz");
gtk_window_set_child(GTK_WINDOW(gtk_window), box);
gtk_window_present(gtk_window);
}
}
void diya_session_shell_unlock(DiyaSessionShell* shell)
{
assert(shell);
GtkSessionLockInstance * lock;
g_object_get(shell, DIYA_PROP_SESSION_LOCK, &lock, NULL);
assert(lock);
gtk_session_lock_instance_unlock(lock);
g_debug("gtk_session_lock_instance_unlock: Shell unlocked");
return gtk_window;
}

View File

@@ -3,7 +3,6 @@
#include "session-shell.h"
void diya_session_shell_lock(DiyaSessionShell* shell);
void diya_session_shell_unlock(DiyaSessionShell* shell);
GtkWindow* diya_session_lock_create(DiyaShell* shell);
#endif

View File

@@ -1,7 +1,7 @@
#include "session-shell.h"
#include <assert.h>
#include <gtk4-session-lock.h>
#include <xkbcommon/xkbcommon.h>
#include "shell.h"
@@ -17,7 +17,6 @@ enum
{
NO_PROP,
SHELL_LAUNCHPAD_WIDGET,
SHELL_LOCK_SESSION,
SHELL_WINDOWS,
N_PROPERTIES
};
@@ -29,7 +28,6 @@ struct _DiyaSessionShell
DiyaShell parent;
DiyaLauncher *launcher;
GHashTable *windows;
GtkSessionLockInstance *lock;
GSettings *settings;
};
G_DEFINE_FINAL_TYPE(DiyaSessionShell, diya_session_shell, DIYA_TYPE_SHELL)
@@ -47,10 +45,6 @@ static void diya_session_shell_dispose(GObject *object)
DiyaSessionShell *self = DIYA_SESSION_SHELL(object);
// g_hash_table_destroy(self->windows);
g_debug("diya_session_shell_dispose: %s", diya_object_to_string(object));
if (self->lock)
{
g_object_unref(self->lock);
}
if (self->launcher)
{
g_object_unref(self->launcher);
@@ -88,10 +82,6 @@ static void diya_session_shell_get_property(GObject *object, guint property_id,
assert(self->launcher);
g_value_set_pointer(value, self->launcher);
break;
case SHELL_LOCK_SESSION:
assert(self->lock);
g_value_set_pointer(value, self->lock);
break;
case SHELL_WINDOWS:
g_value_set_pointer(value, self->windows);
break;
@@ -180,7 +170,7 @@ void diya_session_init_settings(DiyaSessionShell* self)
static void diya_session_shell_startup(DiyaShell *shell)
{
DiyaSessionShell* self = DIYA_SESSION_SHELL(shell);
const gchar* const* dirs = g_get_system_config_dirs();
gchar* path = NULL;
@@ -227,7 +217,7 @@ static void diya_session_shell_class_init(DiyaSessionShellClass *class)
base_shell_class->foreign_register = diya_session_shell_foreign_toplevel_register;
base_shell_class->startup_handle = diya_session_shell_startup;
base_shell_class->active_handle = diya_session_shell_active;
base_shell_class->build_lock_window = diya_session_lock_create;
/// base_class->to_string = diya_session_shell_to_string;
gobject_class->dispose = diya_session_shell_dispose;
gobject_class->finalize = diya_session_shell_finalize;
@@ -235,7 +225,6 @@ static void diya_session_shell_class_init(DiyaSessionShellClass *class)
gobject_class->get_property = diya_session_shell_get_property;
shell_properties[SHELL_LAUNCHPAD_WIDGET] = g_param_spec_pointer(DIYA_PROP_SESSION_LAUNCHPAD, NULL, "Shell launchpad", G_PARAM_READWRITE);
shell_properties[SHELL_LOCK_SESSION] = g_param_spec_pointer(DIYA_PROP_SESSION_LOCK, NULL, "Shell lock session", G_PARAM_READABLE);
shell_properties[SHELL_WINDOWS] = g_param_spec_pointer(DIYA_PROP_SESSION_WINDOWS, NULL, "Shell foreign windows", G_PARAM_READABLE);
g_object_class_install_properties(gobject_class, N_PROPERTIES, shell_properties);
@@ -289,44 +278,6 @@ static void diya_session_shell_class_init(DiyaSessionShellClass *class)
G_TYPE_NONE,
1,
G_TYPE_POINTER);
g_signal_new(DIYA_SIGNAL_SESSION_LOCKED,
DIYA_TYPE_SESSION_SHELL,
G_SIGNAL_DETAILED |
G_SIGNAL_ACTION |
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
g_signal_new(DIYA_SIGNAL_SESSION_UNLOCKED,
DIYA_TYPE_SESSION_SHELL,
G_SIGNAL_DETAILED |
G_SIGNAL_ACTION |
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
}
static void on_session_locked(GtkSessionLockInstance *lock, DiyaSessionShell *shell)
{
(void)lock;
assert(shell);
g_message("Session locked successfully");
g_signal_emit_by_name(shell, DIYA_SIGNAL_SESSION_LOCKED);
}
static void on_session_unlocked(GtkSessionLockInstance *lock, DiyaSessionShell *shell)
{
(void)lock;
assert(shell);
g_message("Session unlocked");
g_signal_emit_by_name(shell, DIYA_SIGNAL_SESSION_UNLOCKED);
}
static void diya_session_shell_init(DiyaSessionShell *self)
@@ -334,10 +285,6 @@ static void diya_session_shell_init(DiyaSessionShell *self)
// self->app = NULL;
self->launcher = NULL;
self->settings = NULL;
self->lock = gtk_session_lock_instance_new();
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);
self->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
}

View File

@@ -9,11 +9,8 @@
#define DIYA_SIGNAL_FOREIGN_WINDOW_STATE_CHANGED "foreign-window-state-changed"
#define DIYA_SIGNAL_FOREIGN_WINDOW_ADDED "foreign-window-added"
#define DIYA_SIGNAL_FOREIGN_WINDOW_REMOVED "foreign-window-removed"
#define DIYA_SIGNAL_SESSION_LOCKED "session-locked"
#define DIYA_SIGNAL_SESSION_UNLOCKED "session-unlocked"
#define DIYA_PROP_SESSION_LAUNCHPAD "launchpad"
#define DIYA_PROP_SESSION_LOCK "session-lock"
#define DIYA_PROP_SESSION_WINDOWS "windows"
#define SESSION_SHELL_SCHEMA_ID "dev.iohub.diya.session"

View File

@@ -19,7 +19,7 @@ static void session_unlocked(DiyaSessionShell* shell, void* data)
int main(int argc, char *argv[])
{
DiyaSessionShell *shell = DIYA_SESSION_SHELL(g_object_new(DIYA_TYPE_SESSION_SHELL, "name","dev.iohub.diya.session", NULL));
g_signal_connect(shell, DIYA_SIGNAL_SESSION_LOCKED, G_CALLBACK(session_locked), NULL);
g_signal_connect(shell, DIYA_SIGNAL_SESSION_UNLOCKED, G_CALLBACK(session_unlocked), NULL);
g_signal_connect(shell, DIYA_SIGNAL_SHELL_LOCKED, G_CALLBACK(session_locked), NULL);
g_signal_connect(shell, DIYA_SIGNAL_SHELL_UNLOCKED, G_CALLBACK(session_unlocked), NULL);
return diya_shell_run(DIYA_SHELL(shell), argc, argv);
}

View File

@@ -8,6 +8,7 @@
#include "hook.h"
#include <wayland-client-protocol.h>
#include <gdk/wayland/gdkwayland.h>
#include <gtk4-session-lock.h>
#define diya_shell_config_theme(priv) (g_strconcat(g_get_home_dir(), "/.themes/", priv->theme ? priv->theme : "default", "/gtk-4.0/gtk.css", NULL))
#define diya_shell_config_theme_dir(priv) (g_strconcat(g_get_home_dir(), "/.themes/", priv->theme ? priv->theme : "default", "/gtk-4.0", NULL))
@@ -19,6 +20,7 @@ enum
PROP_SHELL_NAME,
PROP_SHELL_THEME,
PROP_SHELL_IDLE_TO,
PROP_SHELL_LOCK,
N_PROPERTIES
};
@@ -36,6 +38,7 @@ typedef struct _DiyaShellPrivate
DiyaHook *files_hook;
gchar *theme;
DiyaIdleNotification *idle_notif;
GtkSessionLockInstance *lock;
} DiyaShellPrivate;
G_DEFINE_TYPE_WITH_PRIVATE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT);
@@ -69,6 +72,14 @@ static void diya_shell_dispose(GObject *object)
g_object_unref(priv->idle_notif);
priv->idle_notif = NULL;
}
if (priv->lock)
{
if (gtk_session_lock_instance_is_locked(priv->lock))
{
gtk_session_lock_instance_unlock(priv->lock);
}
g_object_unref(priv->lock);
}
if (priv->wayland)
{
g_object_unref(priv->wayland);
@@ -187,13 +198,14 @@ static void on_gtk_app_startup(GtkApplication *app, void *data)
{
class->startup_handle(shell);
}
/*
if (class->monitor_changed_handle)
{
GListModel *monitor_list = gdk_display_get_monitors(gdk_display_get_default());
g_debug("listen to monitor changed");
g_signal_connect(monitor_list, "items-changed", G_CALLBACK(class->monitor_changed_handle), shell);
}
*/
}
static void on_gtk_app_active(GtkApplication *app, void *data)
@@ -322,6 +334,10 @@ static void diya_shell_get_property(GObject *object, guint property_id, GValue *
case PROP_SHELL_THEME:
g_value_set_string(value, priv->theme);
break;
case PROP_SHELL_LOCK:
// assert(priv->lock);
g_value_set_pointer(value, priv->lock);
break;
case PROP_SHELL_IDLE_TO:
if(priv->idle_notif)
{
@@ -338,6 +354,59 @@ static void diya_shell_get_property(GObject *object, guint property_id, GValue *
}
}
static void on_shell_locked(GtkSessionLockInstance *lock, DiyaShell *shell)
{
(void)lock;
assert(shell);
g_message("Shell locked successfully");
g_signal_emit_by_name(shell, DIYA_SIGNAL_SHELL_LOCKED);
}
static void on_shell_unlocked(GtkSessionLockInstance *lock, DiyaShell *shell)
{
(void)lock;
assert(shell);
g_message("Shell unlocked");
g_signal_emit_by_name(shell, DIYA_SIGNAL_SHELL_UNLOCKED);
}
static void on_shell_lock_failed(GtkSessionLockInstance *lock, DiyaShell *shell)
{
(void)lock;
assert(shell);
g_critical("Unable to lock shell");
g_signal_emit_by_name(shell, DIYA_SIGNAL_SHELL_LOCK_FAILED);
}
static void on_monitor_present(GtkSessionLockInstance* lock, GdkMonitor *monitor, DiyaShell *shell)
{
assert(shell);
g_debug("Build lock window for monitor");
DiyaShellClass *class = DIYA_SHELL_GET_CLASS(shell);
if(class->build_lock_window)
{
GtkWindow* window = class->build_lock_window(shell);
gtk_session_lock_instance_assign_window_to_monitor(lock, window, monitor);
}
}
static void diya_shell_init_lock(DiyaShell* self)
{
DiyaShellPrivate *priv = diya_shell_get_instance_private(self);
if(priv->lock)
{
return;
}
priv->lock = gtk_session_lock_instance_new();
g_signal_connect(priv->lock, DIYA_SIGNAL_SHELL_LOCKED, G_CALLBACK(on_shell_locked), self);
g_signal_connect(priv->lock, "failed", G_CALLBACK(on_shell_lock_failed), self);
g_signal_connect(priv->lock, DIYA_SIGNAL_SHELL_UNLOCKED, G_CALLBACK(on_shell_unlocked), self);
g_signal_connect(priv->lock, "monitor", G_CALLBACK(on_monitor_present), self);
}
static void diya_shell_init(DiyaShell *self)
{
DiyaShellPrivate *priv = diya_shell_get_instance_private(self);
@@ -350,6 +419,7 @@ static void diya_shell_init(DiyaShell *self)
priv->files_hook = NULL;
priv->theme = NULL;
priv->idle_notif = NULL;
priv->lock = NULL;
}
DiyaWayland *diya_shell_get_wayland(DiyaShell *shell)
@@ -390,7 +460,7 @@ static void diya_shell_class_init(DiyaShellClass *class)
class->foreign_register = NULL;
class->virtual_keyboard_register = diya_virtual_keyboard_register;
class->monitor_changed_handle = NULL;
class->build_lock_window = NULL;
class->startup_handle = NULL;
class->active_handle = NULL;
class->reload_handle = NULL;
@@ -400,6 +470,7 @@ static void diya_shell_class_init(DiyaShellClass *class)
shell_properties[PROP_SHELL_APP] = g_param_spec_pointer(DIYA_PROP_SHELL_APPLICATION, NULL, "Shell application", G_PARAM_READABLE);
shell_properties[PROP_SHELL_THEME] = g_param_spec_string(DIYA_PROP_SHELL_THEME, NULL, "Shell theme", NULL, G_PARAM_READWRITE);
shell_properties[PROP_SHELL_IDLE_TO] = g_param_spec_uint(DIYA_PROP_SHELL_IDLE_TIMEOUT, NULL, "Shell IDLE timeout", 0, UINT32_MAX ,DEFAULT_IDLE_TIMEOUT, G_PARAM_READWRITE);
shell_properties[PROP_SHELL_LOCK] = g_param_spec_pointer(DIYA_PROP_SHELL_LOCK, NULL, "Shell lock", G_PARAM_READABLE);
g_object_class_install_properties(gobject_class, N_PROPERTIES, shell_properties);
@@ -519,6 +590,39 @@ static void diya_shell_class_init(DiyaShellClass *class)
G_TYPE_NONE,
1,
G_TYPE_POINTER);
g_signal_new(DIYA_SIGNAL_SHELL_LOCKED,
DIYA_TYPE_SHELL,
G_SIGNAL_DETAILED |
G_SIGNAL_ACTION |
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
g_signal_new(DIYA_SIGNAL_SHELL_UNLOCKED,
DIYA_TYPE_SHELL,
G_SIGNAL_DETAILED |
G_SIGNAL_ACTION |
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
g_signal_new(DIYA_SIGNAL_SHELL_LOCK_FAILED,
DIYA_TYPE_SHELL,
G_SIGNAL_DETAILED |
G_SIGNAL_ACTION |
G_SIGNAL_RUN_FIRST,
0,
NULL,
NULL,
NULL,
G_TYPE_NONE,
0);
}
static int diya_shell_handle_local_options(GApplication *application, GVariantDict *options, gpointer user_data)
@@ -702,4 +806,32 @@ gboolean diya_shell_watch_script(DiyaShell* self, const gchar* script)
priv->files_hook = diya_hook_new();
}
return diya_hook_install_lua(priv->files_hook, script);
}
void diya_shell_lock(DiyaShell* self)
{
DiyaShellPrivate *priv = diya_shell_get_instance_private(self);
if(!priv->lock)
{
diya_shell_init_lock(self);
}
if(gtk_session_lock_instance_is_locked(priv->lock))
{
g_warning("Shell session is already locked, doing nothing");
return;
}
if(!gtk_session_lock_instance_lock(priv->lock))
{
g_error("gtk_session_lock_instance_lock:Unable to lock the current session");
return;
}
}
void diya_shell_unlock(DiyaShell* self)
{
DiyaShellPrivate *priv = diya_shell_get_instance_private(self);
if(priv->lock)
{
gtk_session_lock_instance_unlock(priv->lock);
g_debug("gtk_session_lock_instance_unlock: Shell unlocked");
}
}

View File

@@ -14,7 +14,7 @@
#define DIYA_PROP_SHELL_APPLICATION "application"
#define DIYA_PROP_SHELL_THEME "theme"
#define DIYA_PROP_SHELL_IDLE_TIMEOUT "idle-timeout"
#define DIYA_PROP_SHELL_LOCK "lock"
#define DIYA_SIGNAL_SHELL_KEYBOARD_ENTER "keyboard-enter"
#define DIYA_SIGNAL_SHELL_KEYBOARD_LEAVE "keyboard-leave"
@@ -25,6 +25,9 @@
#define DIYA_SIGNAL_SHELL_RESUME "resume"
#define DIYA_SIGNAL_SHELL_WINDOW_ENTER "shell-window-enter"
#define DIYA_SIGNAL_SHELL_WINDOW_LEAVE "shell-window-leave"
#define DIYA_SIGNAL_SHELL_LOCKED "locked"
#define DIYA_SIGNAL_SHELL_UNLOCKED "unlocked"
#define DIYA_SIGNAL_SHELL_LOCK_FAILED "lock-failed"
#define DIYA_TYPE_SHELL (diya_shell_get_type())
G_DECLARE_DERIVABLE_TYPE(DiyaShell, diya_shell, DIYA, SHELL, DiyaObject)
@@ -38,7 +41,7 @@ struct _DiyaShellClass
DiyaObjectClass parent_class;
wl_protocol_manager_register_t foreign_register;
wl_protocol_manager_register_t virtual_keyboard_register;
void (*monitor_changed_handle)(GListModel* /*list*/,guint /*position*/, guint /*removed*/,guint /*added*/, gpointer);
GtkWindow* (*build_lock_window)(DiyaShell*);
void (*startup_handle)(DiyaShell*);
void (*active_handle)(DiyaShell*);
void (*reload_handle)(DiyaShell*);
@@ -57,6 +60,8 @@ gboolean diya_shell_watch_script(DiyaShell* shell, const gchar* script);
void diya_shell_unwatch_file(DiyaShell* shell, const gchar* file);
void diya_shell_power_display(DiyaShell* shell, gboolean mode);
void diya_shell_launch(DiyaShell* shell, GAppInfo* app);
void diya_shell_lock(DiyaShell* shell);
void diya_shell_unlock(DiyaShell* shell);
int diya_shell_run(DiyaShell* shell, int argc, char **argv);
#endif

View File

@@ -1,5 +1,6 @@
#include "taskbar-widget.h"
#include "foreign.h"
#include "session-lock.h"
#define DEFAULT_APP_ICON_NAME "application-x-executable-symbolic"
@@ -303,6 +304,7 @@ static void diya_dashboard_btn_test_clicked(GtkWidget *widget, gpointer user_dat
DiyaShellWindow *self = user_data;
DiyaSessionShell *shell = DIYA_SESSION_SHELL(diya_shell_window_get_shell(self));
g_return_if_fail(DIYA_IS_SESSION_SHELL(shell));
diya_shell_lock(DIYA_SHELL(shell));
// TODO remove
}