2024-04-14 16:29:02 +02:00
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "foreign.h"
|
2024-04-17 01:05:53 +02:00
|
|
|
#include "session.h"
|
2024-04-14 16:29:02 +02:00
|
|
|
|
|
|
|
#define SHELL_DESCRIPTION "Diya GTK shell for wayland (diyac)"
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
NO_PROP,
|
|
|
|
SHELL_APP,
|
|
|
|
SHELL_BACKGROUND_WIDGET,
|
|
|
|
SHELL_LAUNCHPAD_WIDGET,
|
|
|
|
SHELL_WINDOWS,
|
2024-04-17 01:05:53 +02:00
|
|
|
SHELL_WAYLAND,
|
2024-04-14 16:29:02 +02:00
|
|
|
N_PROPERTIES
|
|
|
|
};
|
|
|
|
|
|
|
|
static GParamSpec *shell_properties[N_PROPERTIES] = {0};
|
|
|
|
|
|
|
|
struct _DiyaShell
|
|
|
|
{
|
|
|
|
DiyaObject parent;
|
|
|
|
GtkApplication* app;
|
|
|
|
GtkWindow* background;
|
|
|
|
GtkWindow* launcher;
|
|
|
|
GHashTable* windows;
|
2024-04-17 01:05:53 +02:00
|
|
|
DiyaLockSession* lock;
|
|
|
|
DiyaWayland * wayland;
|
2024-04-14 16:29:02 +02:00
|
|
|
};
|
2024-04-17 01:05:53 +02:00
|
|
|
G_DEFINE_FINAL_TYPE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT)
|
2024-04-14 16:29:02 +02:00
|
|
|
|
2024-04-17 01:05:53 +02:00
|
|
|
static void diya_shell_dispose(GObject* object)
|
2024-04-14 16:29:02 +02:00
|
|
|
{
|
|
|
|
DiyaShell * self = DIYA_SHELL(object);
|
|
|
|
g_hash_table_destroy(self->windows);
|
2024-04-17 01:05:53 +02:00
|
|
|
g_debug("diya_shell_dispose");
|
|
|
|
if(self->wayland)
|
|
|
|
{
|
|
|
|
g_object_unref(self->wayland);
|
|
|
|
}
|
|
|
|
if(self->lock)
|
|
|
|
{
|
|
|
|
g_object_unref(self->lock);
|
|
|
|
}
|
|
|
|
G_OBJECT_CLASS(diya_shell_parent_class)->dispose(object);
|
2024-04-14 16:29:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void diya_shell_set_property(GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
DiyaShell * self = DIYA_SHELL(object);
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case SHELL_APP:
|
|
|
|
self->app = g_value_get_pointer(value);
|
|
|
|
assert(self->app);
|
|
|
|
break;
|
|
|
|
case SHELL_BACKGROUND_WIDGET:
|
2024-04-17 01:05:53 +02:00
|
|
|
self->background = g_value_get_pointer(value);
|
|
|
|
break;
|
2024-04-14 16:29:02 +02:00
|
|
|
case SHELL_LAUNCHPAD_WIDGET:
|
2024-04-17 01:05:53 +02:00
|
|
|
self->launcher = g_value_get_pointer(value);
|
|
|
|
break;
|
|
|
|
case SHELL_WAYLAND:
|
|
|
|
self->wayland = g_value_get_pointer(value);
|
|
|
|
break;
|
2024-04-14 16:29:02 +02:00
|
|
|
case SHELL_WINDOWS:
|
|
|
|
//self->windows = g_value_get_pointer(value);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void diya_shell_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
|
|
|
|
{
|
|
|
|
DiyaShell * self = DIYA_SHELL(object);
|
|
|
|
switch (property_id)
|
|
|
|
{
|
|
|
|
case SHELL_APP:
|
|
|
|
g_value_set_pointer(value, self->app);
|
|
|
|
break;
|
|
|
|
case SHELL_BACKGROUND_WIDGET:
|
|
|
|
g_value_set_pointer(value, self->background);
|
|
|
|
break;
|
|
|
|
case SHELL_LAUNCHPAD_WIDGET:
|
|
|
|
assert(self->launcher);
|
|
|
|
g_value_set_pointer(value, self->launcher);
|
|
|
|
break;
|
2024-04-17 01:05:53 +02:00
|
|
|
case SHELL_WAYLAND:
|
|
|
|
g_value_set_pointer(value, self->wayland);
|
|
|
|
break;
|
2024-04-14 16:29:02 +02:00
|
|
|
case SHELL_WINDOWS:
|
|
|
|
g_value_set_pointer(value, self->windows);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const gchar* diya_shell_to_string(DiyaObject* object)
|
|
|
|
{
|
|
|
|
(void) object;
|
|
|
|
return SHELL_DESCRIPTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void diya_shell_class_init(DiyaShellClass *class)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
|
|
|
|
DiyaObjectClass *base_class = DIYA_OBJECT_CLASS(class);
|
|
|
|
|
|
|
|
base_class->to_string = diya_shell_to_string;
|
2024-04-17 01:05:53 +02:00
|
|
|
gobject_class->dispose = diya_shell_dispose;
|
2024-04-14 16:29:02 +02:00
|
|
|
gobject_class->set_property = diya_shell_set_property;
|
|
|
|
gobject_class->get_property = diya_shell_get_property;
|
|
|
|
|
|
|
|
shell_properties[SHELL_APP] = g_param_spec_pointer("application", NULL, "Shell application", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
2024-04-17 01:05:53 +02:00
|
|
|
shell_properties[SHELL_BACKGROUND_WIDGET] = g_param_spec_pointer("background", NULL, "Shell background widget", G_PARAM_READWRITE );
|
|
|
|
shell_properties[SHELL_LAUNCHPAD_WIDGET] = g_param_spec_pointer("launchpad", NULL, "Shell launchpad", G_PARAM_READWRITE );
|
2024-04-14 16:29:02 +02:00
|
|
|
shell_properties[SHELL_WINDOWS] = g_param_spec_pointer("windows", NULL, "Shell foreign windows", G_PARAM_READABLE);
|
2024-04-17 01:05:53 +02:00
|
|
|
shell_properties[SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READWRITE );
|
|
|
|
|
2024-04-14 16:29:02 +02:00
|
|
|
g_object_class_install_properties (gobject_class, N_PROPERTIES, shell_properties);
|
|
|
|
|
|
|
|
g_signal_new("foreign-window-changed",
|
|
|
|
DIYA_TYPE_SHELL,
|
|
|
|
G_SIGNAL_DETAILED |
|
|
|
|
G_SIGNAL_ACTION |
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
G_TYPE_NONE,
|
|
|
|
1,
|
|
|
|
G_TYPE_POINTER);
|
|
|
|
g_signal_new("foreign-window-removed",
|
|
|
|
DIYA_TYPE_SHELL,
|
|
|
|
G_SIGNAL_DETAILED |
|
|
|
|
G_SIGNAL_ACTION |
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
G_TYPE_NONE,
|
|
|
|
1,
|
|
|
|
G_TYPE_POINTER);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void diya_shell_init(DiyaShell *self)
|
|
|
|
{
|
|
|
|
//self->app = NULL;
|
|
|
|
self->background = NULL;
|
|
|
|
self->launcher = NULL;
|
2024-04-17 01:05:53 +02:00
|
|
|
self->wayland = NULL;
|
2024-04-14 16:29:02 +02:00
|
|
|
self->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
|
|
|
}
|
|
|
|
|
2024-04-17 01:05:53 +02:00
|
|
|
DiyaForeignWindow* diya_shell_get_window(DiyaShell * shell, gpointer handle)
|
2024-04-14 16:29:02 +02:00
|
|
|
{
|
|
|
|
return g_hash_table_lookup(shell->windows, handle);
|
|
|
|
}
|
2024-04-17 01:05:53 +02:00
|
|
|
gboolean diya_shell_add_window(DiyaShell * shell, DiyaForeignWindow * win)
|
2024-04-14 16:29:02 +02:00
|
|
|
{
|
|
|
|
gpointer handle;
|
|
|
|
g_object_get(win, "handle", &handle, NULL);
|
|
|
|
assert(handle);
|
|
|
|
return g_hash_table_insert(shell->windows,handle, win);
|
|
|
|
}
|
|
|
|
|
2024-04-17 01:05:53 +02:00
|
|
|
gboolean diya_shell_remove_window(DiyaShell * shell, DiyaForeignWindow * win)
|
2024-04-14 16:29:02 +02:00
|
|
|
{
|
|
|
|
gpointer handle;
|
|
|
|
g_object_get(win, "handle", &handle, NULL);
|
|
|
|
assert(handle);
|
|
|
|
return g_hash_table_remove(shell->windows,handle);
|
|
|
|
}
|
|
|
|
|
2024-04-17 01:05:53 +02:00
|
|
|
void diya_shell_remove_all_windows(DiyaShell * shell)
|
|
|
|
{
|
|
|
|
g_hash_table_destroy(shell->windows);
|
|
|
|
shell->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
|
|
|
|
}
|
|
|
|
|
2024-04-14 16:29:02 +02:00
|
|
|
DiyaShell * diya_shell_new(GtkApplication * app)
|
|
|
|
{
|
|
|
|
return DIYA_SHELL(g_object_new(DIYA_TYPE_SHELL,"application",app, NULL));
|
|
|
|
}
|
2024-04-17 01:05:53 +02:00
|
|
|
|
|
|
|
void diya_shell_lock(DiyaShell* shell)
|
|
|
|
{
|
|
|
|
if(shell->lock)
|
|
|
|
{
|
|
|
|
g_warning("Shell session is already locked, doing nothing");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
shell->lock = g_object_new(DIYA_TYPE_LOCK_SESSION, "shell", shell, NULL);
|
|
|
|
}
|
|
|
|
void diya_shell_unlock(DiyaShell* shell)
|
|
|
|
{
|
|
|
|
diya_shell_session_lock_release(shell->lock);
|
|
|
|
g_object_unref(shell->lock);
|
|
|
|
shell->lock = NULL;
|
|
|
|
}
|
|
|
|
DiyaWayland * diya_shell_get_wayland(DiyaShell* shell)
|
|
|
|
{
|
|
|
|
DiyaWayland * wayland;
|
|
|
|
g_object_get(shell,"wayland", &wayland, NULL);
|
|
|
|
assert(DIYA_IS_WAYLAND(wayland));
|
|
|
|
return wayland;
|
|
|
|
}
|
2024-04-14 16:29:02 +02:00
|
|
|
/*
|
|
|
|
static void on_orientation_changed (GtkWindow *window, WindowOrientation orientation, ToplevelData *data)
|
|
|
|
{
|
|
|
|
(void)window;
|
|
|
|
GtkOrientation orient_toplevel, orient_sub;
|
|
|
|
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
orient_sub = GTK_ORIENTATION_VERTICAL;
|
|
|
|
|
|
|
|
switch (orientation) {
|
|
|
|
case WINDOW_ORIENTATION_HORIZONTAL:
|
|
|
|
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
orient_sub = GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
break;
|
|
|
|
case WINDOW_ORIENTATION_VERTICAL:
|
|
|
|
orient_toplevel = GTK_ORIENTATION_VERTICAL;
|
|
|
|
orient_sub = GTK_ORIENTATION_VERTICAL;
|
|
|
|
break;
|
|
|
|
case WINDOW_ORIENTATION_NONE:
|
|
|
|
orient_toplevel = GTK_ORIENTATION_HORIZONTAL;
|
|
|
|
orient_sub = GTK_ORIENTATION_VERTICAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->toplevel_box), orient_toplevel);
|
|
|
|
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->first_box), orient_sub);
|
|
|
|
gtk_orientable_set_orientation (GTK_ORIENTABLE (data->second_box), orient_sub);
|
|
|
|
//gtk_window_resize (window, 1, 1); // force the window to shrink to the smallest size it can
|
|
|
|
}
|
|
|
|
*/
|
2024-04-17 01:05:53 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
static void before_destroy (GtkWidget *win, GtkCssProvider *provider) {
|
|
|
|
GdkDisplay *display = gdk_display_get_default ();
|
|
|
|
gtk_style_context_remove_provider_for_display (display, GTK_STYLE_PROVIDER (provider));
|
2024-04-14 16:29:02 +02:00
|
|
|
}
|
2024-04-17 01:05:53 +02:00
|
|
|
*/
|