From bae9a814d8967d51cbf222a4e1458a5292d5154f Mon Sep 17 00:00:00 2001
From: Patrick McDermott <pj@pehjota.net>
Date: Sun, 22 Oct 2017 18:20:17 -0400
Subject: MqWindow: GObjectify

---
(limited to 'src')

diff --git a/src/window.c b/src/window.c
index b1fc251..8a72a01 100644
--- a/src/window.c
+++ b/src/window.c
@@ -23,32 +23,55 @@
 
 #include <stdlib.h>
 
+#include <glib.h>
 #include <gtk/gtk.h>
 
 #include "application.h"
 #include "tab-page.h"
 
+struct _MqWindow {
+	GtkWindow       parent_instance;
+	MqApplication  *application;
+	const gchar   **uris;
+	MqConfig       *config;
+	GtkWidget      *notebook;
+	MqTabPage      *root_tab;
+	guint           current_tab;
+	gboolean        fullscreen;
+};
+
+enum {
+	PROP_APPLICATION = 1,
+	PROP_URIS,
+	N_PROPERTIES
+};
+
+static GParamSpec *obj_properties[N_PROPERTIES] = {NULL,};
+
+struct _MqWindowClass {
+	GtkWindowClass parent_class;
+};
+
+G_DEFINE_TYPE(MqWindow, mq_window, GTK_TYPE_WINDOW)
+
 static void
-is_maximized_cb(GtkWindow *window, GParamSpec G_GNUC_UNUSED *param_spec,
-	MqConfig *config)
+is_maximized_cb(MqWindow *window, GParamSpec G_GNUC_UNUSED *param_spec)
 {
-	mq_config_set_boolean(config, "window.maximized",
-		gtk_window_is_maximized(window));
-	mq_config_save(config);
+	mq_config_set_boolean(window->config, "window.maximized",
+		gtk_window_is_maximized(GTK_WINDOW(window)));
+	mq_config_save(window->config);
 }
 
 static void
-configure_event_cb(GtkWindow G_GNUC_UNUSED *window, GdkEventConfigure *event,
-	MqConfig *config)
+configure_event_cb(MqWindow G_GNUC_UNUSED *window, GdkEventConfigure *event)
 {
-	mq_config_set_integer(config, "window.width", event->width);
-	mq_config_set_integer(config, "window.height", event->height);
-	mq_config_save(config);
+	mq_config_set_integer(window->config, "window.width", event->width);
+	mq_config_set_integer(window->config, "window.height", event->height);
+	mq_config_save(window->config);
 }
 
 static gboolean
