diff --git a/meson.build b/meson.build
index b3a9a98..79392ef 100644
--- a/meson.build
+++ b/meson.build
@@ -82,7 +82,8 @@ dm_src = [
'src/session.c',
'src/widgets/base-widgets.c',
'src/widgets/taskbar-widget.c',
- 'src/widgets/dashboard-widget.c',
+ 'src/widgets/spotlight-widget.c',
+ 'src/widgets/launchpad-widget.c',
'src/widgets/background-widget.c',
]
diff --git a/resources/css/session-shell.css b/resources/css/session-shell.css
index ea69d37..b77e810 100644
--- a/resources/css/session-shell.css
+++ b/resources/css/session-shell.css
@@ -5,9 +5,9 @@ diya-taskbar
background-color: orange;
}
-diya-dashboard
+diya-spotlight
{
- background-color: lightgray;
+ background-color: blue;
}
diya-shell-background
diff --git a/resources/gresource-session.xml b/resources/gresource-session.xml
index 5e03a82..41bd3aa 100644
--- a/resources/gresource-session.xml
+++ b/resources/gresource-session.xml
@@ -4,8 +4,9 @@
resources/vkb/default.keymap
- resources/ui/dashboard.ui
+ resources/ui/spotlight.ui
resources/ui/taskbar.ui
+ resources/ui/launchpad.ui
resources/css/session-shell.css
diff --git a/resources/ui/dashboard.ui b/resources/ui/dashboard.ui
deleted file mode 100644
index 64aa119..0000000
--- a/resources/ui/dashboard.ui
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/resources/ui/launchpad.ui b/resources/ui/launchpad.ui
new file mode 100644
index 0000000..22f5b63
--- /dev/null
+++ b/resources/ui/launchpad.ui
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ vertical
+
+
+ 1
+ Test
+
+
+
+
+ slide-up
+ 0
+
+
+
+
+ slide-up
+ 0
+
+
+
+
+
+
diff --git a/resources/ui/spotlight.ui b/resources/ui/spotlight.ui
new file mode 100644
index 0000000..6726373
--- /dev/null
+++ b/resources/ui/spotlight.ui
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ vertical
+
+
+ vertical
+
+
+
+
+
+ 1
+ 1
+
+
+ app_list
+ Application list
+
+
+
+
+
+
+
+ search_list
+ Search
+
+
+ second stack child
+
+
+
+
+
+
+
+
+
+
+
+ stack
+
+
+
+
+
+
+
+
diff --git a/resources/ui/taskbar.ui b/resources/ui/taskbar.ui
index b365602..8b49d24 100644
--- a/resources/ui/taskbar.ui
+++ b/resources/ui/taskbar.ui
@@ -1,6 +1,6 @@
-
+
@@ -8,14 +8,6 @@
1
horizontal
-
-
- 1
- Diya
-
-
-
-
1
diff --git a/src/launcher.c b/src/launcher.c
index 9434dc3..51f7e27 100644
--- a/src/launcher.c
+++ b/src/launcher.c
@@ -2,8 +2,7 @@
#include
#include
#include "launcher.h"
-#include "widgets/dashboard-widget.h"
-#include "widgets/taskbar-widget.h"
+#include "widgets/launchpad-widget.h"
#include "widgets/background-widget.h"
#include "foreign.h"
#include "wayland.h"
@@ -11,8 +10,7 @@
struct _DiyaLauncher
{
DiyaShellObject parent;
- DiyaDashboardWidget* dashboard;
- DiyaTaskbarWidget* taskbar;
+ DiyaLaunchpadWidget* launchpad;
DiyaBackgroundWidget* background;
};
G_DEFINE_FINAL_TYPE(DiyaLauncher, diya_launcher, DIYA_TYPE_SHELL_OBJECT)
@@ -20,51 +18,23 @@ G_DEFINE_FINAL_TYPE(DiyaLauncher, diya_launcher, DIYA_TYPE_SHELL_OBJECT)
enum
{
NO_PROP,
- PROP_DASHBOARD,
- PROP_TASKBAR,
+ PROP_LAUNCHPAD,
PROP_BACKGROUND,
N_PROPERTIES
};
static GParamSpec *g_prop[N_PROPERTIES] = {0};
-/*
-static void show_windows(GtkWidget *widget,gpointer data)
-{
- (void) widget;
- g_warning("Show all windows");
- DiyaSessionShell * shell = DIYA_SESSION_SHELL(data);
- assert(shell);
- GHashTable* windows = NULL;
- g_object_get(shell, DIYA_PROP_SESSION_WINDOWS, &windows, NULL);
- assert(windows);
- GHashTableIter iter;
- gpointer handle;
- DiyaForeignWindow* window;
- g_hash_table_iter_init (&iter, windows);
- while (g_hash_table_iter_next(&iter, (gpointer) &handle, (gpointer) &window))
- {
- g_warning("unset minimized %s", diya_object_to_string(window));
- diya_foreign_window_set_state(window, DIYA_WIN_STATE_MINIMIZE, false);
- }
-}
-
-*/
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)
+ if(self->launchpad)
{
- gtk_window_destroy(GTK_WINDOW(self->dashboard));
- self->dashboard = NULL;
- }
- if(self->taskbar)
- {
- gtk_window_destroy(GTK_WINDOW(self->taskbar));
- self->taskbar = NULL;
+ gtk_window_destroy(GTK_WINDOW(self->launchpad));
+ self->launchpad = NULL;
}
if(self->background)
{
@@ -76,8 +46,7 @@ static void diya_launcher_dispose(GObject* object)
static void diya_launcher_init(DiyaLauncher * self)
{
- self->taskbar = NULL;
- self->dashboard = NULL;
+ self->launchpad = NULL;
self->background = NULL;
}
@@ -94,11 +63,8 @@ static void diya_launcher_set_property(GObject *object, guint property_id, const
switch (property_id)
{
- case PROP_DASHBOARD:
- self->dashboard = g_value_get_pointer(value);
- break;
- case PROP_TASKBAR:
- self->taskbar = g_value_get_pointer(value);
+ case PROP_LAUNCHPAD:
+ self->launchpad = g_value_get_pointer(value);
break;
case PROP_BACKGROUND:
self->background = g_value_get_pointer(value);
@@ -114,11 +80,8 @@ static void diya_launcher_get_property(GObject *object, guint property_id, GValu
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);
+ case PROP_LAUNCHPAD:
+ g_value_set_pointer(value, self->launchpad);
break;
case PROP_BACKGROUND:
g_value_set_pointer(value, self->background);
@@ -139,29 +102,29 @@ static void diya_launcher_class_init(DiyaLauncherClass *class)
gobject_class->get_property = diya_launcher_get_property;
base_class->to_string = diya_launcher_to_string;
- g_prop[PROP_DASHBOARD] = g_param_spec_pointer(DIYA_PROP_LAUNCHER_DASHBOARD, NULL, "Launcher dashboard", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
- g_prop[PROP_TASKBAR] = g_param_spec_pointer(DIYA_PROP_LAUNCHER_TASKBAR, NULL, "Launcher taskbar", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
+ g_prop[PROP_LAUNCHPAD] = g_param_spec_pointer(DIYA_PROP_LAUNCHER_LAUNCHPAD, NULL, "Launcher launchpad", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
g_prop[PROP_BACKGROUND] = g_param_spec_pointer(DIYA_PROP_LAUNCHER_BACKGROUND, NULL, "Launcher background", 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)
{
- DiyaDashboardWidget* dashboard = DIYA_DASHBOARD_WIDGET(diya_shell_window_new(DIYA_TYPE_DASHBOARD_WIDGET, shell));
- assert(dashboard);
- DiyaTaskbarWidget* taskbar = DIYA_TASKBAR_WIDGET(diya_shell_window_new(DIYA_TYPE_TASKBAR_WIDGET, shell));
- assert(taskbar);
+ DiyaLaunchpadWidget* launchpad = DIYA_LAUNCHPAD_WIDGET(diya_shell_window_new(DIYA_TYPE_LAUNCHPAD_WIDGET, shell));
+ assert(launchpad);
DiyaBackgroundWidget* background = DIYA_BACKGROUND_WIDGET(diya_shell_window_new(DIYA_TYPE_BACKGROUND_WIDGET, shell));
assert(background);
//gtk_window_set_transient_for(GTK_WINDOW(dashboard), GTK_WINDOW(taskbar));
- DiyaLauncher* self = DIYA_LAUNCHER(g_object_new (DIYA_TYPE_LAUNCHER, DIYA_PROP_LAUNCHER_DASHBOARD, dashboard, DIYA_PROP_LAUNCHER_TASKBAR, taskbar, DIYA_PROP_LAUNCHER_BACKGROUND, background, NULL));
+ DiyaLauncher* self = DIYA_LAUNCHER(g_object_new (DIYA_TYPE_LAUNCHER,
+ DIYA_PROP_LAUNCHER_LAUNCHPAD, launchpad,
+ DIYA_PROP_LAUNCHER_BACKGROUND, background,
+ NULL));
assert(self);
- g_object_bind_property(taskbar, DIYA_PROP_TASKBAR_SHOW_DASHBOARD, dashboard, DIYA_PROP_DASHBOARD_ACTIVE, G_BINDING_BIDIRECTIONAL);
- g_object_set(shell, "launchpad", self, NULL);
+ //g_object_bind_property(taskbar, DIYA_PROP_TASKBAR_SHOW_DASHBOARD, dashboard, DIYA_PROP_DASHBOARD_ACTIVE, G_BINDING_BIDIRECTIONAL);
+ g_object_set(shell,DIYA_PROP_SESSION_LAUNCHER, self, NULL);
//g_signal_connect (GTK_WINDOW(dashboard), "destroy", G_CALLBACK (on_launcher_destroy), NULL);
gtk_window_present (GTK_WINDOW (background));
- gtk_window_present (GTK_WINDOW (taskbar));
+ gtk_window_present (GTK_WINDOW (launchpad));
GtkIconTheme* theme = gtk_icon_theme_get_for_display(gdk_display_get_default());
char**icons = gtk_icon_theme_get_icon_names (theme);
@@ -172,13 +135,20 @@ void diya_session_shell_launcher_init(DiyaSessionShell * shell)
}
}
-void diya_launcher_show_dashboard(DiyaLauncher* self, gboolean value)
+void diya_launcher_show_launchpad(DiyaLauncher* self, gboolean value)
{
- g_object_set(self->dashboard, DIYA_PROP_DASHBOARD_ACTIVE, value, NULL);
+ (void) self;
+ (void) value;
+ /*
+ TODO: implement
+ */
}
-void diya_launcher_toggle_dashboard(DiyaLauncher* self)
+void diya_launcher_toggle_launchpad(DiyaLauncher* self)
{
- diya_launcher_show_dashboard(self, !diya_dashboard_is_active(self->dashboard));
+ (void) self;
+ /*
+ TODO: implement
+ */
}
\ No newline at end of file
diff --git a/src/launcher.h b/src/launcher.h
index fb17b1c..01ad70c 100644
--- a/src/launcher.h
+++ b/src/launcher.h
@@ -5,15 +5,14 @@
USE_CLASS(DiyaSessionShell);
-#define DIYA_PROP_LAUNCHER_DASHBOARD "dashboard"
-#define DIYA_PROP_LAUNCHER_TASKBAR "taskbar"
+#define DIYA_PROP_LAUNCHER_LAUNCHPAD "launchpad"
#define DIYA_PROP_LAUNCHER_BACKGROUND "background"
#define DIYA_TYPE_LAUNCHER (diya_launcher_get_type ())
G_DECLARE_FINAL_TYPE (DiyaLauncher, diya_launcher, DIYA, LAUNCHER, DiyaShellObject)
-void diya_launcher_show_dashboard(DiyaLauncher* self, gboolean value);
-void diya_launcher_toggle_dashboard(DiyaLauncher* self);
+void diya_launcher_show_launchpad(DiyaLauncher* self, gboolean value);
+void diya_launcher_toggle_launchpad(DiyaLauncher* self);
void diya_session_shell_launcher_init(DiyaSessionShell * shell);
diff --git a/src/session-shell.c b/src/session-shell.c
index 9c3de39..1da6824 100644
--- a/src/session-shell.c
+++ b/src/session-shell.c
@@ -103,11 +103,11 @@ static void diya_session_on_key_pressed(DiyaShell* shell, struct xkb_keymap *xkb
switch(sym)
{
case XKB_KEY_Escape:
- diya_launcher_show_dashboard(self->launcher, false);
+ diya_launcher_show_launchpad(self->launcher, false);
break;
case XKB_KEY_space:
if(xkb_state_mod_name_is_active(xkb_state, XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE)) {
- diya_launcher_toggle_dashboard(self->launcher);
+ diya_launcher_toggle_launchpad(self->launcher);
}
default:
break;
diff --git a/src/widgets/base-widgets.c b/src/widgets/base-widgets.c
index 0b1001b..d420efa 100644
--- a/src/widgets/base-widgets.c
+++ b/src/widgets/base-widgets.c
@@ -9,8 +9,8 @@
enum
{
- SW_NO_PROP,
- SW_SHELL,
+ NO_PROP,
+ PROP_SHELL,
SW_N_PROPERTIES
};
@@ -36,7 +36,7 @@ static void diya_shell_window_set_property(GObject *object, guint property_id, c
switch (property_id)
{
- case SW_SHELL:
+ case PROP_SHELL:
priv->shell = g_value_get_pointer(value);
break;
default:
@@ -51,7 +51,7 @@ static void diya_shell_window_get_property(GObject *object, guint property_id, G
DiyaShellWindowPrivate* priv = diya_shell_window_get_instance_private(self);
switch (property_id)
{
- case SW_SHELL:
+ case PROP_SHELL:
g_value_set_pointer(value, priv->shell);
break;
default:
@@ -76,12 +76,11 @@ static void diya_shell_window_class_init(DiyaShellWindowClass *class)
class->setup = NULL;
- g_sw_prop[SW_SHELL] = g_param_spec_pointer(DIYA_PROP_SHELL, NULL, "Reference to global shell", G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY); //
+ g_sw_prop[PROP_SHELL] = g_param_spec_pointer(DIYA_PROP_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);
}
-
DiyaShellWindow* diya_shell_window_new(GType window_type, gpointer data)
{
DiyaShell* shell = data;
@@ -128,4 +127,59 @@ void diya_shell_window_enable_focus_tracking(DiyaShellWindow* window)
g_signal_connect(controller, "enter", G_CALLBACK(diya_shell_window_focus_enter), window);
g_signal_connect(controller, "leave", G_CALLBACK(diya_shell_window_focus_leave), window);
gtk_widget_add_controller(GTK_WIDGET(window), GTK_EVENT_CONTROLLER(controller));
+}
+
+/**
+ * @brief ShellWidget implementation
+ *
+ */
+
+
+typedef struct _DiyaShellWidgetPrivate
+{
+ GtkBox parent;
+ DiyaShell * shell;
+} DiyaShellWidgetPrivate;
+G_DEFINE_TYPE_WITH_PRIVATE(DiyaShellWidget, diya_shell_widget, GTK_TYPE_BOX)
+
+static void diya_shell_widget_dispose(GObject* object)
+{
+ g_debug("diya_shell_widget_dispose");
+ G_OBJECT_CLASS(diya_shell_widget_parent_class)->dispose(object);
+}
+
+
+static void diya_shell_widget_init(DiyaShellWidget *self)
+{
+ DiyaShellWidgetPrivate* priv = diya_shell_widget_get_instance_private(self);
+ priv->shell = NULL;
+}
+
+static void diya_shell_widget_class_init(DiyaShellWidgetClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(class);
+ gobject_class->dispose = diya_shell_widget_dispose;
+ class->setup = NULL;
+}
+
+
+DiyaShellWidget* diya_shell_widget_new(GType widget_type, gpointer data)
+{
+ DiyaShell* shell = data;
+ assert(shell);
+ DiyaShellWidget* self = DIYA_SHELL_WIDGET(g_object_new (widget_type, NULL));
+ DiyaShellWidgetPrivate* priv = diya_shell_widget_get_instance_private(self);
+ priv->shell = shell;
+ DiyaShellWidgetClass *class = DIYA_SHELL_WIDGET_GET_CLASS(self);
+ if(class->setup)
+ {
+ class->setup(self);
+ }
+ return self;
+}
+
+gpointer diya_shell_widget_get_shell(DiyaShellWidget* self)
+{
+ DiyaShellWidgetPrivate* priv = diya_shell_widget_get_instance_private(self);
+ return priv->shell;
}
\ No newline at end of file
diff --git a/src/widgets/base-widgets.h b/src/widgets/base-widgets.h
index 74757d6..cdb0714 100644
--- a/src/widgets/base-widgets.h
+++ b/src/widgets/base-widgets.h
@@ -15,4 +15,18 @@ struct _DiyaShellWindowClass
gpointer diya_shell_window_get_shell(DiyaShellWindow* self);
DiyaShellWindow* diya_shell_window_new(GType window_type, gpointer shell);
void diya_shell_window_enable_focus_tracking(DiyaShellWindow* window);
+
+
+
+#define DIYA_TYPE_SHELL_WIDGET (diya_shell_widget_get_type())
+G_DECLARE_DERIVABLE_TYPE(DiyaShellWidget, diya_shell_widget, DIYA, SHELL_WIDGET, GtkBox)
+
+struct _DiyaShellWidgetClass
+{
+ GtkBoxClass parent_class;
+ void (*setup)(DiyaShellWidget* self);
+};
+
+gpointer diya_shell_widget_get_shell(DiyaShellWidget* self);
+DiyaShellWidget* diya_shell_widget_new(GType widget_type, gpointer data);
#endif
\ No newline at end of file
diff --git a/src/widgets/dashboard-widget.c b/src/widgets/dashboard-widget.c
deleted file mode 100644
index 8348881..0000000
--- a/src/widgets/dashboard-widget.c
+++ /dev/null
@@ -1,355 +0,0 @@
-#include "dashboard-widget.h"
-
-/**
- * Implementation of list model
- *
- */
-struct _DiyaDashboardListModel
-{
- GObject parent_instance;
- GList *appinfos;
-};
-
-static guint diya_dashboard_list_model_get_n_items(GListModel *list)
-{
- DiyaDashboardListModel *self = DIYA_DASHBOARD_LIST_MODEL(list);
- return g_list_length(self->appinfos);
-}
-
-static gpointer diya_dashboard_list_model_get_item(GListModel *list, guint position)
-{
- DiyaDashboardListModel *self = DIYA_DASHBOARD_LIST_MODEL(list);
- if(self->appinfos == NULL)
- {
- return NULL;
- }
- if(position >= g_list_length(self->appinfos))
- {
- return NULL;
- }
- return g_object_ref(g_list_nth_data(self->appinfos, position));
-}
-
-static GType diya_dashboard_list_model_get_item_type(GListModel *list)
-{
- (void)list; // Unused parameter
- return G_TYPE_APP_INFO;
-}
-
-static void diya_dashboard_list_model_interface_init(GListModelInterface *iface)
-{
- iface->get_n_items = diya_dashboard_list_model_get_n_items;
- iface->get_item = diya_dashboard_list_model_get_item;
- iface->get_item_type = diya_dashboard_list_model_get_item_type;
-}
-
-G_DEFINE_TYPE_WITH_CODE(DiyaDashboardListModel, diya_dashboard_list_model, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL, diya_dashboard_list_model_interface_init))
-
-static void diya_dashboard_list_model_finalize(GObject *object)
-{
- g_debug("diya_dashboard_list_model_finalize");
- DiyaDashboardListModel *self = DIYA_DASHBOARD_LIST_MODEL(object);
- g_list_free_full(self->appinfos, g_object_unref);
- G_OBJECT_CLASS(diya_dashboard_list_model_parent_class)->finalize(object);
-}
-
-static void diya_dashboard_list_model_dispose(GObject *object)
-{
- (void)object;
- g_debug("diya_dashboard_list_model_dispose");
- G_OBJECT_CLASS(diya_dashboard_list_model_parent_class)->dispose(object);
-}
-
-static void diya_dashboard_list_model_init(DiyaDashboardListModel *self)
-{
- self->appinfos = NULL;
-}
-
-static void diya_dashboard_list_model_class_init(DiyaDashboardListModelClass *class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS(class);
- gobject_class->finalize = diya_dashboard_list_model_finalize;
- gobject_class->dispose = diya_dashboard_list_model_dispose;
-}
-
-void diya_dashboard_list_model_append(DiyaDashboardListModel *self, GAppInfo *info)
-{
- self->appinfos = g_list_append(self->appinfos, g_object_ref(info));
- // self->appinfos = g_list_reverse(self->appinfos);
- g_list_model_items_changed(G_LIST_MODEL(self), g_list_length(self->appinfos) - 1, 0, 1);
-}
-
-static gint diya_dashboard_app_info_cmp(GAppInfo *a, GAppInfo *b)
-{
- return !g_app_info_equal(a, b);
-}
-
-gboolean diya_dashboard_list_model_contain(DiyaDashboardListModel *self, GAppInfo *info)
-{
- GList *found = NULL;
- found = g_list_find_custom(self->appinfos, info, (GCompareFunc)diya_dashboard_app_info_cmp);
- return found != NULL;
-}
-
-/**
- * Implement of Dashboard widget
- *
- */
-
-struct _DiyaDashboardWidget
-{
- DiyaShellWindow parent;
- GtkWidget *revealer;
- GtkWidget *search_entry;
- GtkWidget *app_list_box;
- DiyaDashboardListModel *list_model;
- GtkSortListModel *sort_model;
- GtkFilterListModel *proxy_model;
- GtkSorter *sorter;
- GtkFilter *filter;
- 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)
-{
- DiyaDashboardWidget *self = DIYA_DASHBOARD_WIDGET(object);
- g_debug("diya_dashboard_widget_dispose");
- if (self->proxy_model)
- {
- g_object_unref(self->proxy_model);
- }
- // verify if the list model + sorter is also unref
- G_OBJECT_CLASS(diya_dashboard_widget_parent_class)->dispose(object);
-}
-
-static void diya_dashboard_app_launch(GtkFlowBox *box, GtkFlowBoxChild *child, gpointer user_data)
-{
- (void)box; // Unused parameter
- DiyaDashboardWidget *self = DIYA_DASHBOARD_WIDGET(user_data);
- int current_index = gtk_flow_box_child_get_index(child);
- if (current_index < 0)
- {
- g_warning("Invalid child index: %d", current_index);
- return;
- }
- GAppInfo *app = G_APP_INFO(g_list_model_get_item(G_LIST_MODEL(self->proxy_model), current_index));
- assert(app);
- diya_shell_launch(diya_shell_window_get_shell(DIYA_SHELL_WINDOW(self)), app);
- g_object_set(self, DIYA_PROP_DASHBOARD_ACTIVE, false, NULL);
- g_object_unref(app);
-}
-static void diya_dashboard_app_icon_clicked(GtkWidget *widget, gpointer user_data)
-{
- // relay signal to the GTK_FLOW_BOX_CHILD parent
- g_signal_emit_by_name(gtk_widget_get_parent(widget), "activate", user_data);
-}
-
-static GtkWidget *diya_dashboard_create_app_icon_widget(void *item, void *user_data)
-{
- (void)user_data; // Unused parameter
- GAppInfo *app_info = G_APP_INFO(item);
- const gchar *name = g_app_info_get_display_name(app_info);
- GIcon *icon = g_app_info_get_icon(app_info);
- GtkWidget *widget = gtk_button_new_with_label(name);
- if (icon)
- {
- g_debug("app_info %s has icon %s", name, g_icon_to_string(icon));
- // gtk_button_set_icon_name(GTK_BUTTON(widget), g_icon_to_string(icon));
- }
- g_signal_connect(widget, "clicked", G_CALLBACK(diya_dashboard_app_icon_clicked), user_data);
- return widget;
-}
-
-static int diya_dashboard_app_info_sort_cmp(GAppInfo *a, GAppInfo *b, gpointer user_data)
-{
- (void)user_data; // Unused parameter
- const gchar *name_a = g_app_info_get_display_name(a);
- const gchar *name_b = g_app_info_get_display_name(b);
- return g_strcmp0(name_a, name_b);
-}
-
-static gboolean diya_app_info_filter_func(GAppInfo *app_info, gpointer user_data)
-{
- DiyaDashboardWidget *self = DIYA_DASHBOARD_WIDGET(user_data);
- gchar *text = g_utf8_strdown(gtk_editable_get_text(GTK_EDITABLE(self->search_entry)), -1);
- if (strlen(text) == 0)
- {
- g_free(text);
- return true;
- }
- gchar *name = g_utf8_strdown(g_app_info_get_display_name(app_info), -1);
- if(!name)
- {
- g_free(text);
- return false;
- }
- gboolean result = g_str_has_prefix(name, text);
- g_free(text);
- g_free(name);
- return result;
-}
-
-static void diya_dashboard_search_text_changed(GtkEntry *entry, DiyaDashboardWidget *self)
-{
- (void)entry; // Unused parameter
- gtk_filter_changed(self->filter, GTK_FILTER_CHANGE_DIFFERENT);
-}
-
-static void diya_dashboard_widget_init(DiyaDashboardWidget *self)
-{
- g_debug("diya_dashboard_widget_init");
- gtk_widget_init_template(GTK_WIDGET(self));
- self->active = false;
-
- // 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);
-
- // event controller
- // GtkEventController *event_controller = gtk_event_controller_key_new();
- // g_signal_connect(event_controller, "key-pressed", G_CALLBACK(on_diya_dashboard_key_press), self);
- // gtk_widget_add_controller(GTK_WIDGET(self), event_controller);
- self->list_model = g_object_new(DIYA_TYPE_DASHBOARD_LIST_MODEL, NULL);
- self->sorter = GTK_SORTER(gtk_custom_sorter_new((GCompareDataFunc)diya_dashboard_app_info_sort_cmp, NULL, NULL));
- self->sort_model = gtk_sort_list_model_new(G_LIST_MODEL(self->list_model), self->sorter);
- self->filter = GTK_FILTER(gtk_custom_filter_new((GtkCustomFilterFunc)diya_app_info_filter_func, self, NULL));
- self->proxy_model = gtk_filter_list_model_new(G_LIST_MODEL(self->sort_model), self->filter);
- gtk_flow_box_bind_model(GTK_FLOW_BOX(self->app_list_box), G_LIST_MODEL(self->proxy_model), diya_dashboard_create_app_icon_widget, self, NULL);
-
- gtk_flow_box_set_selection_mode(GTK_FLOW_BOX(self->app_list_box), GTK_SELECTION_SINGLE);
- gtk_flow_box_set_activate_on_single_click(GTK_FLOW_BOX(self->app_list_box), true);
-
- diya_shell_window_enable_focus_tracking(DIYA_SHELL_WINDOW(self));
-}
-
-static void diya_dashboard_show(DiyaDashboardWidget *self)
-{
- 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));
- GList *apps = g_app_info_get_all();
- GList *l;
- for (l = apps; l != NULL; l = l->next)
- {
- GAppInfo *info = l->data;
- if (diya_dashboard_list_model_contain(self->list_model, info))
- {
- continue;
- }
- g_debug("add AppInfo %s", g_app_info_get_id(info));
- diya_dashboard_list_model_append(self->list_model, info);
- }
- g_list_free_full(apps, g_object_unref);
- gtk_sorter_changed(self->sorter, GTK_SORTER_CHANGE_INVERTED);
-}
-
-static void diya_dashboard_hide(DiyaDashboardWidget *self)
-{
- gtk_revealer_set_reveal_child(GTK_REVEALER(self->revealer), false);
- gtk_widget_set_visible(GTK_WIDGET(self), false);
-}
-
-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:
- {
- gboolean active = g_value_get_boolean(value);
- if (self->active == active)
- {
- return;
- }
- self->active = active;
- if (self->active)
- {
- diya_dashboard_show(self);
- }
- else
- {
- diya_dashboard_hide(self);
- }
- 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;
-
- // DiyaShellWindowClass* base_class = DIYA_SHELL_WINDOW_CLASS(class);
- // base_class->setup = diya_dashboard_widget_setup;
-
- gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), "/dev/iohub/diya/shell/ui/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_child(GTK_WIDGET_CLASS(class), DiyaDashboardWidget, app_list_box);
-
- gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), diya_dashboard_app_launch);
- gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), diya_dashboard_search_text_changed);
-
- 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(DIYA_PROP_DASHBOARD_ACTIVE, NULL, "Active the dashboard", false, G_PARAM_READWRITE); //
-
- g_object_class_install_properties(gobject_class, N_PROPERTIES, g_prop);
-}
-
-gboolean diya_dashboard_is_active(DiyaDashboardWidget *self)
-{
- return self->active;
-}
\ No newline at end of file
diff --git a/src/widgets/dashboard-widget.h b/src/widgets/dashboard-widget.h
deleted file mode 100644
index 4410e97..0000000
--- a/src/widgets/dashboard-widget.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef DIYA_DASHBOARD_WIDGET_H
-#define DIYA_DASHBOARD_WIDGET_H
-
-#include "session-shell.h"
-#include "base-widgets.h"
-
-#define DIYA_PROP_DASHBOARD_ACTIVE "active"
-
-#define DIYA_TYPE_DASHBOARD_WIDGET (diya_dashboard_widget_get_type())
-G_DECLARE_FINAL_TYPE (DiyaDashboardWidget, diya_dashboard_widget, DIYA, DASHBOARD_WIDGET, DiyaShellWindow)
-
-#define DIYA_TYPE_DASHBOARD_LIST_MODEL (diya_dashboard_list_model_get_type())
-G_DECLARE_FINAL_TYPE (DiyaDashboardListModel, diya_dashboard_list_model, DIYA, DASHBOARD_LIST_MODEL, GObject)
-
-gboolean diya_dashboard_is_active(DiyaDashboardWidget* self);
-
-#endif
\ No newline at end of file
diff --git a/src/widgets/launchpad-widget.c b/src/widgets/launchpad-widget.c
new file mode 100644
index 0000000..37edf92
--- /dev/null
+++ b/src/widgets/launchpad-widget.c
@@ -0,0 +1,149 @@
+#include "launchpad-widget.h"
+#include "spotlight-widget.h"
+#include "taskbar-widget.h"
+
+/**
+ * Implement of Launchpad widget
+ *
+ */
+
+struct _DiyaLaunchpadWidget
+{
+ DiyaShellWindow parent;
+ GtkWidget *spotlight_revealer;
+ GtkWidget *taskbar_revealer;
+ GtkWidget *spotlight;
+ GtkWidget *taskbar;
+ GtkWidget *btn_handle;
+};
+
+enum
+{
+ NO_PROP,
+ N_PROPERTIES
+};
+
+static GParamSpec *g_prop[N_PROPERTIES] = {0};
+
+G_DEFINE_TYPE(DiyaLaunchpadWidget, diya_launchpad_widget, DIYA_TYPE_SHELL_WINDOW)
+
+static void diya_launchpad_widget_dispose(GObject *object)
+{
+ // DiyaLaunchpadWidget *self = DIYA_LAUNCHPAD_WIDGET(object);
+ g_debug("diya_launchpad_widget_dispose");
+ // verify if the list model + sorter is also unref
+ G_OBJECT_CLASS(diya_launchpad_widget_parent_class)->dispose(object);
+}
+
+
+static void diya_dashboard_btn_handle_clicked(GtkWidget *widget, gpointer user_data)
+{
+ (void)widget;
+ g_debug("diya_dashboard_btn_handle_clicked");
+ DiyaLaunchpadWidget *self = user_data;
+ DiyaSessionShell *shell = DIYA_SESSION_SHELL(diya_shell_window_get_shell(DIYA_SHELL_WINDOW(self)));
+ g_return_if_fail(DIYA_IS_SESSION_SHELL(shell));
+ gtk_revealer_set_reveal_child(GTK_REVEALER(self->spotlight_revealer), true);
+ gtk_revealer_set_reveal_child(GTK_REVEALER(self->taskbar_revealer), true);
+}
+
+
+static void diya_launchpad_widget_init(DiyaLaunchpadWidget *self)
+{
+ g_debug("diya_launchpad_widget_init");
+ gtk_widget_init_template(GTK_WIDGET(self));
+ self->spotlight = NULL;
+ self->taskbar = 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-launchpad");
+ // 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(launchpad),NAMESPACE);
+ // gtk_window_set_default_size(GTK_WINDOW(launchpad), 48, 48);
+
+ g_signal_connect(self->btn_handle, "clicked", G_CALLBACK(diya_dashboard_btn_handle_clicked), self);
+
+ // event controller
+ // GtkEventController *event_controller = gtk_event_controller_key_new();
+ // g_signal_connect(event_controller, "key-pressed", G_CALLBACK(on_diya_launchpad_key_press), self);
+ // gtk_widget_add_controller(GTK_WIDGET(self), event_controller);
+ diya_shell_window_enable_focus_tracking(DIYA_SHELL_WINDOW(self));
+}
+
+
+static void diya_launchpad_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ DiyaLaunchpadWidget *self = DIYA_LAUNCHPAD_WIDGET(object);
+ (void) self;
+ (void) value;
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void diya_launchpad_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ DiyaLaunchpadWidget *self = DIYA_LAUNCHPAD_WIDGET(object);
+ (void) self;
+ (void) value;
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void diya_launchpad_widget_setup(DiyaShellWindow* win)
+{
+ g_debug("diya_launchpad_widget_setup");
+ DiyaLaunchpadWidget *self = DIYA_LAUNCHPAD_WIDGET(win);
+ g_debug("spot light creation");
+ self->spotlight = GTK_WIDGET(diya_shell_widget_new(DIYA_TYPE_SPOTLIGHT_WIDGET, diya_shell_window_get_shell(win)));
+ g_debug("taskbar creation");
+ self->taskbar = GTK_WIDGET(diya_shell_widget_new(DIYA_TYPE_TASKBAR_WIDGET, diya_shell_window_get_shell(win)));
+
+ gtk_revealer_set_child(GTK_REVEALER(self->spotlight_revealer), GTK_WIDGET(self->spotlight));
+ gtk_revealer_set_child(GTK_REVEALER(self->taskbar_revealer), GTK_WIDGET(self->taskbar));
+
+ gtk_revealer_set_reveal_child(GTK_REVEALER(self->spotlight_revealer), false);
+ gtk_revealer_set_reveal_child(GTK_REVEALER(self->taskbar_revealer), false);
+}
+
+static void diya_launchpad_widget_class_init(DiyaLaunchpadWidgetClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(class);
+ gobject_class->dispose = diya_launchpad_widget_dispose;
+ gobject_class->set_property =diya_launchpad_set_property;
+ gobject_class->get_property =diya_launchpad_get_property;
+
+ DiyaShellWindowClass* base_class = DIYA_SHELL_WINDOW_CLASS(class);
+ base_class->setup = diya_launchpad_widget_setup;
+
+ gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), "/dev/iohub/diya/shell/ui/launchpad.ui");
+ gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), DiyaLaunchpadWidget, taskbar_revealer);
+ gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), DiyaLaunchpadWidget, spotlight_revealer);
+ gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), DiyaLaunchpadWidget, btn_handle);
+
+ gtk_widget_class_set_css_name(GTK_WIDGET_CLASS(class), "diya-launchpad");
+ // 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);
+
+ // TODO g_object_class_install_properties(gobject_class, N_PROPERTIES, g_prop);
+}
\ No newline at end of file
diff --git a/src/widgets/launchpad-widget.h b/src/widgets/launchpad-widget.h
new file mode 100644
index 0000000..1eb1642
--- /dev/null
+++ b/src/widgets/launchpad-widget.h
@@ -0,0 +1,10 @@
+#ifndef DIYA_LAUNCHPAD_WIDGET_H
+#define DIYA_LAUNCHPAD_WIDGET_H
+
+#include "session-shell.h"
+#include "base-widgets.h"
+
+#define DIYA_TYPE_LAUNCHPAD_WIDGET (diya_launchpad_widget_get_type())
+G_DECLARE_FINAL_TYPE (DiyaLaunchpadWidget, diya_launchpad_widget, DIYA, LAUNCHPAD_WIDGET, DiyaShellWindow)
+
+#endif
\ No newline at end of file
diff --git a/src/widgets/spotlight-widget.c b/src/widgets/spotlight-widget.c
new file mode 100644
index 0000000..44663ea
--- /dev/null
+++ b/src/widgets/spotlight-widget.c
@@ -0,0 +1,304 @@
+#include "spotlight-widget.h"
+
+/**
+ * Implementation of list model
+ *
+ */
+struct _DiyaSpotlightListModel
+{
+ GObject parent_instance;
+ GList *appinfos;
+};
+
+static guint diya_spotlight_list_model_get_n_items(GListModel *list)
+{
+ DiyaSpotlightListModel *self = DIYA_SPOTLIGHT_LIST_MODEL(list);
+ return g_list_length(self->appinfos);
+}
+
+static gpointer diya_spotlight_list_model_get_item(GListModel *list, guint position)
+{
+ DiyaSpotlightListModel *self = DIYA_SPOTLIGHT_LIST_MODEL(list);
+ if(self->appinfos == NULL)
+ {
+ return NULL;
+ }
+ if(position >= g_list_length(self->appinfos))
+ {
+ return NULL;
+ }
+ return g_object_ref(g_list_nth_data(self->appinfos, position));
+}
+
+static GType diya_spotlight_list_model_get_item_type(GListModel *list)
+{
+ (void)list; // Unused parameter
+ return G_TYPE_APP_INFO;
+}
+
+static void diya_spotlight_list_model_interface_init(GListModelInterface *iface)
+{
+ iface->get_n_items = diya_spotlight_list_model_get_n_items;
+ iface->get_item = diya_spotlight_list_model_get_item;
+ iface->get_item_type = diya_spotlight_list_model_get_item_type;
+}
+
+G_DEFINE_TYPE_WITH_CODE(DiyaSpotlightListModel, diya_spotlight_list_model, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL, diya_spotlight_list_model_interface_init))
+
+static void diya_spotlight_list_model_finalize(GObject *object)
+{
+ g_debug("diya_spotlight_list_model_finalize");
+ DiyaSpotlightListModel *self = DIYA_SPOTLIGHT_LIST_MODEL(object);
+ g_list_free_full(self->appinfos, g_object_unref);
+ G_OBJECT_CLASS(diya_spotlight_list_model_parent_class)->finalize(object);
+}
+
+static void diya_spotlight_list_model_dispose(GObject *object)
+{
+ (void)object;
+ g_debug("diya_spotlight_list_model_dispose");
+ G_OBJECT_CLASS(diya_spotlight_list_model_parent_class)->dispose(object);
+}
+
+static void diya_spotlight_list_model_init(DiyaSpotlightListModel *self)
+{
+ self->appinfos = NULL;
+}
+
+static void diya_spotlight_list_model_class_init(DiyaSpotlightListModelClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(class);
+ gobject_class->finalize = diya_spotlight_list_model_finalize;
+ gobject_class->dispose = diya_spotlight_list_model_dispose;
+}
+
+void diya_spotlight_list_model_append(DiyaSpotlightListModel *self, GAppInfo *info)
+{
+ self->appinfos = g_list_append(self->appinfos, g_object_ref(info));
+ // self->appinfos = g_list_reverse(self->appinfos);
+ g_list_model_items_changed(G_LIST_MODEL(self), g_list_length(self->appinfos) - 1, 0, 1);
+}
+
+static gint diya_spotlight_app_info_cmp(GAppInfo *a, GAppInfo *b)
+{
+ return !g_app_info_equal(a, b);
+}
+
+gboolean diya_spotlight_list_model_contain(DiyaSpotlightListModel *self, GAppInfo *info)
+{
+ GList *found = NULL;
+ found = g_list_find_custom(self->appinfos, info, (GCompareFunc)diya_spotlight_app_info_cmp);
+ return found != NULL;
+}
+
+/**
+ * Implement of Spotlight widget
+ *
+ */
+
+struct _DiyaSpotlightWidget
+{
+ DiyaShellWidget parent;
+ GtkWidget *search_entry;
+ GtkWidget *app_list_box;
+ DiyaSpotlightListModel *list_model;
+ GtkSortListModel *sort_model;
+ GtkFilterListModel *proxy_model;
+ GtkSorter *sorter;
+ GtkFilter *filter;
+};
+
+enum
+{
+ NO_PROP,
+ N_PROPERTIES
+};
+
+static GParamSpec *g_prop[N_PROPERTIES] = {0};
+
+G_DEFINE_TYPE(DiyaSpotlightWidget, diya_spotlight_widget, DIYA_TYPE_SHELL_WIDGET)
+
+static void diya_spotlight_widget_dispose(GObject *object)
+{
+ DiyaSpotlightWidget *self = DIYA_SPOTLIGHT_WIDGET(object);
+ g_debug("diya_spotlight_widget_dispose");
+ if (self->proxy_model)
+ {
+ g_object_unref(self->proxy_model);
+ }
+ // verify if the list model + sorter is also unref
+ G_OBJECT_CLASS(diya_spotlight_widget_parent_class)->dispose(object);
+}
+
+static void diya_spotlight_app_launch(GtkFlowBox *box, GtkFlowBoxChild *child, gpointer user_data)
+{
+ (void)box; // Unused parameter
+ DiyaSpotlightWidget *self = DIYA_SPOTLIGHT_WIDGET(user_data);
+ int current_index = gtk_flow_box_child_get_index(child);
+ if (current_index < 0)
+ {
+ g_warning("Invalid child index: %d", current_index);
+ return;
+ }
+ GAppInfo *app = G_APP_INFO(g_list_model_get_item(G_LIST_MODEL(self->proxy_model), current_index));
+ assert(app);
+ diya_shell_launch(diya_shell_widget_get_shell(DIYA_SHELL_WIDGET(self)), app);
+ //g_object_set(self, DIYA_PROP_SPOTLIGHT_ACTIVE, false, NULL);
+ g_object_unref(app);
+}
+static void diya_spotlight_app_icon_clicked(GtkWidget *widget, gpointer user_data)
+{
+ // relay signal to the GTK_FLOW_BOX_CHILD parent
+ g_signal_emit_by_name(gtk_widget_get_parent(widget), "activate", user_data);
+}
+
+static GtkWidget *diya_spotlight_create_app_icon_widget(void *item, void *user_data)
+{
+ (void)user_data; // Unused parameter
+ GAppInfo *app_info = G_APP_INFO(item);
+ const gchar *name = g_app_info_get_display_name(app_info);
+ GIcon *icon = g_app_info_get_icon(app_info);
+ GtkWidget *widget = gtk_button_new_with_label(name);
+ if (icon)
+ {
+ g_debug("app_info %s has icon %s", name, g_icon_to_string(icon));
+ // gtk_button_set_icon_name(GTK_BUTTON(widget), g_icon_to_string(icon));
+ }
+ g_signal_connect(widget, "clicked", G_CALLBACK(diya_spotlight_app_icon_clicked), user_data);
+ return widget;
+}
+
+static int diya_spotlight_app_info_sort_cmp(GAppInfo *a, GAppInfo *b, gpointer user_data)
+{
+ (void)user_data; // Unused parameter
+ const gchar *name_a = g_app_info_get_display_name(a);
+ const gchar *name_b = g_app_info_get_display_name(b);
+ return g_strcmp0(name_a, name_b);
+}
+
+static gboolean diya_app_info_filter_func(GAppInfo *app_info, gpointer user_data)
+{
+ DiyaSpotlightWidget *self = DIYA_SPOTLIGHT_WIDGET(user_data);
+ gchar *text = g_utf8_strdown(gtk_editable_get_text(GTK_EDITABLE(self->search_entry)), -1);
+ if (strlen(text) == 0)
+ {
+ g_free(text);
+ return true;
+ }
+ gchar *name = g_utf8_strdown(g_app_info_get_display_name(app_info), -1);
+ if(!name)
+ {
+ g_free(text);
+ return false;
+ }
+ gboolean result = g_str_has_prefix(name, text);
+ g_free(text);
+ g_free(name);
+ return result;
+}
+
+static void diya_spotlight_search_text_changed(GtkEntry *entry, DiyaSpotlightWidget *self)
+{
+ (void)entry; // Unused parameter
+ gtk_filter_changed(self->filter, GTK_FILTER_CHANGE_DIFFERENT);
+}
+
+static void diya_spotlight_widget_init(DiyaSpotlightWidget *self)
+{
+ g_debug("diya_spotlight_widget_init");
+ gtk_widget_init_template(GTK_WIDGET(self));
+
+ // event controller
+ // GtkEventController *event_controller = gtk_event_controller_key_new();
+ // g_signal_connect(event_controller, "key-pressed", G_CALLBACK(on_diya_spotlight_key_press), self);
+ // gtk_widget_add_controller(GTK_WIDGET(self), event_controller);
+ self->list_model = g_object_new(DIYA_TYPE_SPOTLIGHT_LIST_MODEL, NULL);
+ self->sorter = GTK_SORTER(gtk_custom_sorter_new((GCompareDataFunc)diya_spotlight_app_info_sort_cmp, NULL, NULL));
+ self->sort_model = gtk_sort_list_model_new(G_LIST_MODEL(self->list_model), self->sorter);
+ self->filter = GTK_FILTER(gtk_custom_filter_new((GtkCustomFilterFunc)diya_app_info_filter_func, self, NULL));
+ self->proxy_model = gtk_filter_list_model_new(G_LIST_MODEL(self->sort_model), self->filter);
+ gtk_flow_box_bind_model(GTK_FLOW_BOX(self->app_list_box), G_LIST_MODEL(self->proxy_model), diya_spotlight_create_app_icon_widget, self, NULL);
+
+ gtk_flow_box_set_selection_mode(GTK_FLOW_BOX(self->app_list_box), GTK_SELECTION_SINGLE);
+ gtk_flow_box_set_activate_on_single_click(GTK_FLOW_BOX(self->app_list_box), true);
+}
+
+static void diya_spotlight_show(DiyaSpotlightWidget *self)
+{
+ // gtk_widget_grab_focus( GTK_WIDGET(self->search_entry));
+ GList *apps = g_app_info_get_all();
+ GList *l;
+ for (l = apps; l != NULL; l = l->next)
+ {
+ GAppInfo *info = l->data;
+ if (diya_spotlight_list_model_contain(self->list_model, info))
+ {
+ continue;
+ }
+ g_debug("add AppInfo %s", g_app_info_get_id(info));
+ diya_spotlight_list_model_append(self->list_model, info);
+ }
+ g_list_free_full(apps, g_object_unref);
+ gtk_sorter_changed(self->sorter, GTK_SORTER_CHANGE_INVERTED);
+}
+
+
+static void diya_spotlight_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ DiyaSpotlightWidget *self = DIYA_SPOTLIGHT_WIDGET(object);
+ (void) self;
+ (void) value;
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+static void diya_spotlight_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ DiyaSpotlightWidget *self = DIYA_SPOTLIGHT_WIDGET(object);
+ (void) self;
+ (void) value;
+ switch (property_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+ break;
+ }
+}
+
+
+static void diya_spotlight_widget_setup(DiyaShellWidget *widget)
+{
+ g_debug("diya_taskbar_widget_setup");
+ DiyaSpotlightWidget *self = DIYA_SPOTLIGHT_WIDGET(widget);
+ // TODO use signal
+ diya_spotlight_show(self);
+}
+
+static void diya_spotlight_widget_class_init(DiyaSpotlightWidgetClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(class);
+ gobject_class->dispose = diya_spotlight_widget_dispose;
+ gobject_class->set_property = diya_spotlight_set_property;
+ gobject_class->get_property = diya_spotlight_get_property;
+
+ DiyaShellWidgetClass *widget_class = DIYA_SHELL_WIDGET_CLASS(class);
+ widget_class->setup = diya_spotlight_widget_setup;
+
+ gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), "/dev/iohub/diya/shell/ui/spotlight.ui");
+ gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), DiyaSpotlightWidget, search_entry);
+ gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), DiyaSpotlightWidget, app_list_box);
+
+ gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), diya_spotlight_app_launch);
+ gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), diya_spotlight_search_text_changed);
+
+ gtk_widget_class_set_css_name(GTK_WIDGET_CLASS(class), "diya-spotlight");
+ // 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);
+
+
+ // TODO g_object_class_install_properties(gobject_class, N_PROPERTIES, g_prop);
+}
\ No newline at end of file
diff --git a/src/widgets/spotlight-widget.h b/src/widgets/spotlight-widget.h
new file mode 100644
index 0000000..5d56644
--- /dev/null
+++ b/src/widgets/spotlight-widget.h
@@ -0,0 +1,12 @@
+#ifndef DIYA_SPOTLIGHT_WIDGET_H
+#define DIYA_SPOTLIGHT_WIDGET_H
+
+#include "session-shell.h"
+#include "base-widgets.h"
+
+#define DIYA_TYPE_SPOTLIGHT_WIDGET (diya_spotlight_widget_get_type())
+G_DECLARE_FINAL_TYPE (DiyaSpotlightWidget, diya_spotlight_widget, DIYA, SPOTLIGHT_WIDGET, DiyaShellWidget)
+
+#define DIYA_TYPE_SPOTLIGHT_LIST_MODEL (diya_spotlight_list_model_get_type())
+G_DECLARE_FINAL_TYPE (DiyaSpotlightListModel, diya_spotlight_list_model, DIYA, SPOTLIGHT_LIST_MODEL, GObject)
+#endif
\ No newline at end of file
diff --git a/src/widgets/taskbar-widget.c b/src/widgets/taskbar-widget.c
index 188d9a7..17f889c 100644
--- a/src/widgets/taskbar-widget.c
+++ b/src/widgets/taskbar-widget.c
@@ -109,9 +109,7 @@ gboolean diya_taskbar_list_model_contain(DiyaTaskbarListModel *self, DiyaForeign
struct _DiyaTaskbarWidget
{
- DiyaShellWindow parent;
- GtkWidget *btn_toggle;
- bool active_dashboard;
+ DiyaShellWidget parent;
GtkWidget *apps_list;
GtkSingleSelection *proxy_model;
DiyaTaskbarListModel *model;
@@ -125,13 +123,12 @@ struct _DiyaTaskbarWidget
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)
+G_DEFINE_TYPE(DiyaTaskbarWidget, diya_taskbar_widget, DIYA_TYPE_SHELL_WIDGET)
static void diya_taskbar_widget_dispose(GObject *object)
{
@@ -276,7 +273,7 @@ static void diya_taskbar_list_model_selection_changed_cb(GtkSelectionModel *mode
(void)user_data;
(void)position;
DiyaForeignWindow *win = gtk_single_selection_get_selected_item(GTK_SINGLE_SELECTION(model));
- DiyaTaskbarWidget *self = DIYA_TASKBAR_WIDGET(user_data);
+ //DiyaTaskbarWidget *self = DIYA_TASKBAR_WIDGET(user_data);
if (gtk_selection_model_is_selected(GTK_SELECTION_MODEL(model), position))
{
g_debug("Activating window: %s", diya_object_to_string(win));
@@ -285,10 +282,6 @@ static void diya_taskbar_list_model_selection_changed_cb(GtkSelectionModel *mode
{
diya_foreign_window_set_state(win, DIYA_WIN_STATE_MINIMIZE, false);
}
- if (self->active_dashboard)
- {
- g_object_set(self, DIYA_PROP_TASKBAR_SHOW_DASHBOARD, !self->active_dashboard, NULL);
- }
diya_foreign_window_set_state(win, DIYA_WIN_STATE_FOCUS, true);
}
else
@@ -300,52 +293,22 @@ static void diya_taskbar_list_model_selection_changed_cb(GtkSelectionModel *mode
static void diya_dashboard_btn_test_clicked(GtkWidget *widget, gpointer user_data)
{
(void)widget;
- g_return_if_fail(DIYA_IS_SHELL_WINDOW(user_data));
- DiyaShellWindow *self = user_data;
- DiyaSessionShell *shell = DIYA_SESSION_SHELL(diya_shell_window_get_shell(self));
+ g_return_if_fail(DIYA_IS_SHELL_WIDGET(user_data));
+ DiyaShellWidget *self = user_data;
+ DiyaSessionShell *shell = DIYA_SESSION_SHELL(diya_shell_widget_get_shell(self));
g_return_if_fail(DIYA_IS_SESSION_SHELL(shell));
diya_shell_lock(DIYA_SHELL(shell));
// TODO remove
}
-static void diya_taskbar_widget_applist_pressed(GtkGestureClick *gesture, int n_press, double x, double y, gpointer user_data)
-{
- (void)gesture;
-
- DiyaTaskbarWidget *self = DIYA_TASKBAR_WIDGET(user_data);
- g_debug("APP LIST PRESSED (%f, %f): %d", x, y, n_press);
- GtkWidget *target = self->apps_list;
- if (target)
- {
- g_debug("PICKED WIDGET: %s", gtk_widget_get_name(target));
- GtkWidget *child = gtk_widget_get_first_child(target);
- while (child != NULL) {
- g_debug("Child widget: %s (ListItem %d)", gtk_widget_get_name(child), GTK_IS_LIST_ITEM(child));
-
- int width, height;
- graphene_point_t point;
- graphene_point_t local_point = {0, 0};
- // Get size
- width = gtk_widget_get_width(child);
- height = gtk_widget_get_height(child);
- // Get position relative to parent
- if(gtk_widget_compute_point(child, self->apps_list, &local_point, &point))
- {
- g_debug("Position: (%f, %f), Size: %d %d, mouse (%f, %f)", point.x, point.y, width, height, x, y);
- }
- child = gtk_widget_get_next_sibling(child);
- }
- }
-}
-
-static void diya_shell_window_enter(DiyaShell *shell, DiyaShellWindow *window, gpointer user_data)
+static void diya_shell_window_enter(DiyaShell *shell, DiyaShellWidget *window, gpointer user_data)
{
(void) shell;
(void) user_data;
g_debug("Shell Window Enter: %s", gtk_widget_get_name(GTK_WIDGET(window)));
}
-static void diya_shell_window_leave(DiyaShell *shell, DiyaShellWindow *window, gpointer user_data)
+static void diya_shell_window_leave(DiyaShell *shell, DiyaShellWidget *window, gpointer user_data)
{
(void) shell;
(void) user_data;
@@ -355,26 +318,9 @@ static void diya_shell_window_leave(DiyaShell *shell, DiyaShellWindow *window, g
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;
- self->z_indices = 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, DIYA_PROP_TASKBAR_SHOW_DASHBOARD, G_BINDING_BIDIRECTIONAL);
+ gtk_widget_init_template(GTK_WIDGET(self));
+ self->z_indices = NULL;
self->factory = gtk_signal_list_item_factory_new();
g_signal_connect(self->factory, "setup", G_CALLBACK(diya_taskbar_setup_apps_list_cb), NULL);
@@ -390,26 +336,16 @@ static void diya_taskbar_widget_init(DiyaTaskbarWidget *self)
self->selection_changed_sig_id = g_signal_connect(GTK_SELECTION_MODEL(self->proxy_model), "selection-changed", G_CALLBACK(diya_taskbar_list_model_selection_changed_cb), self);
- // event handling
- diya_shell_window_enable_focus_tracking(DIYA_SHELL_WINDOW(self));
-
- GtkGesture *g_controller = gtk_gesture_click_new();
- g_signal_connect(g_controller, "pressed", G_CALLBACK(diya_taskbar_widget_applist_pressed), self);
- //g_signal_connect(controller, "released", G_CALLBACK(diya_vkb_button_event), DIYA_SIGNAL_VKB_KEY_RELEASED);
- gtk_widget_add_controller(GTK_WIDGET(self->apps_list), GTK_EVENT_CONTROLLER(g_controller));
-
g_signal_connect(self->btn_test, "clicked", G_CALLBACK(diya_dashboard_btn_test_clicked), self);
}
static void diya_taskbar_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
DiyaTaskbarWidget *self = DIYA_TASKBAR_WIDGET(object);
-
+ (void) self;
+ (void) value;
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;
@@ -421,34 +357,17 @@ static void diya_taskbar_get_property(GObject *object, guint property_id, GValue
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)
+static void diya_taskbar_widget_setup(DiyaShellWidget *widget)
{
- 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_setup(DiyaShellWindow *win)
-{
- DiyaTaskbarWidget *self = DIYA_TASKBAR_WIDGET(win);
- DiyaSessionShell *shell = DIYA_SESSION_SHELL(diya_shell_window_get_shell(DIYA_SHELL_WINDOW(self)));
+ g_debug("diya_taskbar_widget_setup");
+ DiyaTaskbarWidget *self = DIYA_TASKBAR_WIDGET(widget);
+ DiyaSessionShell *shell = DIYA_SESSION_SHELL(diya_shell_widget_get_shell(DIYA_SHELL_WIDGET(self)));
g_signal_connect(shell, DIYA_SIGNAL_FOREIGN_WINDOW_ADDED, G_CALLBACK(on_foreign_window_added), self);
g_signal_connect(shell, DIYA_SIGNAL_FOREIGN_WINDOW_STATE_CHANGED, G_CALLBACK(on_foreign_window_state_changed), self);
g_signal_connect(shell, DIYA_SIGNAL_FOREIGN_WINDOW_REMOVED, G_CALLBACK(on_foreign_window_removed), self);
@@ -464,21 +383,16 @@ static void diya_taskbar_widget_class_init(DiyaTaskbarWidgetClass *class)
gobject_class->set_property = diya_taskbar_set_property;
gobject_class->get_property = diya_taskbar_get_property;
- DiyaShellWindowClass *window_class = DIYA_SHELL_WINDOW_CLASS(class);
- window_class->setup = diya_taskbar_widget_setup;
+ DiyaShellWidgetClass *widget_class = DIYA_SHELL_WIDGET_CLASS(class);
+ widget_class->setup = diya_taskbar_widget_setup;
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), "/dev/iohub/diya/shell/ui/taskbar.ui");
- gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), DiyaTaskbarWidget, btn_toggle);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), DiyaTaskbarWidget, apps_list);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), DiyaTaskbarWidget, btn_test);
- // 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(DIYA_PROP_TASKBAR_SHOW_DASHBOARD, NULL, "Show/hide dashboard", false, G_PARAM_READWRITE); //
- g_object_class_install_properties(gobject_class, N_PROPERTIES, g_prop);
+ // TODO 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
index cf9d3b4..f9a22a8 100644
--- a/src/widgets/taskbar-widget.h
+++ b/src/widgets/taskbar-widget.h
@@ -4,10 +4,8 @@
#include "session-shell.h"
#include "base-widgets.h"
-#define DIYA_PROP_TASKBAR_SHOW_DASHBOARD "show-taskbar"
-
#define DIYA_TYPE_TASKBAR_WIDGET (diya_taskbar_widget_get_type())
-G_DECLARE_FINAL_TYPE (DiyaTaskbarWidget, diya_taskbar_widget, DIYA, TASKBAR_WIDGET, DiyaShellWindow)
+G_DECLARE_FINAL_TYPE (DiyaTaskbarWidget, diya_taskbar_widget, DIYA, TASKBAR_WIDGET, DiyaShellWidget)
#define DIYA_TYPE_TASKBAR_LIST_MODEL (diya_taskbar_list_model_get_type())
G_DECLARE_FINAL_TYPE (DiyaTaskbarListModel, diya_taskbar_list_model, DIYA, TASKBAR_LIST_MODEL, GObject)