WIP: redesign the session shell launcher
This commit is contained in:
@@ -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',
|
||||
]
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ diya-taskbar
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
diya-dashboard
|
||||
diya-spotlight
|
||||
{
|
||||
background-color: lightgray;
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
diya-shell-background
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
<file alias="default.keymap">resources/vkb/default.keymap</file>
|
||||
</gresource>
|
||||
<gresource prefix="/dev/iohub/diya/shell/ui">
|
||||
<file alias="dashboard.ui">resources/ui/dashboard.ui</file>
|
||||
<file alias="spotlight.ui">resources/ui/spotlight.ui</file>
|
||||
<file alias="taskbar.ui">resources/ui/taskbar.ui</file>
|
||||
<file alias="launchpad.ui">resources/ui/launchpad.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/dev/iohub/diya/shell/css">
|
||||
<file alias="dev.iohub.diya.session.css">resources/css/session-shell.css</file>
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="DiyaDashboardWidget" parent="DiyaShellWindow">
|
||||
<!--property name="title" translatable="yes">Example Application</property-->
|
||||
<!--property name="default-width">600</property>
|
||||
<property name="default-height">400</property-->
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="revealer">
|
||||
<property name="transition-type">slide-up</property>
|
||||
<property name="reveal-child">0</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="header">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="search_entry">
|
||||
<property name="hexpand">1</property>
|
||||
<signal name="search-changed" handler="diya_dashboard_search_text_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="gears">
|
||||
<property name="direction">none</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="vexpand">1</property>
|
||||
<property name="hexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">app_list</property>
|
||||
<property name="title">Application list</property>
|
||||
<property name="child">
|
||||
<object class="GtkScrolledWindow" id="sidebar-sw">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkFlowBox" id="app_list_box">
|
||||
<property name="activate-on-single-click">1</property>
|
||||
<signal name="child-activated" handler="diya_dashboard_app_launch"/>
|
||||
</object>
|
||||
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">search_list</property>
|
||||
<property name="title">Search</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">second stack child</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!--child>
|
||||
<object class="GtkBox" id="taskbar">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="btn_launch">
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Terminal</property>
|
||||
<signal name="clicked" handler="diya_dashboard_launch"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child-->
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
31
resources/ui/launchpad.ui
Normal file
31
resources/ui/launchpad.ui
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="DiyaLaunchpadWidget" parent="DiyaShellWindow">
|
||||
<!--property name="title" translatable="yes">Example Application</property-->
|
||||
<!--property name="default-width">600</property>
|
||||
<property name="default-height">400</property-->
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="btn_handle">
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Test</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="taskbar_revealer">
|
||||
<property name="transition-type">slide-up</property>
|
||||
<property name="reveal-child">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="spotlight_revealer">
|
||||
<property name="transition-type">slide-up</property>
|
||||
<property name="reveal-child">0</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
88
resources/ui/spotlight.ui
Normal file
88
resources/ui/spotlight.ui
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="DiyaSpotlightWidget" parent="DiyaShellWidget">
|
||||
<!--property name="title" translatable="yes">Example Application</property-->
|
||||
<!--property name="default-width">600</property>
|
||||
<property name="default-height">400</property-->
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="header">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkSearchEntry" id="search_entry">
|
||||
<property name="hexpand">1</property>
|
||||
<signal name="search-changed" handler="diya_spotlight_search_text_changed"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="gears">
|
||||
<property name="direction">none</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<property name="vexpand">1</property>
|
||||
<property name="hexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">app_list</property>
|
||||
<property name="title">Application list</property>
|
||||
<property name="child">
|
||||
<object class="GtkScrolledWindow" id="sidebar-sw">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<child>
|
||||
<object class="GtkFlowBox" id="app_list_box">
|
||||
<property name="activate-on-single-click">1</property>
|
||||
<signal name="child-activated" handler="diya_spotlight_app_launch"/>
|
||||
</object>
|
||||
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">search_list</property>
|
||||
<property name="title">Search</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">second stack child</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child type="title">
|
||||
<object class="GtkStackSwitcher" id="tabs">
|
||||
<property name="stack">stack</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<!--child>
|
||||
<object class="GtkBox" id="taskbar">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="btn_launch">
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Terminal</property>
|
||||
<signal name="clicked" handler="diya_spotlight_launch"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child-->
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="DiyaTaskbarWidget" parent="DiyaShellWindow">
|
||||
<template class="DiyaTaskbarWidget" parent="DiyaShellWidget">
|
||||
<!--property name="title" translatable="yes">Example Application</property-->
|
||||
<!--property name="default-width">600</property>
|
||||
<property name="default-height">400</property-->
|
||||
@@ -8,14 +8,6 @@
|
||||
<object class="GtkBox" id="taskbar">
|
||||
<property name="hexpand">1</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="btn_toggle">
|
||||
<property name="visible">1</property>
|
||||
<property name="label" translatable="yes">Diya</property>
|
||||
<!--signal name="toggled" handler="diya_dashboard_toggle"/-->
|
||||
</object>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hexpand">1</property>
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#include <gdk/wayland/gdkwayland.h>
|
||||
#include <assert.h>
|
||||
#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
|
||||
*/
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
149
src/widgets/launchpad-widget.c
Normal file
149
src/widgets/launchpad-widget.c
Normal file
@@ -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);
|
||||
}
|
||||
10
src/widgets/launchpad-widget.h
Normal file
10
src/widgets/launchpad-widget.h
Normal file
@@ -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
|
||||
304
src/widgets/spotlight-widget.c
Normal file
304
src/widgets/spotlight-widget.c
Normal file
@@ -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);
|
||||
}
|
||||
12
src/widgets/spotlight-widget.h
Normal file
12
src/widgets/spotlight-widget.h
Normal file
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user