aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/empathy-geometry.c267
-rw-r--r--libempathy-gtk/empathy-geometry.h21
-rw-r--r--src/empathy-chat-window.c85
-rw-r--r--src/empathy-ft-manager.c59
-rw-r--r--src/empathy-main-window.c59
5 files changed, 184 insertions, 307 deletions
diff --git a/libempathy-gtk/empathy-geometry.c b/libempathy-gtk/empathy-geometry.c
index 14e794c44..a41a52d6c 100644
--- a/libempathy-gtk/empathy-geometry.c
+++ b/libempathy-gtk/empathy-geometry.c
@@ -29,6 +29,7 @@
#include <glib.h>
#include <gdk/gdk.h>
+#include "libempathy/empathy-utils.h"
#include "empathy-geometry.h"
#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
@@ -37,156 +38,212 @@
#define GEOMETRY_DIR_CREATE_MODE (S_IRUSR | S_IWUSR | S_IXUSR)
#define GEOMETRY_FILE_CREATE_MODE (S_IRUSR | S_IWUSR)
-#define GEOMETRY_KEY_FILENAME "geometry.ini"
-#define GEOMETRY_FORMAT "%d,%d,%d,%d"
-#define GEOMETRY_GROUP_NAME "geometry"
+#define GEOMETRY_KEY_FILENAME "geometry.ini"
+#define GEOMETRY_FORMAT "%d,%d,%d,%d"
+#define GEOMETRY_GROUP_NAME "geometry"
+#define GEOMETRY_MAXIMIZED_GROUP_NAME "maximized"
-static gchar *geometry_get_filename (void);
+static guint store_id = 0;
-static gchar *
-geometry_get_filename (void)
+static void
+geometry_real_store (GKeyFile *key_file)
{
- gchar *dir;
gchar *filename;
+ gchar *content;
+ gsize length;
+ GError *error = NULL;
- dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
- if (!g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
- DEBUG ("Creating directory:'%s'", dir);
- g_mkdir_with_parents (dir, GEOMETRY_DIR_CREATE_MODE);
+ content = g_key_file_to_data (key_file, &length, &error);
+ if (error != NULL) {
+ DEBUG ("Error: %s", error->message);
+ g_error_free (error);
+ return;
}
- filename = g_build_filename (dir, GEOMETRY_KEY_FILENAME, NULL);
- g_free (dir);
+ filename = g_build_filename (g_get_user_config_dir (),
+ PACKAGE_NAME, GEOMETRY_KEY_FILENAME, NULL);
- return filename;
+ if (!g_file_set_contents (filename, content, length, &error)) {
+ DEBUG ("Error: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (content);
+ g_free (filename);
}
-void
-empathy_geometry_save (const gchar *name,
- gint x,
- gint y,
- gint w,
- gint h)
+static gboolean
+geometry_store_cb (gpointer key_file)
{
- GError *error = NULL;
- GKeyFile *key_file;
- gchar *filename;
- GdkScreen *screen;
- gint max_width;
- gint max_height;
- gchar *content;
- gsize length;
- gchar *str;
- gchar *escaped_name;
+ geometry_real_store (key_file);
+ store_id = 0;
- /* escape the name so that unwanted characters such as # are removed */
- escaped_name = g_uri_escape_string (name, NULL, TRUE);
-
- DEBUG ("Saving window geometry: name:%s x:%d, y:%d, w:%d, h:%d\n",
- escaped_name, x, y, w, h);
+ return FALSE;
+}
- screen = gdk_screen_get_default ();
- max_width = gdk_screen_get_width (screen);
- max_height = gdk_screen_get_height (screen);
+static void
+geometry_schedule_store (GKeyFile *key_file)
+{
+ if (store_id != 0)
+ g_source_remove (store_id);
- w = CLAMP (w, 100, max_width);
- h = CLAMP (h, 100, max_height);
+ store_id = g_timeout_add_seconds (1, geometry_store_cb, key_file);
+}
- x = CLAMP (x, 0, max_width - w);
- y = CLAMP (y, 0, max_height - h);
+static GKeyFile *
+geometry_get_key_file (void)
+{
+ static GKeyFile *key_file = NULL;
+ gchar *dir;
+ gchar *filename;
- str = g_strdup_printf (GEOMETRY_FORMAT, x, y, w, h);
+ if (key_file != NULL)
+ return key_file;
- key_file = g_key_file_new ();
+ dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
+ if (!g_file_test (dir, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) {
+ DEBUG ("Creating directory:'%s'", dir);
+ g_mkdir_with_parents (dir, GEOMETRY_DIR_CREATE_MODE);
+ }
- filename = geometry_get_filename ();
+ filename = g_build_filename (dir, GEOMETRY_KEY_FILENAME, NULL);
+ g_free (dir);
+ key_file = g_key_file_new ();
g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL);
- g_key_file_set_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, str);
-
- g_free (str);
-
- content = g_key_file_to_data (key_file, &length, NULL);
- if (!g_file_set_contents (filename, content, length, &error)) {
- g_warning ("Couldn't save window geometry, error:%d->'%s'",
- error->code, error->message);
- g_error_free (error);
- }
-
- g_free (content);
g_free (filename);
- g_free (escaped_name);
- g_key_file_free (key_file);
+
+ return key_file;
}
void
-empathy_geometry_load (const gchar *name,
- gint *x,
- gint *y,
- gint *w,
- gint *h)
+empathy_geometry_save (GtkWindow *window,
+ const gchar *name)
{
- GKeyFile *key_file;
- gchar *filename;
- gchar *str = NULL;
- gchar *escaped_name;
+ GKeyFile *key_file;
+ GdkWindow *gdk_window;
+ GdkWindowState window_state;
+ gchar *escaped_name;
+ gint x, y, w, h;
+ gboolean maximized;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (!EMP_STR_EMPTY (name));
/* escape the name so that unwanted characters such as # are removed */
escaped_name = g_uri_escape_string (name, NULL, TRUE);
- if (x) {
- *x = -1;
- }
+ /* Get window geometry */
+ gtk_window_get_position (window, &x, &y);
+ gtk_window_get_size (window, &w, &h);
+ gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
+ window_state = gdk_window_get_state (gdk_window);
+ maximized = (window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
- if (y) {
- *y = -1;
- }
+ key_file = geometry_get_key_file ();
- if (w) {
- *w = -1;
- }
+ /* Save window size only if not maximized */
+ if (!maximized) {
+ gchar *str;
- if (h) {
- *h = -1;
+ str = g_strdup_printf (GEOMETRY_FORMAT, x, y, w, h);
+ g_key_file_set_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, str);
+ g_free (str);
}
- key_file = g_key_file_new ();
+ g_key_file_set_boolean (key_file, GEOMETRY_MAXIMIZED_GROUP_NAME,
+ escaped_name, maximized);
- filename = geometry_get_filename ();
+ geometry_schedule_store (key_file);
+}
- if (g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, NULL)) {
- str = g_key_file_get_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, NULL);
- }
+void
+empathy_geometry_load (GtkWindow *window,
+ const gchar *name)
+{
+ GKeyFile *key_file;
+ gchar *escaped_name;
+ gchar *str;
+ gboolean maximized;
+
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (!EMP_STR_EMPTY (name));
+
+ /* escape the name so that unwanted characters such as # are removed */
+ escaped_name = g_uri_escape_string (name, NULL, TRUE);
+ key_file = geometry_get_key_file ();
+
+ /* restore window size and position */
+ str = g_key_file_get_string (key_file, GEOMETRY_GROUP_NAME, escaped_name, NULL);
if (str) {
- gint tmp_x, tmp_y, tmp_w, tmp_h;
+ gint x, y, w, h;
- sscanf (str, GEOMETRY_FORMAT, &tmp_x, &tmp_y, &tmp_w, &tmp_h);
+ sscanf (str, GEOMETRY_FORMAT, &x, &y, &w, &h);
+ gtk_window_move (window, x, y);
+ gtk_window_resize (window, w, h);
+ }
- if (x) {
- *x = tmp_x;
- }
+ /* restore window maximized state */
+ maximized = g_key_file_get_boolean (key_file,
+ GEOMETRY_MAXIMIZED_GROUP_NAME,
+ escaped_name, NULL);
+ if (maximized)
+ gtk_window_maximize (window);
+ else
+ gtk_window_unmaximize (window);
- if (y) {
- *y = tmp_y;
- }
+ g_free (str);
+ g_free (escaped_name);
+}
- if (w) {
- *w = tmp_w;
- }
+static gboolean
+geometry_configure_event_cb (GtkWindow *window,
+ GdkEventConfigure *event,
+ gchar *name)
+{
+ empathy_geometry_save (window, name);
+ return FALSE;
+}
- if (h) {
- *h = tmp_h;
- }
+static gboolean
+geometry_window_state_event_cb (GtkWindow *window,
+ GdkEventWindowState *event,
+ gchar *name)
+{
+ if ((event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) != 0)
+ empathy_geometry_save (window, name);
- g_free (str);
- }
+ return FALSE;
+}
- DEBUG ("Loading window geometry: x:%d, y:%d, w:%d, h:%d\n",
- x ? *x : -1, y ? *y : -1, w ? *w : -1, h ? *h : -1);
+void
+empathy_geometry_bind (GtkWindow *window,
+ const gchar *name)
+{
+ g_return_if_fail (GTK_IS_WINDOW (window));
+ g_return_if_fail (!EMP_STR_EMPTY (name));
+
+ /* First load initial geometry */
+ empathy_geometry_load (window, name);
+
+ /* Track geometry changes */
+ g_signal_connect_data (window, "configure-event",
+ G_CALLBACK (geometry_configure_event_cb), g_strdup (name),
+ (GClosureNotify) g_free, 0);
+ g_signal_connect_data (window, "window-state-event",
+ G_CALLBACK (geometry_window_state_event_cb), g_strdup (name),
+ (GClosureNotify) g_free, 0);
+}
- g_free (filename);
- g_free (escaped_name);
- g_key_file_free (key_file);
+void
+empathy_geometry_unbind (GtkWindow *window)
+{
+ g_signal_handlers_disconnect_matched (window,
+ G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ geometry_configure_event_cb, NULL);
+ g_signal_handlers_disconnect_matched (window,
+ G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ geometry_window_state_event_cb, NULL);
}
diff --git a/libempathy-gtk/empathy-geometry.h b/libempathy-gtk/empathy-geometry.h
index b7bd86bc2..2bb923b6c 100644
--- a/libempathy-gtk/empathy-geometry.h
+++ b/libempathy-gtk/empathy-geometry.h
@@ -26,19 +26,20 @@
#define __EMPATHY_GEOMETRY_H__
#include <glib.h>
+#include <gtk/gtk.h>
G_BEGIN_DECLS
-void empathy_geometry_save (const gchar *name,
- gint x,
- gint y,
- gint w,
- gint h);
-void empathy_geometry_load (const gchar *name,
- gint *x,
- gint *y,
- gint *w,
- gint *h);
+void empathy_geometry_save (GtkWindow *window,
+ const gchar *name);
+
+void empathy_geometry_load (GtkWindow *window,
+ const gchar *name);
+
+void empathy_geometry_bind (GtkWindow *window,
+ const gchar *name);
+
+void empathy_geometry_unbind (GtkWindow *window);
G_END_DECLS
diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c
index 4d99afd31..ca3375306 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -73,7 +73,6 @@ typedef struct {
GList *chats_composing;
gboolean page_added;
gboolean dnd_same_window;
- guint save_geometry_id;
EmpathyChatroomManager *chatroom_manager;
EmpathyNotifyManager *notify_mgr;
GtkWidget *dialog;
@@ -725,63 +724,6 @@ chat_window_contacts_toggled_cb (GtkToggleAction *toggle_action,
empathy_chat_set_show_contacts (priv->current_chat, active);
}
-static const gchar *
-chat_get_window_id_for_geometry (EmpathyChat *chat)
-{
- const gchar *res = NULL;
- gboolean separate_windows;
-
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS,
- &separate_windows);
-
- if (separate_windows) {
- res = empathy_chat_get_id (chat);
- }
-
- return res ? res : "chat-window";
-}
-
-static gboolean
-chat_window_save_geometry_timeout_cb (EmpathyChatWindow *window)
-{
- EmpathyChatWindowPriv *priv;
- gint x, y, w, h;
-
- priv = GET_PRIV (window);
-
- gtk_window_get_size (GTK_WINDOW (priv->dialog), &w, &h);
- gtk_window_get_position (GTK_WINDOW (priv->dialog), &x, &y);
-
- empathy_geometry_save (chat_get_window_id_for_geometry (priv->current_chat),
- x, y, w, h);
-
- priv->save_geometry_id = 0;
-
- return FALSE;
-}
-
-static gboolean
-chat_window_configure_event_cb (GtkWidget *widget,
- GdkEventConfigure *event,
- EmpathyChatWindow *window)
-{
- EmpathyChatWindowPriv *priv;
-
- priv = GET_PRIV (window);
-
- if (priv->save_geometry_id != 0) {
- g_source_remove (priv->save_geometry_id);
- }
-
- priv->save_geometry_id =
- g_timeout_add_seconds (1,
- (GSourceFunc) chat_window_save_geometry_timeout_cb,
- window);
-
- return FALSE;
-}
-
static void
chat_window_close_activate_cb (GtkAction *action,
EmpathyChatWindow *window)
@@ -1511,10 +1453,6 @@ chat_window_finalize (GObject *object)
g_object_unref (priv->ui_manager);
g_object_unref (priv->chatroom_manager);
g_object_unref (priv->notify_mgr);
- if (priv->save_geometry_id != 0) {
- g_source_remove (priv->save_geometry_id);
- chat_window_save_geometry_timeout_cb (window);
- }
if (priv->notification != NULL) {
notify_notification_close (priv->notification, NULL);
@@ -1591,7 +1529,6 @@ empathy_chat_window_init (EmpathyChatWindow *window)
g_free (filename);
empathy_builder_connect (gui, window,
- "chat_window", "configure-event", chat_window_configure_event_cb,
"menu_conv", "activate", chat_window_conv_activate_cb,
"menu_conv_clear", "activate", chat_window_clear_activate_cb,
"menu_conv_favorite", "toggled", chat_window_favorite_toggled_cb,
@@ -1758,7 +1695,6 @@ empathy_chat_window_add_chat (EmpathyChatWindow *window,
GtkWidget *label;
GtkWidget *popup_label;
GtkWidget *child;
- gint x, y, w, h;
g_return_if_fail (window != NULL);
g_return_if_fail (EMPATHY_IS_CHAT (chat));
@@ -1770,21 +1706,18 @@ empathy_chat_window_add_chat (EmpathyChatWindow *window,
/* If this window has just been created, position it */
if (priv->chats == NULL) {
- empathy_geometry_load (chat_get_window_id_for_geometry (chat), &x, &y, &w, &h);
+ const gchar *name = "chat-window";
+ gboolean separate_windows;
- if (x >= 0 && y >= 0) {
- /* Let the window manager position it if we don't have
- * good x, y coordinates.
- */
- gtk_window_move (GTK_WINDOW (priv->dialog), x, y);
- }
+ empathy_conf_get_bool (empathy_conf_get (),
+ EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS,
+ &separate_windows);
- if (w > 0 && h > 0) {
- /* Use the defaults from the ui file if we don't have
- * good w, h geometry.
- */
- gtk_window_resize (GTK_WINDOW (priv->dialog), w, h);
+ if (separate_windows) {
+ name = empathy_chat_get_id (chat);
}
+
+ empathy_geometry_bind (GTK_WINDOW (priv->dialog), name);
}
child = GTK_WIDGET (chat);
diff --git a/src/empathy-ft-manager.c b/src/empathy-ft-manager.c
index ff12c9b6b..e681f8441 100644
--- a/src/empathy-ft-manager.c
+++ b/src/empathy-ft-manager.c
@@ -66,8 +66,6 @@ typedef struct {
GtkWidget *open_button;
GtkWidget *abort_button;
GtkWidget *clear_button;
-
- guint save_geometry_id;
} EmpathyFTManagerPriv;
enum
@@ -868,38 +866,6 @@ ft_manager_stop (EmpathyFTManager *manager)
g_object_unref (handler);
}
-static gboolean
-ft_manager_save_geometry_timeout_cb (EmpathyFTManager *manager)
-{
- EmpathyFTManagerPriv *priv = GET_PRIV (manager);
- gint x, y, w, h;
-
- gtk_window_get_size (GTK_WINDOW (priv->window), &w, &h);
- gtk_window_get_position (GTK_WINDOW (priv->window), &x, &y);
-
- empathy_geometry_save ("ft-manager", x, y, w, h);
-
- priv->save_geometry_id = 0;
-
- return FALSE;
-}
-
-static gboolean
-ft_manager_configure_event_cb (GtkWidget *widget,
- GdkEventConfigure *event,
- EmpathyFTManager *manager)
-{
- EmpathyFTManagerPriv *priv = GET_PRIV (manager);
-
- if (priv->save_geometry_id != 0)
- g_source_remove (priv->save_geometry_id);
-
- priv->save_geometry_id = g_timeout_add (500,
- (GSourceFunc) ft_manager_save_geometry_timeout_cb, manager);
-
- return FALSE;
-}
-
static void
ft_manager_response_cb (GtkWidget *widget,
gint response,
@@ -970,7 +936,6 @@ static void
ft_manager_build_ui (EmpathyFTManager *manager)
{
GtkBuilder *gui;
- gint x, y, w, h;
GtkTreeView *view;
GtkListStore *liststore;
GtkTreeViewColumn *column;
@@ -993,28 +958,13 @@ ft_manager_build_ui (EmpathyFTManager *manager)
"ft_manager_dialog", "destroy", ft_manager_destroy_cb,
"ft_manager_dialog", "response", ft_manager_response_cb,
"ft_manager_dialog", "delete-event", ft_manager_delete_event_cb,
- "ft_manager_dialog", "configure-event", ft_manager_configure_event_cb,
"ft_manager_dialog", "key-press-event", ft_manager_key_press_event_cb,
NULL);
empathy_builder_unref_and_keep_widget (gui, priv->window);
/* Window geometry. */
- empathy_geometry_load ("ft-manager", &x, &y, &w, &h);
-
- if (x >= 0 && y >= 0)
- {
- /* Let the window manager position it if we don't have
- * good x, y coordinates. */
- gtk_window_move (GTK_WINDOW (priv->window), x, y);
- }
-
- if (w > 0 && h > 0)
- {
- /* Use the defaults from the ui file if we don't have
- * good w, h geometry. */
- gtk_window_resize (GTK_WINDOW (priv->window), w, h);
- }
+ empathy_geometry_bind (GTK_WINDOW (priv->window), "ft-manager");
/* Setup the tree view */
view = GTK_TREE_VIEW (priv->treeview);
@@ -1093,19 +1043,12 @@ ft_manager_build_ui (EmpathyFTManager *manager)
static void
empathy_ft_manager_finalize (GObject *object)
{
- EmpathyFTManager *self = EMPATHY_FT_MANAGER (object);
EmpathyFTManagerPriv *priv = GET_PRIV (object);
DEBUG ("FT Manager %p", object);
g_hash_table_destroy (priv->ft_handler_to_row_ref);
- if (priv->save_geometry_id != 0)
- {
- g_source_remove (priv->save_geometry_id);
- ft_manager_save_geometry_timeout_cb (self);
- }
-
G_OBJECT_CLASS (empathy_ft_manager_parent_class)->finalize (object);
}
diff --git a/src/empathy-main-window.c b/src/empathy-main-window.c
index 473e47706..2a316b99e 100644
--- a/src/empathy-main-window.c
+++ b/src/empathy-main-window.c
@@ -117,9 +117,6 @@ typedef struct {
static EmpathyMainWindow *main_window = NULL;
-static gboolean main_window_configure_event_timeout_cb (
- EmpathyMainWindow *window);
-
static void
main_window_flash_stop (EmpathyMainWindow *window)
{
@@ -659,11 +656,6 @@ main_window_destroy_cb (GtkWidget *widget,
/* Save user-defined accelerators. */
main_window_accels_save ();
- if (window->size_timeout_id) {
- g_source_remove (window->size_timeout_id);
- main_window_configure_event_timeout_cb (window);
- }
-
g_list_free (window->actions_connected);
g_object_unref (window->account_manager);
@@ -1104,37 +1096,6 @@ main_window_throbber_button_press_event_cb (GtkWidget *throbber_ebox,
return FALSE;
}
-static gboolean
-main_window_configure_event_timeout_cb (EmpathyMainWindow *window)
-{
- gint x, y, w, h;
-
- gtk_window_get_size (GTK_WINDOW (window->window), &w, &h);
- gtk_window_get_position (GTK_WINDOW (window->window), &x, &y);
-
- empathy_geometry_save (GEOMETRY_NAME, x, y, w, h);
-
- window->size_timeout_id = 0;
-
- return FALSE;
-}
-
-static gboolean
-main_window_configure_event_cb (GtkWidget *widget,
- GdkEventConfigure *event,
- EmpathyMainWindow *window)
-{
- if (window->size_timeout_id) {
- g_source_remove (window->size_timeout_id);
- }
-
- window->size_timeout_id = g_timeout_add_seconds (1,
- (GSourceFunc) main_window_configure_event_timeout_cb,
- window);
-
- return FALSE;
-}
-
static void
main_window_account_removed_cb (TpAccountManager *manager,
TpAccount *account,
@@ -1247,7 +1208,6 @@ empathy_main_window_show (void)
GtkAction *show_map_widget;
GtkToolItem *item;
gboolean show_offline;
- gint x, y, w, h;
gchar *filename;
GSList *l;
@@ -1282,7 +1242,6 @@ empathy_main_window_show (void)
empathy_builder_connect (gui, window,
"main_window", "destroy", main_window_destroy_cb,
- "main_window", "configure_event", main_window_configure_event_cb,
"chat_quit", "activate", main_window_chat_quit_cb,
"chat_new_message", "activate", main_window_chat_new_message_cb,
"view_history", "activate", main_window_view_history_cb,
@@ -1388,23 +1347,7 @@ empathy_main_window_show (void)
main_window_accels_load ();
/* Set window size. */
- empathy_geometry_load (GEOMETRY_NAME, &x, &y, &w, &h);
-
- if (w >= 1 && h >= 1) {
- /* Use the defaults from the ui file if we
- * don't have good w, h geometry.
- */
- DEBUG ("Configuring window default size w:%d, h:%d", w, h);
- gtk_window_set_default_size (GTK_WINDOW (window->window), w, h);
- }
-
- if (x >= 0 && y >= 0) {
- /* Let the window manager position it if we
- * don't have good x, y coordinates.
- */
- DEBUG ("Configuring window default position x:%d, y:%d", x, y);
- gtk_window_move (GTK_WINDOW (window->window), x, y);
- }
+ empathy_geometry_bind (GTK_WINDOW (window->window), GEOMETRY_NAME);
/* Enable event handling */
window->event_manager = empathy_event_manager_dup_singleton ();