#include #include "foreign.h" #include "session.h" #define SHELL_DESCRIPTION "Diya GTK shell for wayland (diyac)" enum { NO_PROP, SHELL_APP, SHELL_BACKGROUND_WIDGET, SHELL_LAUNCHPAD_WIDGET, SHELL_WINDOWS, SHELL_WAYLAND, N_PROPERTIES }; static GParamSpec *shell_properties[N_PROPERTIES] = {0}; struct _DiyaShell { DiyaObject parent; GtkApplication* app; GtkWindow* background; GtkWindow* launcher; GHashTable* windows; DiyaLockSession* lock; DiyaWayland * wayland; }; G_DEFINE_FINAL_TYPE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT) static void diya_shell_dispose(GObject* object) { DiyaShell * self = DIYA_SHELL(object); g_hash_table_destroy(self->windows); 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); } 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: self->background = g_value_get_pointer(value); break; case SHELL_LAUNCHPAD_WIDGET: self->launcher = g_value_get_pointer(value); break; case SHELL_WAYLAND: self->wayland = g_value_get_pointer(value); break; 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; case SHELL_WAYLAND: g_value_set_pointer(value, self->wayland); break; 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; gobject_class->dispose = diya_shell_dispose; 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); 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 ); shell_properties[SHELL_WINDOWS] = g_param_spec_pointer("windows", NULL, "Shell foreign windows", G_PARAM_READABLE); shell_properties[SHELL_WAYLAND] = g_param_spec_pointer("wayland", NULL, "Shell wayland", G_PARAM_READWRITE ); 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; self->wayland = NULL; self->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref); } DiyaForeignWindow* diya_shell_get_window(DiyaShell * shell, gpointer handle) { return g_hash_table_lookup(shell->windows, handle); } gboolean diya_shell_add_window(DiyaShell * shell, DiyaForeignWindow * win) { gpointer handle; g_object_get(win, "handle", &handle, NULL); assert(handle); return g_hash_table_insert(shell->windows,handle, win); } gboolean diya_shell_remove_window(DiyaShell * shell, DiyaForeignWindow * win) { gpointer handle; g_object_get(win, "handle", &handle, NULL); assert(handle); return g_hash_table_remove(shell->windows,handle); } 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); } DiyaShell * diya_shell_new(GtkApplication * app) { return DIYA_SHELL(g_object_new(DIYA_TYPE_SHELL,"application",app, NULL)); } 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; } /* 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 } */ /* 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)); } */