From c0489c0880deb64ada223e52edddbdd039f63a50 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sun, 8 Apr 2018 17:13:42 -0300 Subject: window: Delegate model creation to CcApplication In order be able to modify panel information statically, we need to have access to the CcShellModel from static functions. CcApplication, thus, is a better place for the model to live, since we can access it outside any scope using g_application_get_default(). It also makes sense from the modeling point of view, since the model is not tied to the shell anymore. --- shell/cc-application.c | 13 +++++++- shell/cc-application.h | 6 +++- shell/cc-window.c | 88 ++++++++++++++++++++++++++++++++++---------------- shell/cc-window.h | 4 ++- 4 files changed, 81 insertions(+), 30 deletions(-) diff --git a/shell/cc-application.c b/shell/cc-application.c index 3f828f3a6..51c2cb245 100644 --- a/shell/cc-application.c +++ b/shell/cc-application.c @@ -39,6 +39,8 @@ struct _CcApplication { GtkApplication parent; + CcShellModel *model; + CcWindow *window; }; @@ -264,7 +266,8 @@ cc_application_startup (GApplication *application) gtk_application_set_accels_for_action (GTK_APPLICATION (application), "app.help", help_accels); - self->window = cc_window_new (GTK_APPLICATION (application)); + self->model = cc_shell_model_new (); + self->window = cc_window_new (GTK_APPLICATION (application), self->model); } static void @@ -325,3 +328,11 @@ cc_application_new (void) "flags", G_APPLICATION_HANDLES_COMMAND_LINE, NULL); } + +CcShellModel * +cc_application_get_model (CcApplication *self) +{ + g_return_val_if_fail (CC_IS_APPLICATION (self), NULL); + + return self->model; +} diff --git a/shell/cc-application.h b/shell/cc-application.h index eeda001b0..e9c8b60af 100644 --- a/shell/cc-application.h +++ b/shell/cc-application.h @@ -19,6 +19,8 @@ #pragma once +#include "cc-shell-model.h" + #include G_BEGIN_DECLS @@ -29,4 +31,6 @@ G_DECLARE_FINAL_TYPE (CcApplication, cc_application, CC, APPLICATION, GtkApplica GtkApplication *cc_application_new (void); -G_END_DECLS \ No newline at end of file +CcShellModel *cc_application_get_model (CcApplication *self); + +G_END_DECLS diff --git a/shell/cc-window.c b/shell/cc-window.c index f8dbc0ffb..a4c093374 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -35,6 +35,7 @@ #include #include +#include "cc-application.h" #include "cc-panel.h" #include "cc-shell.h" #include "cc-shell-category-view.h" @@ -87,7 +88,8 @@ G_DEFINE_TYPE_WITH_CODE (CcWindow, cc_window, GTK_TYPE_APPLICATION_WINDOW, enum { PROP_0, - PROP_ACTIVE_PANEL + PROP_ACTIVE_PANEL, + PROP_MODEL }; /* Auxiliary methods */ @@ -253,7 +255,9 @@ setup_model (CcWindow *shell) GtkTreeIter iter; gboolean valid; - shell->store = (GtkListStore *) cc_shell_model_new (); + /* CcApplication must have a valid model at this point */ + g_assert (shell->store != NULL); + model = GTK_TREE_MODEL (shell->store); cc_panel_loader_fill_model (CC_SHELL_MODEL (shell->store)); @@ -632,6 +636,11 @@ cc_window_get_property (GObject *object, case PROP_ACTIVE_PANEL: g_value_set_object (value, self->active_panel); break; + + case PROP_MODEL: + g_value_set_object (value, self->store); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -650,11 +659,49 @@ cc_window_set_property (GObject *object, case PROP_ACTIVE_PANEL: set_active_panel (shell, g_value_get_object (value)); break; + + case PROP_MODEL: + g_assert (shell->store == NULL); + shell->store = g_value_dup_object (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } } +static void +cc_window_constructed (GObject *object) +{ + g_autofree char *id = NULL; + GtkSettings *settings; + CcWindow *self; + + self = CC_WINDOW (object); + + /* Handle decorations for the split headers. */ + settings = gtk_settings_get_default (); + g_signal_connect (settings, + "notify::gtk-decoration-layout", + G_CALLBACK (split_decorations_cb), + self); + + split_decorations_cb (settings, NULL, self); + + /* Add the panels */ + setup_model (self); + + /* After everything is loaded, select the last used panel, if any, + * or the first visible panel */ + id = g_settings_get_string (self->settings, "last-panel"); + if (id != NULL && cc_shell_model_has_panel (CC_SHELL_MODEL (self->store), id)) + cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), id); + else + cc_panel_list_activate (CC_PANEL_LIST (self->panel_list)); + + G_OBJECT_CLASS (cc_window_parent_class)->constructed (object); +} + static void cc_window_dispose (GObject *object) { @@ -692,11 +739,20 @@ cc_window_class_init (CcWindowClass *klass) object_class->get_property = cc_window_get_property; object_class->set_property = cc_window_set_property; + object_class->constructed = cc_window_constructed; object_class->dispose = cc_window_dispose; object_class->finalize = cc_window_finalize; g_object_class_override_property (object_class, PROP_ACTIVE_PANEL, "active-panel"); + g_object_class_install_property (object_class, + PROP_MODEL, + g_param_spec_object ("model", + "Model", + "The CcShellModel of this application", + CC_TYPE_SHELL_MODEL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/ControlCenter/gtk/window.ui"); gtk_widget_class_bind_template_child (widget_class, CcWindow, header); @@ -729,41 +785,18 @@ cc_window_class_init (CcWindowClass *klass) static void cc_window_init (CcWindow *self) { - GtkSettings *settings; - g_autofree char *id = NULL; - gtk_widget_init_template (GTK_WIDGET (self)); gtk_widget_add_events (GTK_WIDGET (self), GDK_BUTTON_RELEASE_MASK); self->settings = g_settings_new ("org.gnome.ControlCenter"); - - /* Handle decorations for the split headers. */ - settings = gtk_settings_get_default (); - g_signal_connect (settings, - "notify::gtk-decoration-layout", - G_CALLBACK (split_decorations_cb), - self); - - split_decorations_cb (settings, NULL, self); - - /* Add the panels */ self->custom_widgets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); self->previous_panels = g_queue_new (); - - setup_model (self); - - /* After everything is loaded, select the last used panel, if any, - * or the first visible panel */ - id = g_settings_get_string (self->settings, "last-panel"); - if (id != NULL && cc_shell_model_has_panel (CC_SHELL_MODEL (self->store), id)) - cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), id); - else - cc_panel_list_activate (CC_PANEL_LIST (self->panel_list)); } CcWindow * -cc_window_new (GtkApplication *application) +cc_window_new (GtkApplication *application, + CcShellModel *model) { g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL); @@ -774,6 +807,7 @@ cc_window_new (GtkApplication *application) "icon-name", DEFAULT_WINDOW_ICON_NAME, "window-position", GTK_WIN_POS_CENTER, "show-menubar", FALSE, + "model", model, NULL); } diff --git a/shell/cc-window.h b/shell/cc-window.h index cac270944..b7a272abe 100644 --- a/shell/cc-window.h +++ b/shell/cc-window.h @@ -23,6 +23,7 @@ #include #include "cc-shell.h" +#include "cc-shell-model.h" G_BEGIN_DECLS @@ -30,7 +31,8 @@ G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (CcWindow, cc_window, CC, WINDOW, GtkApplicationWindow) -CcWindow *cc_window_new (GtkApplication *application); +CcWindow *cc_window_new (GtkApplication *application, + CcShellModel *model); void cc_window_set_overview_page (CcWindow *center); -- cgit v1.2.1