diff --git a/src/gcal-application.c b/src/gcal-application.c index a3883667..4b1ec90e 100644 --- a/src/gcal-application.c +++ b/src/gcal-application.c @@ -74,14 +74,6 @@ static void gcal_application_changed_view (GSettings * gchar *key, gpointer user_data); -static gboolean gcal_application_window_state_changed (GtkWidget *widget, - GdkEvent *event, - gpointer user_data); - -static gboolean gcal_application_window_configured (GtkWidget *widget, - GdkEvent *event, - gpointer user_data); - G_DEFINE_TYPE_WITH_PRIVATE (GcalApplication, gcal_application, GTK_TYPE_APPLICATION); static gboolean show_version = FALSE; @@ -141,12 +133,6 @@ gcal_application_activate (GApplication *application) } else { - GVariant *variant; - gboolean maximized; - const gint32 *position; - const gint32 *size; - gsize n_elements; - priv->window = gcal_window_new_with_view (GCAL_APPLICATION (application), g_settings_get_enum (priv->settings, @@ -163,33 +149,7 @@ gcal_application_activate (GApplication *application) "enabled", G_BINDING_DEFAULT | G_BINDING_INVERT_BOOLEAN); - variant = g_settings_get_value (priv->settings, "window-size"); - size = g_variant_get_fixed_array (variant, &n_elements, sizeof (gint32)); - if (n_elements == 2) - gtk_window_set_default_size (GTK_WINDOW (priv->window), size[0], size[1]); - g_variant_unref (variant); - - variant = g_settings_get_value (priv->settings, "window-position"); - position = g_variant_get_fixed_array (variant, &n_elements, sizeof (gint32)); - if (n_elements == 2) - gtk_window_move (GTK_WINDOW (priv->window), position[0], position[1]); - g_variant_unref (variant); - - maximized = g_settings_get_boolean (priv->settings, "window-maximized"); - if (maximized) - gtk_window_maximize (GTK_WINDOW (priv->window)); - gtk_widget_show_all (priv->window); - - g_signal_connect (priv->window, - "window-state-event", - G_CALLBACK (gcal_application_window_state_changed), - application); - - g_signal_connect (priv->window, - "configure-event", - G_CALLBACK (gcal_application_window_configured), - application); } } @@ -437,59 +397,6 @@ gcal_application_changed_view (GSettings *settings, "active-view")); } -static gboolean -gcal_application_window_state_changed (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - GcalApplicationPrivate *priv; - GdkWindowState state; - gboolean maximized; - - priv = gcal_application_get_instance_private (GCAL_APPLICATION (user_data)); - state = gdk_window_get_state (gtk_widget_get_window (widget)); - maximized = state & GDK_WINDOW_STATE_MAXIMIZED; - - g_settings_set_boolean (priv->settings, "window-maximized", maximized); - - return FALSE; -} - -static gboolean -gcal_application_window_configured (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - GcalApplicationPrivate *priv; - GVariant *variant; - GdkWindowState state; - gint32 size[2]; - gint32 position[2]; - - priv = gcal_application_get_instance_private (GCAL_APPLICATION (user_data)); - state = gdk_window_get_state (gtk_widget_get_window (widget)); - if (state & GDK_WINDOW_STATE_MAXIMIZED) - return FALSE; - - gtk_window_get_size (GTK_WINDOW (priv->window), - (gint *) &size[0], - (gint *) &size[1]); - variant = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, - size, 2, - sizeof (size[0])); - g_settings_set_value (priv->settings, "window-size", variant); - - gtk_window_get_position (GTK_WINDOW (priv->window), - (gint *) &position[0], - (gint *) &position[1]); - variant = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, - position, 2, - sizeof (position[0])); - g_settings_set_value (priv->settings, "window-position", variant); - - return FALSE; -} - /* Public API */ GcalApplication* gcal_application_new (void) diff --git a/src/gcal-window.c b/src/gcal-window.c index 60f888cf..92ebe8ff 100644 --- a/src/gcal-window.c +++ b/src/gcal-window.c @@ -53,6 +53,9 @@ typedef struct _NewEventData NewEventData; typedef struct { + /* timeout ids */ + guint save_geometry_timeout_id; + /* upper level widgets */ GtkWidget *main_box; @@ -96,6 +99,8 @@ enum PROP_NEW_EVENT_MODE }; +#define SAVE_GEOMETRY_ID_TIMEOUT 100 /* ms */ + static gboolean key_pressed (GtkWidget *widget, GdkEventKey *event, gpointer user_data); @@ -103,6 +108,10 @@ static gboolean key_pressed (GtkWidget *w static void date_updated (GtkButton *buttton, gpointer user_data); +static void load_geometry (GcalWindow *window); + +static gboolean save_geometry (gpointer user_data); + static void update_view (GcalWindow *window); static void view_changed (GObject *object, @@ -149,6 +158,12 @@ static void gcal_window_get_property (GObject *o GValue *value, GParamSpec *pspec); +static gboolean gcal_window_configure_event (GtkWidget *widget, + GdkEventConfigure *event); + +static gboolean gcal_window_state_event (GtkWidget *widget, + GdkEventWindowState *event); + static void gcal_window_search_toggled (GObject *object, GParamSpec *pspec, gpointer user_data); @@ -252,6 +267,131 @@ date_updated (GtkButton *button, update_view (GCAL_WINDOW (user_data)); } +static void +load_geometry (GcalWindow *window) +{ + GcalApplication *app; + GSettings *settings; + GVariant *variant; + gboolean maximized; + const gint32 *position; + const gint32 *size; + gsize n_elements; + + app = GCAL_APPLICATION (gtk_window_get_application (GTK_WINDOW (window))); + settings = gcal_application_get_settings (app); + + /* load window settings: size */ + variant = g_settings_get_value (settings, + "window-size"); + size = g_variant_get_fixed_array (variant, + &n_elements, + sizeof (gint32)); + if (n_elements == 2) + gtk_window_set_default_size (GTK_WINDOW (window), + size[0], + size[1]); + g_variant_unref (variant); + + g_debug ("loaded window geometry -> size:[%d,%d]", + size[0], + size[1]); + + /* load window settings: position */ + variant = g_settings_get_value (settings, + "window-position"); + position = g_variant_get_fixed_array (variant, + &n_elements, + sizeof (gint32)); + if (n_elements == 2) + gtk_window_move (GTK_WINDOW (window), + position[0], + position[1]); + + g_variant_unref (variant); + + g_debug ("loaded window geometry -> position:[%d,%d]", + position[0], + position[1]); + + /* load window settings: state */ + maximized = g_settings_get_boolean (settings, + "window-maximized"); + if (maximized) + gtk_window_maximize (GTK_WINDOW (window)); + + g_debug ("loaded window geometry -> maximized:[%s]", + maximized ? "true" : "false"); +} + +static gboolean +save_geometry (gpointer user_data) +{ + GtkWindow *self; + GdkWindow *window; + GdkWindowState state; + GcalApplication *app; + GSettings *settings; + gboolean maximized; + GVariant *variant; + gint32 size[2]; + gint32 position[2]; + + self = GTK_WINDOW (user_data); + + window = gtk_widget_get_window (GTK_WIDGET (self)); + state = gdk_window_get_state (window); + + app = GCAL_APPLICATION (gtk_window_get_application (self)); + settings = gcal_application_get_settings (app); + + /* save window's state */ + maximized = state & GDK_WINDOW_STATE_MAXIMIZED; + g_settings_set_boolean (settings, + "window-maximized", + maximized); + + g_debug ("saved window geometry -> maximized:[%s]", + maximized ? "true" : "false"); + + if (maximized) + return FALSE; + + /* save window's size */ + gtk_window_get_size (self, + (gint *) &size[0], + (gint *) &size[1]); + variant = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, + size, + 2, + sizeof (size[0])); + g_settings_set_value (settings, + "window-size", + variant); + + g_debug ("saved window geometry -> size:[%d,%d]", + size[0], + size[1]); + + /* save windows's position */ + gtk_window_get_position (self, + (gint *) &position[0], + (gint *) &position[1]); + variant = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, + position, + 2, + sizeof (position[0])); + g_settings_set_value (settings, + "window-position", + variant); + + g_debug ("saved window geometry -> position:[%d,%d]", + position[0], + position[1]); + + return FALSE; +} + /** * update_view: * @window: @@ -547,6 +687,7 @@ static void gcal_window_class_init(GcalWindowClass *klass) { GObjectClass *object_class; + GtkWidgetClass *widget_class; object_class = G_OBJECT_CLASS (klass); object_class->constructed = gcal_window_constructed; @@ -554,6 +695,10 @@ gcal_window_class_init(GcalWindowClass *klass) object_class->set_property = gcal_window_set_property; object_class->get_property = gcal_window_get_property; + widget_class = GTK_WIDGET_CLASS (klass); + widget_class->configure_event = gcal_window_configure_event; + widget_class->window_state_event = gcal_window_state_event; + g_object_class_install_property ( object_class, PROP_ACTIVE_VIEW, @@ -586,7 +731,7 @@ gcal_window_class_init(GcalWindowClass *klass) } static void -gcal_window_init(GcalWindow *self) +gcal_window_init (GcalWindow *self) { GcalWindowPrivate *priv; @@ -598,6 +743,7 @@ gcal_window_init(GcalWindow *self) priv->event_creation_data = NULL; /* FIXME: Review real need of this */ + priv->save_geometry_timeout_id = 0; priv->event_to_delete = NULL; priv->open_edit_dialog = FALSE; } @@ -851,6 +997,58 @@ gcal_window_get_property (GObject *object, G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } +static gboolean +gcal_window_configure_event (GtkWidget *widget, + GdkEventConfigure *event) +{ + GcalWindow *window; + GcalWindowPrivate *priv; + gboolean retval; + + window = GCAL_WINDOW (widget); + priv = gcal_window_get_instance_private (window); + + if (priv->save_geometry_timeout_id != 0) + { + g_source_remove (priv->save_geometry_timeout_id); + priv->save_geometry_timeout_id = 0; + } + + priv->save_geometry_timeout_id = g_timeout_add (SAVE_GEOMETRY_ID_TIMEOUT, + save_geometry, + window); + + retval = GTK_WIDGET_CLASS (gcal_window_parent_class)->configure_event (widget, event); + + return retval; +} + +static gboolean +gcal_window_state_event (GtkWidget *widget, + GdkEventWindowState *event) +{ + GcalWindow *window; + GcalWindowPrivate *priv; + gboolean retval; + + window = GCAL_WINDOW (widget); + priv = gcal_window_get_instance_private (window); + + if (priv->save_geometry_timeout_id != 0) + { + g_source_remove (priv->save_geometry_timeout_id); + priv->save_geometry_timeout_id = 0; + } + + priv->save_geometry_timeout_id = g_timeout_add (SAVE_GEOMETRY_ID_TIMEOUT, + save_geometry, + window); + + retval = GTK_WIDGET_CLASS (gcal_window_parent_class)->window_state_event (widget, event); + + return retval; +} + static void gcal_window_search_toggled (GObject *object, GParamSpec *pspec, @@ -1426,6 +1624,8 @@ gcal_window_new_with_view (GcalApplication *app, win); /* init hack */ + load_geometry (win); + if (view_type == GCAL_WINDOW_VIEW_DAY) view_changed (NULL, NULL, win);