-window_state_event_cb(GtkWidget G_GNUC_UNUSED *widget,
-	GdkEventWindowState *event, MqWindow *window)
+window_state_event_cb(MqWindow *window, GdkEventWindowState *event)
 {
 	window->fullscreen =
 		event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN;
@@ -70,13 +93,12 @@ close_confirm_response_cb(GtkWidget *dialog, gint response_id, MqWindow *window)
 {
 	gtk_widget_destroy(dialog);
 	if (response_id == GTK_RESPONSE_OK) {
-		gtk_widget_destroy(window->window);
+		gtk_widget_destroy(GTK_WIDGET(window));
 	}
 }
 
 static gboolean
-delete_event_cb(GtkWindow *widget, GdkEvent G_GNUC_UNUSED *event,
-	MqWindow *window)
+delete_event_cb(MqWindow *window, GdkEvent G_GNUC_UNUSED *event)
 {
 	guint      num_tabs;
 	gchar     *message;
@@ -126,8 +148,8 @@ delete_event_cb(GtkWindow *widget, GdkEvent G_GNUC_UNUSED *event,
 	gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
 
 	/* Dialog */
-	dialog = gtk_dialog_new_with_buttons("Confirm Close", widget,
-		GTK_DIALOG_DESTROY_WITH_PARENT,
+	dialog = gtk_dialog_new_with_buttons("Confirm Close",
+		GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT,
 		"_Cancel",     GTK_RESPONSE_CANCEL,
 		"Cl_ose Tabs", GTK_RESPONSE_OK,
 		NULL);
@@ -144,7 +166,7 @@ delete_event_cb(GtkWindow *widget, GdkEvent G_GNUC_UNUSED *event,
 }
 
 static void
-destroy_cb(GtkWidget G_GNUC_UNUSED *widget, MqWindow *window)
+destroy_cb(MqWindow *window)
 {
 	mq_application_delete_window(window->application, window);
 }
@@ -155,7 +177,7 @@ set_title(MqWindow *window, const gchar *title)
 	gchar *window_title;
 
 	window_title = g_strdup_printf("%s - Marquee", title);
-	gtk_window_set_title(GTK_WINDOW(window->window), window_title);
+	gtk_window_set_title(GTK_WINDOW(window), window_title);
 	g_free(window_title);
 }
 
@@ -183,67 +205,151 @@ update_positions(GtkNotebook G_GNUC_UNUSED *notebook,
 	window = window;
 }
 
-MqWindow *
-mq_window_new(MqApplication *application, const gchar **uris)
+static void
+constructed(GObject *object)
 {
 	MqWindow *window;
-	guint i;
+	gsize i;
 
-	window = malloc(sizeof(*window));
-	window->application = application;
-	window->config = mq_application_get_config(application);
+	window = MQ_WINDOW(object);
 
-	window->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 	if (mq_config_get_boolean(window->config, "window.maximized")) {
-		gtk_window_maximize(GTK_WINDOW(window->window));
+		gtk_window_maximize(GTK_WINDOW(window));
 	} else {
-		gtk_window_unmaximize(GTK_WINDOW(window->window));
+		gtk_window_unmaximize(GTK_WINDOW(window));
 	}
-	gtk_window_set_default_size(GTK_WINDOW(window->window),
+	gtk_window_set_default_size(GTK_WINDOW(window),
 		mq_config_get_integer(window->config, "window.width"),
 		mq_config_get_integer(window->config, "window.height"));
-	g_signal_connect(window->window, "notify::is-maximized",
-		G_CALLBACK(is_maximized_cb), window->config);
-	g_signal_connect(window->window, "configure-event",
-		G_CALLBACK(configure_event_cb), window->config);
-	g_signal_connect(window->window, "window-state-event",
-		G_CALLBACK(window_state_event_cb), window);
-	g_signal_connect(window->window, "delete-event",
-		G_CALLBACK(delete_event_cb), window);
-	g_signal_connect(window->window, "destroy",
-		G_CALLBACK(destroy_cb), window);
+
+	window->root_tab = mq_tab_page_new_root(window);
+
+	if (window->uris && window->uris[0]) {
+		for (i = 0; window->uris && window->uris[i]; ++i) {
+			mq_tab_page_new_relative(window->uris[i],
+				window->root_tab);
+		}
+	} else {
+		mq_tab_page_new_relative(NULL, window->root_tab);
+	}
+
+	gtk_widget_show_all(GTK_WIDGET(window));
+}
+
+static void
+get_property(GObject *object, guint property_id, GValue *value,
+	GParamSpec *param_spec)
+{
+	MqWindow *window;
+
+	window = MQ_WINDOW(object);
+
+	switch (property_id) {
+		case PROP_APPLICATION:
+			g_value_set_pointer(value, window->application);
+			break;
+		case PROP_URIS:
+			g_value_set_pointer(value, window->uris);
+			break;
+			;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id,
+				param_spec);
+			break;
+	}
+}
+
+static void
+set_property(GObject *object, guint property_id, const GValue *value,
+	GParamSpec *param_spec)
+{
+	MqWindow *window;
+
+	window = MQ_WINDOW(object);
+
+	switch (property_id) {
+		case PROP_APPLICATION:
+			window->application = g_value_get_pointer(value);
+			window->config = mq_application_get_config(
+				window->application);
+			break;
+		case PROP_URIS:
+			window->uris = g_value_get_pointer(value);
+			break;
+			;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id,
+				param_spec);
+			break;
+	}
+}
+
+static void
+mq_window_class_init(MqWindowClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+	object_class->constructed  = constructed;
+	object_class->get_property = get_property;
+	object_class->set_property = set_property;
+
+	obj_properties[PROP_APPLICATION] = g_param_spec_pointer(
+		"application",
+		"Application",
+		"The parent MqApplication instance",
+		G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+		G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
+	obj_properties[PROP_URIS] = g_param_spec_pointer(
+		"uris",
+		"URIs",
+		"A NULL-terminated string array of URIs to load",
+		G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+		G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
+	g_object_class_install_properties(object_class, N_PROPERTIES,
+		obj_properties);
+}
+
+static void
+mq_window_init(MqWindow *window)
+{
 	window->fullscreen = FALSE;
 
+	g_signal_connect(window, "notify::is-maximized",
+		G_CALLBACK(is_maximized_cb), NULL);
+	g_signal_connect(window, "configure-event",
+		G_CALLBACK(configure_event_cb), NULL);
+	g_signal_connect(window, "window-state-event",
+		G_CALLBACK(window_state_event_cb), NULL);
+	g_signal_connect(window, "delete-event",
+		G_CALLBACK(delete_event_cb), NULL);
+	g_signal_connect(window, "destroy",
+		G_CALLBACK(destroy_cb), NULL);
+
 	window->notebook = gtk_notebook_new();
 	gtk_notebook_set_scrollable(GTK_NOTEBOOK(window->notebook), TRUE);
 	gtk_notebook_set_group_name(GTK_NOTEBOOK(window->notebook), "mq-tabs");
 	gtk_widget_set_can_focus(window->notebook, FALSE);
-	gtk_container_add(GTK_CONTAINER(window->window),
-		window->notebook);
+	gtk_container_add(GTK_CONTAINER(window), window->notebook);
 	g_signal_connect(window->notebook, "switch-page",
 		G_CALLBACK(switch_page_cb), window);
 	g_signal_connect(window->notebook, "page-reordered",
 		G_CALLBACK(update_positions), window);
+}
 
-	window->root_tab = mq_tab_page_new_root(window);
-
-	if (uris && uris[0]) {
-		for (i = 0; uris && uris[i]; ++i) {
-			mq_tab_page_new_relative(uris[i], window->root_tab);
-		}
-	} else {
-		mq_tab_page_new_relative(NULL, window->root_tab);
-	}
-
-	gtk_widget_show_all(window->window);
-
-	return window;
+MqWindow *
+mq_window_new(MqApplication *application, const gchar **uris)
+{
+	return g_object_new(MQ_TYPE_WINDOW,
+		"type", GTK_WINDOW_TOPLEVEL,
+		"application", application,
+		"uris", uris,
+		NULL);
 }
 
 void
 mq_window_quit(MqWindow *window)
 {
-	mq_application_quit(window->application, GTK_WINDOW(window->window));
+	mq_application_quit(window->application, GTK_WINDOW(window));
 }
 
 MqApplication *
@@ -256,9 +362,9 @@ void
 mq_window_toggle_fullscreen(MqWindow *window)
 {
 	if (!window->fullscreen) {
-		gtk_window_fullscreen(GTK_WINDOW(window->window));
+		gtk_window_fullscreen(GTK_WINDOW(window));
 	} else {
-		gtk_window_unfullscreen(GTK_WINDOW(window->window));
+		gtk_window_unfullscreen(GTK_WINDOW(window));
 	}
 }
 
diff --git a/src/window.h b/src/window.h
index bd98d23..0dcb25c 100644
--- a/src/window.h
+++ b/src/window.h
@@ -19,7 +19,8 @@
  * along with Marquee.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-typedef struct MqWindow MqWindow;
+typedef struct _MqWindow      MqWindow;
+typedef struct _MqWindowClass MqWindowClass;
 
 #ifndef MQ_WINDOW_H
 #define MQ_WINDOW_H
@@ -31,15 +32,22 @@ typedef struct MqWindow MqWindow;
 #include "config.h"
 #include "tab-page.h"
 
-struct MqWindow {
-	MqApplication *application;
-	MqConfig      *config;
-	GtkWidget     *window;
-	GtkWidget     *notebook;
-	MqTabPage     *root_tab;
-	guint          current_tab;
-	gboolean       fullscreen;
-};
+G_BEGIN_DECLS
+
+#define MQ_TYPE_WINDOW            (mq_window_get_type())
+#define MQ_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+                                  MQ_TYPE_WINDOW, MqWindow))
+#define MQ_IS_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+                                  MQ_TYPE_WINDOW))
+#define MQ_WINDOW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), \
+                                  MQ_TYPE_WINDOW, MqWindowClass))
+#define MQ_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
+                                  MQ_TYPE_WINDOW))
+#define MQ_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), \
+                                  MQ_TYPE_WINDOW, MqWindowClass))
+
+GType
+mq_window_get_type(void);
 
 MqWindow *
 mq_window_new(MqApplication *application, const gchar **uris);
@@ -79,4 +87,6 @@ mq_window_begin_scrolling_tab_labels(MqWindow *window);
 void
 mq_window_end_scrolling_tab_labels(MqWindow *window);
 
-#endif
+G_END_DECLS
+
+#endif  /* MQ_WINDOW_H */
--
cgit v0.9.1