summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGert Michael Kulyk <gkulyk@klio>2012-09-02 03:07:57 +0200
committerChristophe Fergeau <cfergeau@redhat.com>2014-01-23 16:15:33 +0100
commitac160474703a504436c6e3fae6e62ef5f98c2edf (patch)
tree4601d9220e661209934de3781a0d7583b17d0146
parent60c940d69785697ea1c45f05963aa7d2ba3dbfe5 (diff)
Store/restore the window size using gsettings
Part of the fixes for bgo #625897.
-rw-r--r--src/Makefile.am2
-rw-r--r--src/sj-main.c19
-rw-r--r--src/sj-window-prefs.c336
-rw-r--r--src/sj-window-prefs.h76
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__ */