From b10cfab3ba99dd0664cf8cc7f7912679b65c5110 Mon Sep 17 00:00:00 2001 From: Dany LE Date: Fri, 13 Jun 2025 19:34:12 +0200 Subject: [PATCH] feat: implement the base classes for launcher + input - Base classes for lancher: Dashboard + Taskbar - Allow the shell to monitor directly wayland seat keyboard (on demand) --- meson.build | 11 +- resources/gresource-session.xml | 2 + resources/session-shell.css | 8 +- resources/ui/dashboard.ui | 59 +++++ resources/ui/taskbar.ui | 20 ++ src/base.c | 5 + src/base.h | 1 + src/foreign.c | 5 + src/foreign.h | 1 + src/input.c | 233 ++++++++++++++++++ src/input.h | 10 + src/launcher.c | 167 ++++++++++--- src/launcher.h | 3 + src/login-shell.c | 2 +- src/session-shell.c | 7 +- src/shell.c | 173 +++++++------ src/shell.h | 1 + src/{vkb => }/virtual-keyboard.c | 0 src/{vkb => }/virtual-keyboard.h | 0 src/widgets/base-widgets.c | 79 ++++++ src/widgets/base-widgets.h | 16 ++ src/widgets/dashboard-widget.c | 129 ++++++++++ src/widgets/dashboard-widget.h | 10 + src/widgets/taskbar-widget.c | 128 ++++++++++ src/widgets/taskbar-widget.h | 10 + .../virtual-keyboard-widgets.c | 0 .../virtual-keyboard-widgets.h | 0 27 files changed, 949 insertions(+), 131 deletions(-) create mode 100644 resources/ui/dashboard.ui create mode 100644 resources/ui/taskbar.ui create mode 100644 src/input.c create mode 100644 src/input.h rename src/{vkb => }/virtual-keyboard.c (100%) rename src/{vkb => }/virtual-keyboard.h (100%) create mode 100644 src/widgets/base-widgets.c create mode 100644 src/widgets/base-widgets.h create mode 100644 src/widgets/dashboard-widget.c create mode 100644 src/widgets/dashboard-widget.h create mode 100644 src/widgets/taskbar-widget.c create mode 100644 src/widgets/taskbar-widget.h rename src/{vkb => widgets}/virtual-keyboard-widgets.c (100%) rename src/{vkb => widgets}/virtual-keyboard-widgets.h (100%) diff --git a/meson.build b/meson.build index d88d701..8745dad 100644 --- a/meson.build +++ b/meson.build @@ -60,8 +60,9 @@ base = [ 'src/base.c', 'src/shell.c', 'src/wayland.c', - 'src/vkb/virtual-keyboard.c', - 'src/vkb/virtual-keyboard-widgets.c', + 'src/input.c', + 'src/virtual-keyboard.c', + 'src/widgets/virtual-keyboard-widgets.c', wayland_targets ] @@ -72,7 +73,11 @@ dm_src = [ 'src/session-shell.c', 'src/foreign.c', 'src/session-lock.c', - 'src/session.c'] + 'src/session.c', + 'src/widgets/base-widgets.c', + 'src/widgets/taskbar-widget.c', + 'src/widgets/dashboard-widget.c', +] buil_dep = [gtk, gtk_layer_shell, wayland_client, xkbcommon] diff --git a/resources/gresource-session.xml b/resources/gresource-session.xml index dde94c5..f89f093 100644 --- a/resources/gresource-session.xml +++ b/resources/gresource-session.xml @@ -4,5 +4,7 @@ resources/session-shell.css resources/virtual-keyboard.css resources/default.keymap + resources/ui/dashboard.ui + resources/ui/taskbar.ui \ No newline at end of file diff --git a/resources/session-shell.css b/resources/session-shell.css index 36cf45c..48a694b 100644 --- a/resources/session-shell.css +++ b/resources/session-shell.css @@ -1,9 +1,15 @@ @import url("resource:///dev/iohub/diya/shell/virtual-keyboard.css"); -#diya_shell_launcher +diya-taskbar { background-color: orange; } + +diya-dashboard +{ + background-color: blue; +} + #diya_shell_background { background-image:url("file:///etc/xdg/labwc/wpp.jpg"); diff --git a/resources/ui/dashboard.ui b/resources/ui/dashboard.ui new file mode 100644 index 0000000..0b9d559 --- /dev/null +++ b/resources/ui/dashboard.ui @@ -0,0 +1,59 @@ + + + + diff --git a/resources/ui/taskbar.ui b/resources/ui/taskbar.ui new file mode 100644 index 0000000..815276f --- /dev/null +++ b/resources/ui/taskbar.ui @@ -0,0 +1,20 @@ + + + + diff --git a/src/base.c b/src/base.c index d72af20..459eda5 100644 --- a/src/base.c +++ b/src/base.c @@ -22,6 +22,11 @@ static void diya_object_init(DiyaObject *self) (void) self; } +/** + * @brief Implementation of DiyaShellObject + * + */ + enum { SO_NO_PROP, diff --git a/src/base.h b/src/base.h index e94ae37..74bfc72 100644 --- a/src/base.h +++ b/src/base.h @@ -31,4 +31,5 @@ struct _DiyaShellObjectClass const gchar *diya_object_to_string(gpointer object); + #endif \ No newline at end of file diff --git a/src/foreign.c b/src/foreign.c index c7e0f7a..db4ad32 100644 --- a/src/foreign.c +++ b/src/foreign.c @@ -366,4 +366,9 @@ void diya_foreign_window_set_state(DiyaForeignWindow* self, enum diya_win_state zwlr_foreign_toplevel_handle_v1_unset_fullscreen(self->handle); } } +} + +bool diya_foreign_window_is_toplevel(DiyaForeignWindow* self) +{ + return self->parent_win == NULL; } \ No newline at end of file diff --git a/src/foreign.h b/src/foreign.h index 21332ac..9247493 100644 --- a/src/foreign.h +++ b/src/foreign.h @@ -16,4 +16,5 @@ void diya_session_shell_foreign_toplevel_register(struct wl_registry *registry, DiyaShell* diya_foreign_window_get_shell(DiyaForeignWindow* window); void diya_foreign_window_set_state(DiyaForeignWindow* window, enum diya_win_state state, bool value); +bool diya_foreign_window_is_toplevel(DiyaForeignWindow* window); #endif \ No newline at end of file diff --git a/src/input.c b/src/input.c new file mode 100644 index 0000000..b427adc --- /dev/null +++ b/src/input.c @@ -0,0 +1,233 @@ +#include "input.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wlr-foreign-toplevel-management-unstable-v1.h" +#include "virtual-keyboard-unstable-v1.h" +#include "wayland.h" + +struct _DiyaInput +{ + DiyaShellObject parent; + gchar *name; + struct wl_keyboard *keyboard; + struct wl_seat *seat; + struct xkb_state *xkb_state; + struct xkb_context *xkb_context; + struct xkb_keymap *xkb_keymap; +}; +G_DEFINE_FINAL_TYPE(DiyaInput, diya_input, DIYA_TYPE_SHELL_OBJECT) + +static void diya_input_dispose(GObject *object) +{ + g_debug("diya_input_dispose: %s", diya_object_to_string(object)); + DiyaInput *self = DIYA_INPUT(object); + if (self->name) + { + g_free(self->name); + self->name = NULL; + } + if (self->keyboard) + { + wl_keyboard_release(self->keyboard); + self->keyboard = NULL; + } + if (self->xkb_keymap) + { + xkb_keymap_unref(self->xkb_keymap); + self->xkb_keymap = NULL; + } + if (self->xkb_state) + { + xkb_state_unref(self->xkb_state); + self->xkb_state = NULL; + } + if (self->xkb_context) + { + xkb_context_unref(self->xkb_context); + self->xkb_context = NULL; + } + G_OBJECT_CLASS(diya_input_parent_class)->dispose(object); +} + +static void diya_input_init(DiyaInput *self) +{ + self->name = NULL; + self->keyboard = NULL; + self->xkb_state = NULL; + self->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + self->xkb_keymap = NULL; +} + +static const gchar *diya_input_to_string(DiyaObject *object) +{ + DiyaInput *self = DIYA_INPUT(object); + if (self->name) + { + return self->name; + } + return "unknown"; +} + +static void diya_input_class_init(DiyaInputClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(class); + DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class); + + gobject_class->dispose = diya_input_dispose; + // gobject_class->set_property = diya_input_set_property; + // gobject_class->get_property = diya_input_get_property; + base_class->to_string = diya_input_to_string; +} + +static void wl_keyboard_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int32_t fd, uint32_t size) +{ + (void) keyboard; + DiyaInput *self = data; + assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); + char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + assert(map_shm != MAP_FAILED); + struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_string(self->xkb_context, map_shm, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); + munmap(map_shm, size); + close(fd); + + struct xkb_state *xkb_state = xkb_state_new(xkb_keymap); + xkb_keymap_unref(self->xkb_keymap); + xkb_state_unref(self->xkb_state); + self->xkb_keymap = xkb_keymap; + self->xkb_state = xkb_state; +} + +static void wl_keyboard_enter(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface, + struct wl_array *keys) +{ + (void) keyboard; + (void) serial; + (void) surface; + DiyaInput *self = data; + g_warning("keyboard enter; keys pressed are:"); + uint32_t *key; + wl_array_for_each(key, keys) + { + char buf[128]; + xkb_keysym_t sym = xkb_state_key_get_one_sym(self->xkb_state, *key + 8); + xkb_keysym_get_name(sym, buf, sizeof(buf)); + g_warning("\tsym: %-12s (%d), ", buf, sym); + xkb_state_key_get_utf8(self->xkb_state, *key + 8, buf, sizeof(buf)); + g_warning("\tutf8: '%s'", buf); + } +} + +static void wl_keyboard_key(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, uint32_t key, uint32_t state) +{ + (void) keyboard; + (void) serial; + (void) time; + DiyaInput *self = data; + char buf[128]; + uint32_t keycode = key + 8; + xkb_keysym_t sym = xkb_state_key_get_one_sym(self->xkb_state, keycode); + xkb_keysym_get_name(sym, buf, sizeof(buf)); + const char *action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? "press" : "release"; + g_warning("wl_keyboard_key %s: sym: %-12s (%d), ", action, buf, sym); + xkb_state_key_get_utf8(self->xkb_state, keycode, buf, sizeof(buf)); + g_warning("\tutf8: '%s'", buf); +} + +static void wl_keyboard_leave(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface) +{ + (void) data; + (void) keyboard; + (void) serial; + (void) surface; + g_warning("keyboard leave"); +} + +static void wl_keyboard_modifiers(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ + (void) keyboard; + (void) serial; + DiyaInput *self = data; + xkb_state_update_mask(self->xkb_state,mods_depressed, mods_latched, mods_locked, 0, 0, group); +} + +static void wl_keyboard_repeat_info(void *data, struct wl_keyboard *keyboard,int32_t rate, int32_t delay) +{ + (void) data; + (void) keyboard; + (void) rate; + (void) delay; +} + +static const struct wl_keyboard_listener wl_keyboard_listener = { + .keymap = wl_keyboard_keymap, + .enter = wl_keyboard_enter, + .leave = wl_keyboard_leave, + .key = wl_keyboard_key, + .modifiers = wl_keyboard_modifiers, + .repeat_info = wl_keyboard_repeat_info, +}; + +static void wl_seat_capabilities(void *data, struct wl_seat *seat, uint32_t capabilities) +{ + DiyaInput *self = data; + bool have_keyboard = capabilities & WL_SEAT_CAPABILITY_KEYBOARD; + + if (have_keyboard && self->keyboard == NULL) + { + self->keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(self->keyboard, &wl_keyboard_listener, self); + } + else if (!have_keyboard && self->keyboard != NULL) + { + wl_keyboard_release(self->keyboard); + self->keyboard = NULL; + } +} + +static void wl_seat_name(void *data, struct wl_seat *seat, const char *name) +{ + (void) seat; + DiyaInput *self = data; + if (self->name) + { + return; + } + g_info("Attach to seat: %s", name); + self->name = g_strdup(name); +} + +static const struct wl_seat_listener wl_seat_listener = { + .capabilities = wl_seat_capabilities, + .name = wl_seat_name, +}; + +DiyaInput *diya_input_new(DiyaShell *shell) +{ + assert(shell); + DiyaInput *self = g_object_new(DIYA_TYPE_INPUT, "shell", shell, NULL); + DiyaWayland *wayland = diya_shell_get_wayland(shell); + assert(wayland); + struct wl_seat *seat = diya_wayland_get_seat(wayland); + wl_seat_add_listener(seat, &wl_seat_listener, self); + return self; +} diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000..8cb8949 --- /dev/null +++ b/src/input.h @@ -0,0 +1,10 @@ +#ifndef DIYA_INPUT_H +#define DIYA_INPUT_H +#include "base.h" +#include "shell.h" + +#define DIYA_TYPE_INPUT (diya_input_get_type ()) +G_DECLARE_FINAL_TYPE (DiyaInput, diya_input, DIYA, INPUT, DiyaShellObject) + +DiyaInput* diya_input_new(DiyaShell* shell); +#endif \ No newline at end of file diff --git a/src/launcher.c b/src/launcher.c index 1410abc..894245d 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -1,16 +1,30 @@ -#include "launcher.h" -#include "foreign.h" -#include "session-lock.h" +#include +#include #include +#include "launcher.h" +#include "widgets/dashboard-widget.h" +#include "widgets/taskbar-widget.h" +#include "foreign.h" +#include "wayland.h" -#define NAMESPACE "diya_shell_launcher" - -static void on_launcher_destroy(GtkWindow *window, GApplication *_data) +struct _DiyaLauncher { - (void) window; - (void)_data; - //g_application_quit (G_APPLICATION (gtk_window_get_application (window))); -} + DiyaShellObject parent; + DiyaDashboardWidget* dashboard; + DiyaTaskbarWidget* taskbar; +}; +G_DEFINE_FINAL_TYPE(DiyaLauncher, diya_launcher, DIYA_TYPE_SHELL_OBJECT) + +enum +{ + NO_PROP, + PROP_DASHBOARD, + PROP_TASKBAR, + N_PROPERTIES +}; + +static GParamSpec *g_prop[N_PROPERTIES] = {0}; + static void on_foreign_window_change(DiyaSessionShell* shell, DiyaForeignWindow * win, gpointer data) { @@ -28,12 +42,6 @@ static void on_foreign_window_removed(DiyaSessionShell* shell, DiyaForeignWindow g_warning("on_foreign_window_removed: WINDOW REMOVED %s, shell %s", diya_object_to_string(DIYA_OBJECT(win)), diya_object_to_string(DIYA_OBJECT(shell))); } -static void session_lock(GtkWidget *widget,gpointer data) -{ - (void) widget; - g_warning("Enter session lock"); - diya_session_shell_lock(data); -} static void show_windows(GtkWidget *widget,gpointer data) { @@ -55,37 +63,107 @@ static void show_windows(GtkWidget *widget,gpointer data) } } + +static void diya_launcher_dispose(GObject* object) +{ + (void) object; + DiyaLauncher * self = DIYA_LAUNCHER(object); + g_debug("diya_launcher_dispose: %s", diya_object_to_string(object)); + if(self->dashboard) + { + gtk_window_destroy(GTK_WINDOW(self->dashboard)); + } + if(self->taskbar) + { + gtk_window_destroy(GTK_WINDOW(self->taskbar)); + } + G_OBJECT_CLASS(diya_launcher_parent_class)->dispose(object); +} + +static void diya_launcher_init(DiyaLauncher * self) +{ + self->taskbar = NULL; + self->dashboard = NULL; +} + +static const gchar* diya_launcher_to_string(DiyaObject* object) +{ + (void) object; + return "DiyaLauncher"; +} + + +static void diya_launcher_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + DiyaLauncher * self = DIYA_LAUNCHER(object); + + switch (property_id) + { + case PROP_DASHBOARD: + self->dashboard = g_value_get_pointer(value); + break; + case PROP_TASKBAR: + self->taskbar = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void diya_launcher_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + DiyaLauncher * self = DIYA_LAUNCHER(object); + switch (property_id) + { + case PROP_DASHBOARD: + g_value_set_pointer(value, self->dashboard); + break; + case PROP_TASKBAR: + g_value_set_pointer(value, self->taskbar); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void diya_launcher_class_init(DiyaLauncherClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(class); + DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class); + + gobject_class->dispose = diya_launcher_dispose; + gobject_class->set_property = diya_launcher_set_property; + gobject_class->get_property = diya_launcher_get_property; + base_class->to_string = diya_launcher_to_string; + + g_prop[PROP_DASHBOARD] = g_param_spec_pointer("dashboard", NULL, "Launcher dashboard", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); + g_prop[PROP_TASKBAR] = g_param_spec_pointer("taskbar", NULL, "Launcher taskbar", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_properties (gobject_class, N_PROPERTIES, g_prop); +} + void diya_session_shell_launcher_init(DiyaSessionShell * shell) { assert(shell); GtkApplication * app; g_object_get(shell, "application", &app, NULL); assert(app); - GtkWindow *gtk_window = GTK_WINDOW (gtk_application_window_new (app)); - assert(gtk_window); - g_object_set(shell, "launchpad", gtk_window, NULL); - g_signal_connect (gtk_window, "destroy", G_CALLBACK (on_launcher_destroy), NULL); - // int layer shell for window - gtk_layer_init_for_window (gtk_window); - // anchor window to all edges - gtk_layer_set_anchor (gtk_window, GTK_LAYER_SHELL_EDGE_LEFT, true); - gtk_layer_set_anchor (gtk_window, GTK_LAYER_SHELL_EDGE_RIGHT, true); - gtk_layer_set_anchor (gtk_window, GTK_LAYER_SHELL_EDGE_TOP, false); - gtk_layer_set_anchor (gtk_window, GTK_LAYER_SHELL_EDGE_BOTTOM, true); + DiyaDashboardWidget* dashboard = DIYA_DASHBOARD_WIDGET(g_object_new (DIYA_TYPE_DASHBOARD_WIDGET, "application", app, "shell",shell, NULL)); + assert(dashboard); - // set margin on window - for (int i = 0; i < GTK_LAYER_SHELL_EDGE_ENTRY_NUMBER; i++) - gtk_layer_set_margin (gtk_window, i, 0); - gtk_layer_set_layer (gtk_window, GTK_LAYER_SHELL_LAYER_TOP); - gtk_layer_set_keyboard_mode (gtk_window, GTK_LAYER_SHELL_KEYBOARD_MODE_ON_DEMAND); - gtk_layer_set_namespace (gtk_window, NAMESPACE); - // the top launcher shall be exclusive - gtk_layer_auto_exclusive_zone_enable (gtk_window); + DiyaTaskbarWidget* taskbar = DIYA_TASKBAR_WIDGET(g_object_new (DIYA_TYPE_TASKBAR_WIDGET, "application", app, "shell",shell, NULL)); + assert(taskbar); + //gtk_window_set_transient_for(GTK_WINDOW(dashboard), GTK_WINDOW(taskbar)); + DiyaLauncher* self = DIYA_LAUNCHER(g_object_new (DIYA_TYPE_LAUNCHER, "dashboard", dashboard, "taskbar",taskbar, NULL)); + assert(self); + g_object_bind_property(taskbar, "show-dashboard", dashboard, "active", G_BINDING_BIDIRECTIONAL); + g_object_set(shell, "launchpad", self, NULL); + //g_signal_connect (GTK_WINDOW(dashboard), "destroy", G_CALLBACK (on_launcher_destroy), NULL); - gtk_widget_set_name(GTK_WIDGET(gtk_window),NAMESPACE); - gtk_window_set_default_size(gtk_window, 48, 48); + /* GtkWidget *box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5); gtk_box_set_homogeneous (GTK_BOX (box), TRUE); gtk_window_set_child (GTK_WINDOW (gtk_window), box); @@ -96,10 +174,17 @@ void diya_session_shell_launcher_init(DiyaSessionShell * shell) gtk_box_append (GTK_BOX (box), button); button = gtk_button_new_with_label ("show all windows"); - g_signal_connect (button, "clicked", G_CALLBACK (show_windows), shell); + g_signal_connect (button, "clicked", G_CALLBACK (show_windows), shell); gtk_box_append (GTK_BOX (box), button); - //g_signal_connect (gtk_window, "orientation-changed", G_CALLBACK (on_orientation_changed), /*data*/NULL); - gtk_window_present (GTK_WINDOW (gtk_window)); + + button = gtk_button_new_with_label ("Dashboard"); + g_signal_connect (button, "clicked", G_CALLBACK (show_dashboard), shell); + gtk_box_append (GTK_BOX (box), button); + + //g_signal_connect (gtk_window, "orientation-changed", G_CALLBACK (on_orientation_changed), NULL); + */ + + gtk_window_present (GTK_WINDOW (taskbar)); g_signal_connect (shell, "foreign-window-changed", G_CALLBACK (on_foreign_window_change), NULL); g_signal_connect (shell, "foreign-window-removed", G_CALLBACK (on_foreign_window_removed), NULL); @@ -116,4 +201,4 @@ void diya_session_shell_launcher_init(DiyaSessionShell * shell) //g_warning("%s", g_app_info_get_icon(element_data)); } g_list_free_full(apps, g_object_unref); -} \ No newline at end of file +} diff --git a/src/launcher.h b/src/launcher.h index df477b9..4bc3e46 100644 --- a/src/launcher.h +++ b/src/launcher.h @@ -3,6 +3,9 @@ #include "session-shell.h" +#define DIYA_TYPE_LAUNCHER (diya_launcher_get_type ()) +G_DECLARE_FINAL_TYPE (DiyaLauncher, diya_launcher, DIYA, LAUNCHER, DiyaShellObject) + void diya_session_shell_launcher_init(DiyaSessionShell * shell); diff --git a/src/login-shell.c b/src/login-shell.c index ec9aee5..a4fd046 100644 --- a/src/login-shell.c +++ b/src/login-shell.c @@ -3,7 +3,7 @@ #include #include "login-shell.h" -#include "vkb/virtual-keyboard-widgets.h" +#include "widgets/virtual-keyboard-widgets.h" #define DBUS_SERVER_NAME "dev.iohub.diya.SessionManager" #define DBUS_SERVER_PATH "/dev/iohub/diya/SessionManager" diff --git a/src/session-shell.c b/src/session-shell.c index 3149582..5c31dc8 100644 --- a/src/session-shell.c +++ b/src/session-shell.c @@ -24,7 +24,7 @@ struct _DiyaSessionShell { DiyaShell parent; GtkWindow* background; - GtkWindow* launcher; + DiyaLauncher* launcher; GHashTable* windows; GtkSessionLockInstance* lock; }; @@ -45,7 +45,7 @@ static void diya_session_shell_dispose(GObject* object) } if(self->launcher) { - gtk_window_destroy(self->launcher); + g_object_unref(self->launcher); } G_OBJECT_CLASS(diya_session_shell_parent_class)->dispose(object); } @@ -103,8 +103,7 @@ static void diya_session_shell_startup(DiyaShell* shell) static void diya_session_shell_active(DiyaShell* shell) { - (void) shell; - // diya_session_shell_lock(DIYA_SESSION_SHELL(shell)); + diya_shell_monitor_input(shell); } static void diya_session_shell_class_init(DiyaSessionShellClass *class) diff --git a/src/shell.c b/src/shell.c index 640f148..7633dfb 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1,7 +1,8 @@ #include #include "shell.h" #include "wayland.h" -#include "vkb/virtual-keyboard.h" +#include "virtual-keyboard.h" +#include "input.h" enum { NO_PROP, @@ -13,39 +14,41 @@ enum static GParamSpec *shell_properties[N_PROPERTIES] = {0}; - typedef struct _DiyaShellPrivate { - DiyaObject parent; - DiyaWayland * wayland; - GtkApplication* app; - gchar* name; - GHashTable* vkbs; - GtkCssProvider* css_provider; + DiyaObject parent; + DiyaWayland *wayland; + GtkApplication *app; + gchar *name; + GHashTable *vkbs; + GtkCssProvider *css_provider; + DiyaInput *input; } DiyaShellPrivate; G_DEFINE_TYPE_WITH_PRIVATE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT); - - -static void diya_shell_dispose(GObject* object) +static void diya_shell_dispose(GObject *object) { g_debug("diya_shell_dispose: %s", diya_object_to_string(object)); - DiyaShell * self = DIYA_SHELL(object); - DiyaShellPrivate* priv = diya_shell_get_instance_private(self); - if(priv->wayland) + DiyaShell *self = DIYA_SHELL(object); + DiyaShellPrivate *priv = diya_shell_get_instance_private(self); + if (priv->wayland) { g_object_unref(priv->wayland); } - if(priv->name) + if (priv->name) { g_free(priv->name); priv->name = NULL; } - if(priv->css_provider) + if (priv->css_provider) { g_object_unref(priv->css_provider); } + if (priv->input) + { + g_object_unref(priv->input); + } g_hash_table_destroy(priv->vkbs); G_OBJECT_CLASS(diya_shell_parent_class)->dispose(object); if (priv->app) @@ -54,15 +57,15 @@ static void diya_shell_dispose(GObject* object) } } -static void diya_shell_reload(DiyaShell* shell) +static void diya_shell_reload(DiyaShell *shell) { GError *err = NULL; GBytes *bytes = NULL; - gchar* css_string = NULL; - DiyaShellPrivate* priv = diya_shell_get_instance_private(shell); - gchar* css_file = g_strconcat(g_get_user_config_dir(),"/diya/themes/",priv->name,".css", NULL); + gchar *css_string = NULL; + DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); + gchar *css_file = g_strconcat(g_get_user_config_dir(), "/diya/themes/", priv->name, ".css", NULL); g_debug("diya_shell_reload: Looking for css file: %s", css_file); - g_file_get_contents(css_file,&css_string, NULL, &err); + g_file_get_contents(css_file, &css_string, NULL, &err); free(css_file); if (err != NULL) { @@ -70,7 +73,7 @@ static void diya_shell_reload(DiyaShell* shell) g_error_free(err); err = NULL; g_debug("diya_shell_reload: Fallback to default theme"); - css_file = g_strconcat("/dev/iohub/diya/shell/",priv->name,".css", NULL); + css_file = g_strconcat("/dev/iohub/diya/shell/", priv->name, ".css", NULL); bytes = g_resources_lookup_data(css_file, 0, &err); free(css_file); if (err != NULL) @@ -81,18 +84,18 @@ static void diya_shell_reload(DiyaShell* shell) } else { - css_string = (gchar*)g_bytes_get_data(bytes, NULL); + css_string = (gchar *)g_bytes_get_data(bytes, NULL); } } - if(css_string) + if (css_string) { - if(priv->css_provider) + if (priv->css_provider) { gtk_style_context_remove_provider_for_display(gdk_display_get_default(), GTK_STYLE_PROVIDER(priv->css_provider)); g_object_unref(priv->css_provider); priv->css_provider = NULL; } - + g_debug("diya_shell_reload: Applying stylesheet:\n %s", css_string); priv->css_provider = gtk_css_provider_new(); gtk_css_provider_load_from_string(priv->css_provider, css_string); @@ -100,12 +103,12 @@ static void diya_shell_reload(DiyaShell* shell) gdk_display_get_default(), GTK_STYLE_PROVIDER(priv->css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); - if(!bytes) + if (!bytes) { free(css_string); } } - if(bytes) + if (bytes) { g_bytes_unref(bytes); } @@ -115,19 +118,19 @@ static void on_gtk_app_startup(GtkApplication *app, void *data) { (void)app; DiyaShell *shell = data; - DiyaShellPrivate* priv = diya_shell_get_instance_private(shell); - priv->wayland =diya_wayland_new(DIYA_SHELL(shell)); - DiyaShellClass* class = DIYA_SHELL_GET_CLASS(shell); + DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); + priv->wayland = diya_wayland_new(DIYA_SHELL(shell)); + DiyaShellClass *class = DIYA_SHELL_GET_CLASS(shell); diya_shell_reload(shell); - if(class->startup_handle) + if (class->startup_handle) { class->startup_handle(shell); } - if(class->monitor_changed_handle) + if (class->monitor_changed_handle) { - GListModel* monitor_list = gdk_display_get_monitors(gdk_display_get_default()); + 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); + g_signal_connect(monitor_list, "items-changed", G_CALLBACK(class->monitor_changed_handle), shell); } } @@ -135,8 +138,8 @@ static void on_gtk_app_active(GtkApplication *app, void *data) { (void)app; DiyaShell *shell = data; - DiyaShellClass* class = DIYA_SHELL_GET_CLASS(shell); - if(class->active_handle) + DiyaShellClass *class = DIYA_SHELL_GET_CLASS(shell); + if (class->active_handle) { class->active_handle(shell); } @@ -148,42 +151,41 @@ static gboolean diya_shell_sigint_handle(gpointer data) return true; } - -static gboolean diya_shell_sighub_handle(DiyaShell* self) +static gboolean diya_shell_sighub_handle(DiyaShell *self) { // reload css file diya_shell_reload(self); - DiyaShellClass* class = DIYA_SHELL_GET_CLASS(self); - if(class->reload_handle) + DiyaShellClass *class = DIYA_SHELL_GET_CLASS(self); + if (class->reload_handle) { class->reload_handle(self); } return true; } -static void init_gtk_application(DiyaShell* self) +static void init_gtk_application(DiyaShell *self) { - DiyaShellPrivate* priv = diya_shell_get_instance_private(self); - if(priv->app) + DiyaShellPrivate *priv = diya_shell_get_instance_private(self); + if (priv->app) { return; } priv->app = gtk_application_new(priv->name, G_APPLICATION_DEFAULT_FLAGS); g_signal_connect(priv->app, "startup", G_CALLBACK(on_gtk_app_startup), (void *)self); g_signal_connect(priv->app, "activate", G_CALLBACK(on_gtk_app_active), (void *)self); - g_unix_signal_add(SIGINT,(GSourceFunc)diya_shell_sigint_handle,(void*)self); - g_unix_signal_add(SIGHUP, (GSourceFunc)diya_shell_sighub_handle, (void*)self); + g_unix_signal_add(SIGINT, (GSourceFunc)diya_shell_sigint_handle, (void *)self); + g_unix_signal_add(SIGHUP, (GSourceFunc)diya_shell_sighub_handle, (void *)self); } static void diya_shell_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { - DiyaShell * self = DIYA_SHELL(object); - DiyaShellPrivate* priv = diya_shell_get_instance_private(self); + DiyaShell *self = DIYA_SHELL(object); + DiyaShellPrivate *priv = diya_shell_get_instance_private(self); switch (property_id) { case PROP_SHELL_NAME: - if(priv->name) + if (priv->name) { return; } @@ -191,15 +193,15 @@ static void diya_shell_set_property(GObject *object, guint property_id, const GV init_gtk_application(self); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } } static void diya_shell_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { - DiyaShell * self = DIYA_SHELL(object); - DiyaShellPrivate* priv = diya_shell_get_instance_private(self); + DiyaShell *self = DIYA_SHELL(object); + DiyaShellPrivate *priv = diya_shell_get_instance_private(self); switch (property_id) { case PROP_SHELL_WAYLAND: @@ -212,39 +214,39 @@ static void diya_shell_get_property(GObject *object, guint property_id, GValue * g_value_set_string(value, priv->name); break; default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; } } - static void diya_shell_init(DiyaShell *self) { - DiyaShellPrivate* priv = diya_shell_get_instance_private(self); + DiyaShellPrivate *priv = diya_shell_get_instance_private(self); priv->wayland = NULL; priv->app = NULL; priv->name = NULL; - priv->vkbs = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref); + priv->vkbs = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, g_object_unref); priv->css_provider = NULL; + priv->input = NULL; } -DiyaWayland * diya_shell_get_wayland(DiyaShell* shell) +DiyaWayland *diya_shell_get_wayland(DiyaShell *shell) { - DiyaShellPrivate* priv = diya_shell_get_instance_private(shell); + DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); assert(DIYA_IS_WAYLAND(priv->wayland)); return priv->wayland; } -GtkApplication* diya_shell_get_application(DiyaShell* shell) +GtkApplication *diya_shell_get_application(DiyaShell *shell) { - DiyaShellPrivate* priv = diya_shell_get_instance_private(shell); + DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); assert(GTK_IS_APPLICATION(priv->app)); return priv->app; } -const char* diya_shell_get_name(DiyaShell* shell) +const char *diya_shell_get_name(DiyaShell *shell) { - DiyaShellPrivate* priv = diya_shell_get_instance_private(shell); + DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); return priv->name; } @@ -269,43 +271,43 @@ static void diya_shell_class_init(DiyaShellClass *class) class->startup_handle = NULL; class->active_handle = NULL; class->reload_handle = NULL; - - shell_properties[PROP_SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READABLE); // + + shell_properties[PROP_SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READABLE); // shell_properties[PROP_SHELL_NAME] = g_param_spec_string("name", NULL, "Shell name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); shell_properties[PROP_SHELL_APP] = g_param_spec_pointer("application", NULL, "Shell application", G_PARAM_READABLE); - g_object_class_install_properties (gobject_class, N_PROPERTIES, shell_properties); + g_object_class_install_properties(gobject_class, N_PROPERTIES, shell_properties); } -int diya_shell_run(DiyaShell* shell, int argc, char **argv) -{ - DiyaShellPrivate* priv = diya_shell_get_instance_private(shell); +int diya_shell_run(DiyaShell *shell, int argc, char **argv) +{ + DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); assert(GTK_IS_APPLICATION(priv->app)); - GtkApplication* app = priv->app; - int status = g_application_run(G_APPLICATION(app),argc,argv); + GtkApplication *app = priv->app; + int status = g_application_run(G_APPLICATION(app), argc, argv); g_object_unref(app); return status; } -DiyaVirtualKeyboard* diya_shell_get_virtual_keyboard(DiyaShell* shell, const gchar* name) +DiyaVirtualKeyboard *diya_shell_get_virtual_keyboard(DiyaShell *shell, const gchar *name) { - DiyaVirtualKeyboard* vkb = NULL; - DiyaShellPrivate* priv = diya_shell_get_instance_private(shell); - if(name) + DiyaVirtualKeyboard *vkb = NULL; + DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); + if (name) { - if(g_hash_table_contains(priv->vkbs, name)) + if (g_hash_table_contains(priv->vkbs, name)) { g_debug("diya_shell_get_virtual_keyboard: Getting keyboard %s from cache", name); vkb = g_hash_table_lookup(priv->vkbs, name); } else { - gchar* keymap_file = g_strconcat(g_get_user_config_dir(),"/diya/xkb/", name,".keymap", NULL); + gchar *keymap_file = g_strconcat(g_get_user_config_dir(), "/diya/xkb/", name, ".keymap", NULL); g_debug("diya_shell_get_virtual_keyboard: Looking for keymap file: %s", keymap_file); - if(g_file_test(keymap_file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK)) + if (g_file_test(keymap_file, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK)) { vkb = diya_virtual_keyboard_new(shell, keymap_file); - if(vkb) + if (vkb) { g_debug("diya_shell_get_virtual_keyboard: add new keyboard %s to cache", name); g_hash_table_insert(priv->vkbs, (gpointer)name, vkb); @@ -315,16 +317,25 @@ DiyaVirtualKeyboard* diya_shell_get_virtual_keyboard(DiyaShell* shell, const gch } } - if(!vkb) + if (!vkb) { g_debug("Fallback to default virtual key board"); - if(!g_hash_table_contains(priv->vkbs, "default")) + if (!g_hash_table_contains(priv->vkbs, "default")) { g_debug("Add new keyboard instance to cache"); - g_hash_table_insert(priv->vkbs,"default", diya_virtual_keyboard_new(shell, NULL)); + g_hash_table_insert(priv->vkbs, "default", diya_virtual_keyboard_new(shell, NULL)); } vkb = g_hash_table_lookup(priv->vkbs, "default"); } return vkb; +} +void diya_shell_monitor_input(DiyaShell *self) +{ + DiyaShellPrivate *priv = diya_shell_get_instance_private(self); + if (priv->input) + { + return; + } + priv->input = diya_input_new(self); } \ No newline at end of file diff --git a/src/shell.h b/src/shell.h index 8ef40cc..72f8f43 100644 --- a/src/shell.h +++ b/src/shell.h @@ -33,6 +33,7 @@ DiyaWayland * diya_shell_get_wayland(DiyaShell* shell); GtkApplication* diya_shell_get_application(DiyaShell* shell); const char* diya_shell_get_name(DiyaShell* shell); DiyaVirtualKeyboard* diya_shell_get_virtual_keyboard(DiyaShell* shell, const gchar* name); +void diya_shell_monitor_input(DiyaShell* shell); int diya_shell_run(DiyaShell* shell, int argc, char **argv); #endif \ No newline at end of file diff --git a/src/vkb/virtual-keyboard.c b/src/virtual-keyboard.c similarity index 100% rename from src/vkb/virtual-keyboard.c rename to src/virtual-keyboard.c diff --git a/src/vkb/virtual-keyboard.h b/src/virtual-keyboard.h similarity index 100% rename from src/vkb/virtual-keyboard.h rename to src/virtual-keyboard.h diff --git a/src/widgets/base-widgets.c b/src/widgets/base-widgets.c new file mode 100644 index 0000000..0ad4dde --- /dev/null +++ b/src/widgets/base-widgets.c @@ -0,0 +1,79 @@ + +#include "base-widgets.h" +#include "shell.h" +/** + * @brief Implementation of DiyaShellWindow + * + */ + + +enum +{ + SW_NO_PROP, + SW_SHELL, + SW_N_PROPERTIES +}; + +static GParamSpec *g_sw_prop[SW_N_PROPERTIES] = {0}; + +typedef struct _DiyaShellWindowPrivate +{ + GtkApplicationWindow parent; + DiyaShell * shell; +} DiyaShellWindowPrivate; +G_DEFINE_TYPE_WITH_PRIVATE(DiyaShellWindow, diya_shell_window, GTK_TYPE_APPLICATION_WINDOW) + +static void diya_shell_window_dispose(GObject* object) +{ + g_debug("diya_shell_window_dispose"); + G_OBJECT_CLASS(diya_shell_window_parent_class)->dispose(object); +} + +static void diya_shell_window_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + DiyaShellWindow * self = DIYA_SHELL_WINDOW(object); + DiyaShellWindowPrivate* priv = diya_shell_window_get_instance_private(self); + + switch (property_id) + { + case SW_SHELL: + priv->shell = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void diya_shell_window_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + DiyaShellWindow * self = DIYA_SHELL_WINDOW(object); + DiyaShellWindowPrivate* priv = diya_shell_window_get_instance_private(self); + switch (property_id) + { + case SW_SHELL: + g_value_set_pointer(value, priv->shell); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +static void diya_shell_window_init(DiyaShellWindow *self) +{ + DiyaShellWindowPrivate* priv = diya_shell_window_get_instance_private(self); + priv->shell = NULL; +} + +static void diya_shell_window_class_init(DiyaShellWindowClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(class); + gobject_class->dispose = diya_shell_window_dispose; + gobject_class->set_property = diya_shell_window_set_property; + gobject_class->get_property = diya_shell_window_get_property; + g_sw_prop[SW_SHELL] = g_param_spec_pointer("shell", NULL, "Reference to global shell", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); // + + g_object_class_install_properties (gobject_class, SW_N_PROPERTIES, g_sw_prop); +} diff --git a/src/widgets/base-widgets.h b/src/widgets/base-widgets.h new file mode 100644 index 0000000..6564aa4 --- /dev/null +++ b/src/widgets/base-widgets.h @@ -0,0 +1,16 @@ +#ifndef DIYA_BASE_WIDGETS_H +#define DIYA_BASE_WIDGETS_H + +#include +#include +#include + +#define DIYA_TYPE_SHELL_WINDOW (diya_shell_window_get_type()) +G_DECLARE_DERIVABLE_TYPE(DiyaShellWindow, diya_shell_window, DIYA, SHELL_WINDOW, GtkApplicationWindow) +struct _DiyaShellWindowClass +{ + GtkApplicationWindowClass parent_class; +}; + + +#endif \ No newline at end of file diff --git a/src/widgets/dashboard-widget.c b/src/widgets/dashboard-widget.c new file mode 100644 index 0000000..7b9c427 --- /dev/null +++ b/src/widgets/dashboard-widget.c @@ -0,0 +1,129 @@ +#include "dashboard-widget.h" + + +struct _DiyaDashboardWidget +{ + DiyaShellWindow parent; + GtkWidget *revealer; + GtkWidget *search_entry; + bool active; +}; + +enum +{ + NO_PROP, + PROP_ACTIVE, + N_PROPERTIES +}; + +static GParamSpec *g_prop[N_PROPERTIES] = {0}; + + +G_DEFINE_TYPE (DiyaDashboardWidget, diya_dashboard_widget, DIYA_TYPE_SHELL_WINDOW) + +static void diya_dashboard_widget_dispose(GObject* object) +{ + (void) object; + g_debug("diya_dashboard_widget_dispose"); + G_OBJECT_CLASS(diya_dashboard_widget_parent_class)->dispose(object); +} + +static void diya_dashboard_widget_init(DiyaDashboardWidget * self) +{ + g_debug("diya_dashboard_widget_init"); + gtk_widget_init_template (GTK_WIDGET(self)); + self->active = false; + //builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui"); + // GtkWindow* win = GTK_WINDOW(self); + + // g_object_bind_property(self->btn_toggle, "active", self->revealer, "reveal-child", G_SETTINGS_BIND_DEFAULT); + // gtk_widget_set_can_focus(self->revealer, false); + + //g_signal_connect (GTK_WINDOW(dashboard), "destroy", G_CALLBACK (on_launcher_destroy), NULL); + + // int layer shell for window + gtk_layer_init_for_window (GTK_WINDOW(self)); + // anchor window to all edges + gtk_layer_set_anchor (GTK_WINDOW(self), GTK_LAYER_SHELL_EDGE_LEFT, true); + gtk_layer_set_anchor (GTK_WINDOW(self), GTK_LAYER_SHELL_EDGE_RIGHT, true); + gtk_layer_set_anchor (GTK_WINDOW(self), GTK_LAYER_SHELL_EDGE_TOP, true); + gtk_layer_set_anchor (GTK_WINDOW(self), GTK_LAYER_SHELL_EDGE_BOTTOM, true); + gtk_layer_set_namespace(GTK_WINDOW(self), "diya-dashboard"); + // set margin on window + for (int i = 0; i < GTK_LAYER_SHELL_EDGE_ENTRY_NUMBER; i++) + gtk_layer_set_margin (GTK_WINDOW(self), i, 0); + gtk_layer_set_layer (GTK_WINDOW(self), GTK_LAYER_SHELL_LAYER_TOP); + //gtk_layer_set_keyboard_mode (GTK_WINDOW(self), GTK_LAYER_SHELL_KEYBOARD_MODE_ON_DEMAND); + // the top launcher shall be exclusive + //gtk_layer_auto_exclusive_zone_enable (GTK_WINDOW(self)); + gtk_layer_set_keyboard_mode(GTK_WINDOW(self), GTK_LAYER_SHELL_KEYBOARD_MODE_ON_DEMAND); + // gtk_widget_set_can_focus(GTK_WIDGET(self), true); + //gtk_widget_set_name(GTK_WIDGET(dashboard),NAMESPACE); + //gtk_window_set_default_size(GTK_WINDOW(dashboard), 48, 48); +} + +static void diya_dashboard_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + DiyaDashboardWidget * self = DIYA_DASHBOARD_WIDGET(object); + + switch (property_id) + { + case PROP_ACTIVE: + self->active = g_value_get_boolean(value); + if(self->active) + { + gtk_window_present(GTK_WINDOW(self)); + // gtk_widget_set_visible(GTK_WIDGET(self), true); + gtk_revealer_set_reveal_child(GTK_REVEALER(self->revealer), true); + gtk_window_set_focus(GTK_WINDOW(self), self->search_entry); + // gtk_widget_grab_focus( GTK_WIDGET(self->search_entry)); + } + else + { + gtk_revealer_set_reveal_child(GTK_REVEALER(self->revealer), false); + gtk_widget_set_visible(GTK_WIDGET(self), false); + } + + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void diya_dashboard_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + DiyaDashboardWidget * self = DIYA_DASHBOARD_WIDGET(object); + switch (property_id) + { + case PROP_ACTIVE: + g_value_set_boolean(value, self->active); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +static void diya_dashboard_widget_class_init(DiyaDashboardWidgetClass* class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(class); + gobject_class->dispose = diya_dashboard_widget_dispose; + gobject_class->set_property = diya_dashboard_set_property; + gobject_class->get_property = diya_dashboard_get_property; + + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),"/dev/iohub/diya/shell/dashboard.ui"); + gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), DiyaDashboardWidget, revealer); + gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), DiyaDashboardWidget, search_entry); + + //gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), diya_dashboard_toggle); + + gtk_widget_class_set_css_name(GTK_WIDGET_CLASS(class), "diya-dashboard"); + //gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS (class), ExampleAppWindow, stack); + //gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed); + + g_prop[PROP_ACTIVE] = g_param_spec_boolean("active", NULL, "Active the dashboard", false, G_PARAM_READWRITE); // + + g_object_class_install_properties (gobject_class, N_PROPERTIES, g_prop); +} \ No newline at end of file diff --git a/src/widgets/dashboard-widget.h b/src/widgets/dashboard-widget.h new file mode 100644 index 0000000..161d6a3 --- /dev/null +++ b/src/widgets/dashboard-widget.h @@ -0,0 +1,10 @@ +#ifndef DIYA_DASHBOARD_WIDGET_H +#define DIYA_DASHBOARD_WIDGET_H + +#include "session-shell.h" +#include "base-widgets.h" + +#define DIYA_TYPE_DASHBOARD_WIDGET (diya_dashboard_widget_get_type()) +G_DECLARE_FINAL_TYPE (DiyaDashboardWidget, diya_dashboard_widget, DIYA, DASHBOARD_WIDGET, DiyaShellWindow) + +#endif \ No newline at end of file diff --git a/src/widgets/taskbar-widget.c b/src/widgets/taskbar-widget.c new file mode 100644 index 0000000..e03b501 --- /dev/null +++ b/src/widgets/taskbar-widget.c @@ -0,0 +1,128 @@ +#include "taskbar-widget.h" + + +struct _DiyaTaskbarWidget +{ + DiyaShellWindow parent; + GtkWidget *btn_toggle; + bool active_dashboard; +}; + +enum +{ + NO_PROP, + PROP_SHOW_DASHBOARD, + N_PROPERTIES +}; + +static GParamSpec *g_prop[N_PROPERTIES] = {0}; + + +G_DEFINE_TYPE (DiyaTaskbarWidget, diya_taskbar_widget, DIYA_TYPE_SHELL_WINDOW) + +static void diya_taskbar_widget_dispose(GObject* object) +{ + (void) object; + g_debug("diya_taskbar_widget_dispose"); + G_OBJECT_CLASS(diya_taskbar_widget_parent_class)->dispose(object); +} + +static void diya_taskbar_widget_init(DiyaTaskbarWidget * self) +{ + g_debug("diya_taskbar_widget_init"); + gtk_widget_init_template (GTK_WIDGET(self)); + self->active_dashboard = false; + //builder = gtk_builder_new_from_resource ("/org/gtk/exampleapp/gears-menu.ui"); + // GtkWindow* win = GTK_WINDOW(self); + + // g_object_bind_property(self->btn_toggle, "active", self->revealer, "reveal-child", G_SETTINGS_BIND_DEFAULT); + // gtk_widget_set_can_focus(self->revealer, false); + + //g_signal_connect (GTK_WINDOW(taskbar), "destroy", G_CALLBACK (on_launcher_destroy), NULL); + + // int layer shell for window + gtk_layer_init_for_window (GTK_WINDOW(self)); + // anchor window to all edges + gtk_layer_set_anchor (GTK_WINDOW(self), GTK_LAYER_SHELL_EDGE_LEFT, true); + gtk_layer_set_anchor (GTK_WINDOW(self), GTK_LAYER_SHELL_EDGE_RIGHT, true); + gtk_layer_set_anchor (GTK_WINDOW(self), GTK_LAYER_SHELL_EDGE_TOP, false); + gtk_layer_set_anchor (GTK_WINDOW(self), GTK_LAYER_SHELL_EDGE_BOTTOM, true); + gtk_layer_set_namespace(GTK_WINDOW(self), "diya-taskbar"); + // set margin on window + for (int i = 0; i < GTK_LAYER_SHELL_EDGE_ENTRY_NUMBER; i++) + gtk_layer_set_margin (GTK_WINDOW(self), i, 0); + gtk_layer_set_layer (GTK_WINDOW(self), GTK_LAYER_SHELL_LAYER_TOP); + gtk_layer_set_keyboard_mode (GTK_WINDOW(self), GTK_LAYER_SHELL_KEYBOARD_MODE_ON_DEMAND); + // the top launcher shall be exclusive + gtk_layer_auto_exclusive_zone_enable (GTK_WINDOW(self)); + + g_object_bind_property(self->btn_toggle, "active", self, "show-dashboard", G_BINDING_BIDIRECTIONAL); +} + + +static void diya_taskbar_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + DiyaTaskbarWidget * self = DIYA_TASKBAR_WIDGET(object); + + switch (property_id) + { + case PROP_SHOW_DASHBOARD: + self->active_dashboard = g_value_get_boolean(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void diya_taskbar_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + DiyaTaskbarWidget * self = DIYA_TASKBAR_WIDGET(object); + switch (property_id) + { + case PROP_SHOW_DASHBOARD: + g_value_set_boolean(value, self->active_dashboard); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +/* +static void diya_dashboard_toggle(GtkToggleButton* btn, DiyaTaskbarWidget* self) +{ + g_warning("TODDLDLDL"); + if(gtk_toggle_button_get_active(btn)) + { + gtk_layer_set_exclusive_zone(GTK_WINDOW(self), 0); + } + else + { + gtk_layer_auto_exclusive_zone_enable (GTK_WINDOW(self)); + } +} + */ + + +static void diya_taskbar_widget_class_init(DiyaTaskbarWidgetClass* class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(class); + gobject_class->dispose = diya_taskbar_widget_dispose; + gobject_class->set_property = diya_taskbar_set_property; + gobject_class->get_property = diya_taskbar_get_property; + + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),"/dev/iohub/diya/shell/taskbar.ui"); + gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), DiyaTaskbarWidget, btn_toggle); + + // gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), diya_dashboard_toggle); + + gtk_widget_class_set_css_name(GTK_WIDGET_CLASS(class), "diya-taskbar"); + //gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS (class), ExampleAppWindow, stack); + //gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), search_text_changed); + + g_prop[PROP_SHOW_DASHBOARD] = g_param_spec_boolean("show-dashboard", NULL, "Show/hide dashboard", false, G_PARAM_READWRITE); // + + g_object_class_install_properties (gobject_class, N_PROPERTIES, g_prop); +} \ No newline at end of file diff --git a/src/widgets/taskbar-widget.h b/src/widgets/taskbar-widget.h new file mode 100644 index 0000000..716d846 --- /dev/null +++ b/src/widgets/taskbar-widget.h @@ -0,0 +1,10 @@ +#ifndef DIYA_TASKBAR_WIDGET_H +#define DIYA_TASKBAR_WIDGET_H + +#include "session-shell.h" +#include "base-widgets.h" + +#define DIYA_TYPE_TASKBAR_WIDGET (diya_taskbar_widget_get_type()) +G_DECLARE_FINAL_TYPE (DiyaTaskbarWidget, diya_taskbar_widget, DIYA, TASKBAR_WIDGET, DiyaShellWindow) + +#endif \ No newline at end of file diff --git a/src/vkb/virtual-keyboard-widgets.c b/src/widgets/virtual-keyboard-widgets.c similarity index 100% rename from src/vkb/virtual-keyboard-widgets.c rename to src/widgets/virtual-keyboard-widgets.c diff --git a/src/vkb/virtual-keyboard-widgets.h b/src/widgets/virtual-keyboard-widgets.h similarity index 100% rename from src/vkb/virtual-keyboard-widgets.h rename to src/widgets/virtual-keyboard-widgets.h