summaryrefslogtreecommitdiffstats
path: root/src/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c244
1 files changed, 177 insertions, 67 deletions
diff --git a/src/window.c b/src/window.c
index a4807db..8a72a01 100644
--- a/src/window.c
+++ b/src/window.c
@@ -19,35 +19,59 @@
* along with Marquee. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "window.h"
+
#include <stdlib.h>
+#include <glib.h>
#include <gtk/gtk.h>
-#include "window.h"
#include "application.h"
-#include "tab.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 *paramspec,
- 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;
@@ -69,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;
@@ -125,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);
@@ -135,13 +158,15 @@ delete_event_cb(GtkWindow *widget, GdkEvent G_GNUC_UNUSED *event,
hbox);
g_signal_connect(dialog, "response",
G_CALLBACK(close_confirm_response_cb), window);
+ gtk_widget_grab_focus(gtk_dialog_get_widget_for_response(
+ GTK_DIALOG(dialog), GTK_RESPONSE_OK));
gtk_widget_show_all(dialog);
return TRUE;
}
static void
-destroy_cb(GtkWidget G_GNUC_UNUSED *widget, MqWindow *window)
+destroy_cb(MqWindow *window)
{
mq_application_delete_window(window->application, window);
}
@@ -152,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);
}
@@ -162,8 +187,8 @@ switch_page_cb(GtkNotebook G_GNUC_UNUSED *notebook,
{
window->current_tab = ++page_num;
- set_title(window, mq_tab_get_title(mq_tab_seek(window->root_tab,
- page_num)));
+ set_title(window, mq_tab_page_get_title(
+ mq_tab_page_seek(window->root_tab, page_num)));
}
static void
@@ -171,75 +196,160 @@ update_positions(GtkNotebook G_GNUC_UNUSED *notebook,
GtkWidget G_GNUC_UNUSED *child, guint G_GNUC_UNUSED page_num,
MqWindow *window)
{
- /* TODO: Once MqWindow has a data structure for tabs, loop through them
- * all and call mq_tab_update_position(). */
+ /* TODO: After MqTab becomes MqTabPage, derived from GtkBox, call
+ * mq_tab_page_update_positions() on child or
+ * mq_tab_page_seek(page_num + 1), whichever has the lower position. */
/* TODO: Should this also update the tabs data structure? Probably. */
/* Temporarily "use" window. */
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_new_root(window);
-
- if (uris && uris[0]) {
- for (i = 0; uris && uris[i]; ++i) {
- mq_tab_new_relative(uris[i], window->root_tab);
- }
- } else {
- mq_tab_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 *
@@ -252,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));
}
}
@@ -288,7 +398,7 @@ mq_window_get_current_tab(MqWindow *window)
guint
mq_window_get_num_tabs(MqWindow *window)
{
- return mq_tab_get_tree_size(window->root_tab) - 1;
+ return mq_tab_page_get_tree_size(window->root_tab) - 1;
}
void
@@ -302,17 +412,17 @@ mq_window_update_tab_title(MqWindow *window, guint position, const gchar *title)
void
mq_window_scroll_tab_labels(MqWindow *window)
{
- mq_tab_scroll_tab_labels(window->root_tab);
+ mq_tab_page_scroll_tab_labels(window->root_tab);
}
void
mq_window_begin_scrolling_tab_labels(MqWindow *window)
{
- mq_tab_begin_scrolling_tab_labels(window->root_tab);
+ mq_tab_page_begin_scrolling_tab_labels(window->root_tab);
}
void
mq_window_end_scrolling_tab_labels(MqWindow *window)
{
- mq_tab_end_scrolling_tab_labels(window->root_tab);
+ mq_tab_page_end_scrolling_tab_labels(window->root_tab);
}