diya-shell/src/shell.c

231 lines
7.4 KiB
C
Raw Normal View History

#include <assert.h>
#include "background.h"
#include "launcher.h"
#include "wayland.h"
#include "foreign.h"
#define SHELL_DESCRIPTION "Diya GTK shell for wayland (diyac)"
enum
{
NO_PROP,
SHELL_APP,
SHELL_BACKGROUND_WIDGET,
SHELL_LAUNCHPAD_WIDGET,
SHELL_WINDOWS,
N_PROPERTIES
};
static GParamSpec *shell_properties[N_PROPERTIES] = {0};
struct _DiyaShell
{
DiyaObject parent;
GtkApplication* app;
GtkWindow* background;
GtkWindow* launcher;
GHashTable* windows;
};
G_DEFINE_TYPE(DiyaShell, diya_shell, DIYA_TYPE_OBJECT)
static void diya_shell_finalize(GObject* object)
{
DiyaShell * self = DIYA_SHELL(object);
g_hash_table_destroy(self->windows);
// TODO: free element in each entry of the table
// g_object_unref(self->app);
g_warning("diya_shell_finalize");
}
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);
self->background = GTK_WINDOW (gtk_application_window_new (self->app));
self->launcher = GTK_WINDOW (gtk_application_window_new (self->app));
break;
case SHELL_BACKGROUND_WIDGET:
case SHELL_LAUNCHPAD_WIDGET:
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_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->finalize = diya_shell_finalize;
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_READABLE );
shell_properties[SHELL_LAUNCHPAD_WIDGET] = g_param_spec_pointer("launchpad", NULL, "Shell launchpad", G_PARAM_READABLE );
shell_properties[SHELL_WINDOWS] = g_param_spec_pointer("windows", NULL, "Shell foreign windows", G_PARAM_READABLE);
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->windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_object_unref);
}
gpointer diya_shell_get_window(DiyaShell * shell, gpointer handle)
{
return g_hash_table_lookup(shell->windows, handle);
}
gboolean diya_shell_add_window(DiyaShell * shell, DiyaWindow * 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, DiyaWindow * win)
{
gpointer handle;
g_object_get(win, "handle", &handle, NULL);
assert(handle);
return g_hash_table_remove(shell->windows,handle);
}
DiyaShell * diya_shell_new(GtkApplication * app)
{
return DIYA_SHELL(g_object_new(DIYA_TYPE_SHELL,"application",app, NULL));
}
/*
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 shutdown(GtkApplication *app, void *data)
{
(void) app;
g_warning("Application shutdown");
DiyaShell * shell = data;
assert(shell);
g_object_unref(shell);
}
static void activate(GtkApplication *app, void *data)
{
(void)data;
DiyaShell * shell = diya_shell_new(app);
assert(shell);
assert(DIYA_IS_SHELL(shell));
g_signal_connect(app, "shutdown", G_CALLBACK(shutdown), (void*)shell);
diya_launcher_init(shell);
diya_shell_wayland_init(shell);
diya_shell_init_background(shell);
// CSS support
// set color for it
GtkCssProvider *provider = gtk_css_provider_new();
const char *css = "#launcher {background-color: red;} #background {background-image:url(\"file:///etc/xdg/labwc/wpp.jpg\");background-size: cover;}";
gtk_css_provider_load_from_string(provider, css);
gtk_style_context_add_provider_for_display(
gdk_display_get_default(), GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
}
int main(int argc, char *argv[])
{
GtkApplication* app = gtk_application_new("dev.iohub.diya-shell", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
int status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}