diff options
author | Gert Michael Kulyk <gkulyk@klio> | 2012-09-02 03:07:57 +0200 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2014-01-23 16:15:33 +0100 |
commit | ac160474703a504436c6e3fae6e62ef5f98c2edf (patch) | |
tree | 4601d9220e661209934de3781a0d7583b17d0146 | |
parent | 60c940d69785697ea1c45f05963aa7d2ba3dbfe5 (diff) |
Store/restore the window size using gsettings
Part of the fixes for bgo #625897.
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/sj-main.c | 19 | ||||
-rw-r--r-- | src/sj-window-prefs.c | 336 | ||||
-rw-r--r-- | src/sj-window-prefs.h | 76 |
4 files changed, 424 insertions, 9 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 37b2d9c..d11218c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,6 +16,8 @@ sound_juicer_SOURCES = \ sj-inhibit.c \ sj-genres.h \ sj-genres.c \ + sj-window-prefs.h \ + sj-window-prefs.c \ egg-play-preview.c \ egg-play-preview.h diff --git a/src/sj-main.c b/src/sj-main.c index 33df6f8..cf10402 100644 --- a/src/sj-main.c +++ b/src/sj-main.c @@ -52,6 +52,7 @@ #include "sj-prefs.h" #include "sj-play.h" #include "sj-genres.h" +#include "sj-window-prefs.h" gboolean on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data); @@ -1315,9 +1316,9 @@ static void reread_cd (gboolean ignore_no_media) } static void -media_added_cb (BraseroMediumMonitor *drive, - BraseroMedium *medium, - gpointer data) +media_added_cb (BraseroMediumMonitor *drive, + BraseroMedium *medium, + gpointer data) { if (extracting == TRUE) { /* FIXME: recover? */ @@ -1328,9 +1329,9 @@ media_added_cb (BraseroMediumMonitor *drive, } static void -media_removed_cb (BraseroMediumMonitor *drive, - BraseroMedium *medium, - gpointer data) +media_removed_cb (BraseroMediumMonitor *drive, + BraseroMedium *medium, + gpointer data) { if (extracting == TRUE) { /* FIXME: recover? */ @@ -1943,8 +1944,8 @@ is_cd_duplication_available(void) /* Now check that there is at least one cd recorder available */ BraseroMediumMonitor *monitor; - GSList *drives; - GSList *iter; + GSList *drives; + GSList *iter; monitor = brasero_medium_monitor_get_default (); drives = brasero_medium_monitor_get_drives (monitor, BRASERO_DRIVE_TYPE_ALL); @@ -2299,7 +2300,7 @@ startup_cb (GApplication *app, gpointer user_data) set_action_enabled ("duplicate", FALSE); duplication_enabled = is_cd_duplication_available(); - /*gconf_bridge_bind_window_size(gconf_bridge_get(), GCONF_WINDOW, GTK_WINDOW (main_window));*/ + sj_window_prefs_bind_window_size(sj_window_prefs_get(), GTK_WINDOW (main_window)); gtk_application_add_window (GTK_APPLICATION (app), GTK_WINDOW (main_window)); gtk_widget_show (main_window); diff --git a/src/sj-window-prefs.c b/src/sj-window-prefs.c new file mode 100644 index 0000000..886aebf --- /dev/null +++ b/src/sj-window-prefs.c @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2005 OpenedHand Ltd. + * Copyright (C) 2012 Gert Michael Kulyk <gkulyk@yahoo.de> + * + * Sound Juicer - sj-window-prefs.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Authors: Jorn Baayen <jorn@openedhand.com> + * Gert Michael Kulyk <gkulyk@yahoo.de> + * + * This file is based on gconf-prefs.c, (C) 2005 OpenedHand Ltd. + * Original Author: Jorn Baayen <jorn@openedhand.com> + * + */ + +#include <config.h> + +#include <gtk/gtk.h> +#include <string.h> +#include <stdlib.h> + +#include "sj-window-prefs.h" + +struct _SJWindowPrefs { + GSettings *settings; + + GHashTable *bindings; +}; + +typedef enum { + BINDING_PROP, + BINDING_WINDOW, + BINDING_LIST_STORE +} BindingType; + +typedef struct { + BindingType type; + guint id; + + gboolean bind_size; + gboolean bind_pos; + + GtkWindow *window; + gulong configure_event_id; + gulong unmap_id; + guint sync_timeout_id; +} WindowBinding; + +static SJWindowPrefs *prefs = NULL; /* Global SJWindowPrefs object */ + +/* Generate an ID for a new binding */ +static guint +new_id (void) +{ + static guint id_counter = 0; + + id_counter++; + + return id_counter; +} + +/* + * Window bindings + */ + +/* Performs a scheduled dimensions-to-prefs sync for a window binding */ +static gboolean +window_binding_perform_scheduled_sync (WindowBinding *binding) +{ + if (binding->bind_size) { + int width, height; + GdkWindowState state; + + state = gdk_window_get_state (gtk_widget_get_window (GTK_WIDGET (binding->window))); + + if (state & GDK_WINDOW_STATE_MAXIMIZED) { + g_settings_set_boolean (prefs->settings, "maximized", TRUE); + } else { + gtk_window_get_size (binding->window, &width, &height); + + g_settings_set_int (prefs->settings, "width", width); + + g_settings_set_int (prefs->settings, "height", height); + + g_settings_set_boolean (prefs->settings, "maximized", FALSE); + } + } + + if (binding->bind_pos) { + int x, y; + + gtk_window_get_position (binding->window, &x, &y); + + g_settings_set_int (prefs->settings, "position-x", x); + + g_settings_set_int (prefs->settings, "position-y", y); + } + + binding->sync_timeout_id = 0; + + return FALSE; +} + +#define WINDOW_BINDING_SYNC_DELAY 1000 /* Delay before syncing new window + dimensions to GSettings, in ms */ + +/* Called when the window han been resized or moved */ +static gboolean +window_binding_configure_event_cb (GtkWindow *window, + GdkEventConfigure *event, + WindowBinding *binding) +{ + /* Schedule a sync */ + if (binding->sync_timeout_id == 0) { + binding->sync_timeout_id = + g_timeout_add (WINDOW_BINDING_SYNC_DELAY, + (GSourceFunc) + window_binding_perform_scheduled_sync, + binding); + } + + return FALSE; +} + +/* Called when the window state is being changed */ +static gboolean +window_binding_state_event_cb (GtkWindow *window, + GdkEventWindowState *event, + WindowBinding *binding) +{ + window_binding_perform_scheduled_sync (binding); + + return FALSE; +} + +/* Called when the window is being unmapped */ +static gboolean +window_binding_unmap_cb (GtkWindow *window, + WindowBinding *binding) +{ + /* Force sync */ + if (binding->sync_timeout_id > 0) + g_source_remove (binding->sync_timeout_id); + + window_binding_perform_scheduled_sync (binding); + + return FALSE; +} + +/* Called when a window is destroyed */ +static void +window_binding_window_destroyed (gpointer user_data, + GObject *where_the_object_was) +{ + WindowBinding *binding; + + binding = (WindowBinding *) user_data; + binding->window = NULL; /* Don't do anything with the window + at unbind() */ + + g_hash_table_remove (prefs->bindings, + GUINT_TO_POINTER (binding->id)); +} + +/** + * sj_window_prefs_bind_window + * @prefs: A #SJWindowPrefs + * @window: A #GtkWindow + * @bind_size: TRUE to bind the size of @window + * @bind_pos: TRUE to bind the position of @window + * + * On calling this function @window will be resized to the values + * specified by "@key_prefix<!-- -->_width" and "@key_prefix<!-- -->_height" + * and maximixed if "@key_prefix<!-- -->_maximized is TRUE if + * @bind_size is TRUE, and moved to the values specified by + * "@key_prefix<!-- -->_x" and "@key_prefix<!-- -->_y" if @bind_pos is TRUE. + * The respective GSettings keys will be updated when the window is resized + * and/or moved. + * + * Return value: The ID of the new binding. + **/ +guint +sj_window_prefs_bind_window (SJWindowPrefs *prefs, + GtkWindow *window, + gboolean bind_size, + gboolean bind_pos) +{ + WindowBinding *binding; + + g_return_val_if_fail (prefs != NULL, 0); + g_return_val_if_fail (GTK_IS_WINDOW (window), 0); + + /* Create new binding. */ + binding = g_new (WindowBinding, 1); + + binding->type = BINDING_WINDOW; + binding->id = new_id (); + binding->bind_size = bind_size; + binding->bind_pos = bind_pos; + binding->window = window; + binding->sync_timeout_id = 0; + + /* Set up keys & sync window to GSettings values */ + if (bind_size) { + int width_val, height_val; + gboolean maximized_val; + + width_val = g_settings_get_int (prefs->settings, "width"); + + height_val = g_settings_get_int (prefs->settings, "height"); + + maximized_val = g_settings_get_boolean (prefs->settings, "maximized"); + + if (width_val && height_val) { + gtk_window_resize (window, width_val, height_val); + } + + if (maximized_val) { + if (maximized_val) { + gtk_window_maximize (window); + } + } + } + + if (bind_pos) { + int x_val, y_val; + + x_val = g_settings_get_int (prefs->settings, "position-x"); + + y_val = g_settings_get_int (prefs->settings, "position-y"); + + if (x_val && y_val) { + gtk_window_move (window, x_val, y_val); + } + } + + /* Connect to window size change notifications */ + binding->configure_event_id = + g_signal_connect (window, + "configure-event", + G_CALLBACK + (window_binding_configure_event_cb), + binding); + + binding->configure_event_id = + g_signal_connect (window, + "window_state_event", + G_CALLBACK + (window_binding_state_event_cb), + binding); + binding->unmap_id = + g_signal_connect (window, + "unmap", + G_CALLBACK (window_binding_unmap_cb), + binding); + + /* Handle case where window gets destroyed */ + g_object_weak_ref (G_OBJECT (window), + window_binding_window_destroyed, binding); + + /* Insert binding */ + g_hash_table_insert (prefs->bindings, + GUINT_TO_POINTER (binding->id), binding); + + /* Done */ + return binding->id; +} + +/* Unbinds a window binding */ +static void +window_binding_unbind (WindowBinding *binding) +{ + if (binding->sync_timeout_id > 0) + g_source_remove (binding->sync_timeout_id); + + /* The window might have been destroyed .. */ + if (binding->window) { + g_signal_handler_disconnect (binding->window, + binding->configure_event_id); + g_signal_handler_disconnect (binding->window, + binding->unmap_id); + + g_object_weak_unref (G_OBJECT (binding->window), + window_binding_window_destroyed, binding); + } + g_free (binding); +} + +/* Free up all resources allocated by the SJWindowPrefs. Called on exit. */ +static void +destroy_prefs (void) +{ + g_hash_table_destroy (prefs->bindings); + + if (prefs->settings) + g_object_unref (prefs->settings); + + g_free (prefs); +} + +/** + * sj_window_prefs_get + * + * Returns the #SJWindowPrefs. This is a singleton object. + * + * Return value: The #SJWindowPrefs. + **/ +SJWindowPrefs * +sj_window_prefs_get (void) +{ + if (prefs) + return prefs; + + prefs = g_new (SJWindowPrefs, 1); + + prefs->settings = g_settings_new ("org.gnome.SoundJuicer"); + prefs->bindings = g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) window_binding_unbind); + + atexit (destroy_prefs); + + return prefs; +} diff --git a/src/sj-window-prefs.h b/src/sj-window-prefs.h new file mode 100644 index 0000000..884de7b --- /dev/null +++ b/src/sj-window-prefs.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2005 OpenedHand Ltd. + * Copyright (C) 2012 Gert Michael Kulyk <gkulyk@yahoo.de> + * + * Sound Juicer - sj-window-prefs.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Authors: Jorn Baayen <jorn@openedhand.com> + * Gert Michael Kulyk <gkulyk@yahoo.de> + * + * This file is based on gconf-prefs.c, (C) 2005 OpenedHand Ltd. + * Original Author: Jorn Baayen <jorn@openedhand.com> + * + */ + +#ifndef __SJ_WINDOW_PREFS_H__ +#define __SJ_WINDOW_PREFS_H__ + +#include <glib.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS + + +typedef struct _SJWindowPrefs SJWindowPrefs; + +SJWindowPrefs *sj_window_prefs_get (void); + +guint sj_window_prefs_bind_window (SJWindowPrefs *prefs, + GtkWindow *window, + gboolean bind_size, + gboolean bind_pos); + +/** + * sj_window_prefs_bind_window_size + * @prefs: A #SJWindowPrefs + * @window: A #GtkWindow + * + * On calling this function @window will be resized to the values specified by + * "width" and "height". The respective + * GSettings values will be updated when the window is resized. See + * #sj_window_prefs_bind_window for more details. + **/ +#define sj_window_prefs_bind_window_size(prefs, window) \ + sj_window_prefs_bind_window ((prefs), (window), TRUE, FALSE) + +/** + * sj_window_prefs_bind_window_pos + * @prefs: A #SJWindowPrefs + * @window: A #GtkWindow + * + * On calling this function @window will be moved to the values specified by + * "position-x" and "position-y". The respective + * values will be updated when the window is moved. See + * #sj_window_prefs_bind_window for more details. + **/ +#define sj_window_prefs_bind_window_pos(prefs, window) \ + sj_window_prefs_bind_window ((prefs), (window), FALSE, TRUE) + + +G_END_DECLS + +#endif /* __SJ_WINDOW_PREFS_H__ */ |