[gimp] Bug 602223 - Can't hide docks with Tab in single-window mode
- From: Martin Nordholts <martinn src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 602223 - Can't hide docks with Tab in single-window mode
- Date: Wed, 24 Feb 2010 18:51:20 +0000 (UTC)
commit 18f3be6bd3438c828648a93174595ebd3f4a632c
Author: Martin Nordholts <martinn src gnome org>
Date: Tue Feb 23 20:21:08 2010 +0100
Bug 602223 - Can't hide docks with Tab in single-window mode
Add a "hide-docks" config and connect the Windows->Hide docks menu
item to it. Also connect the image window to the config property so it
can hide/show its docks when it needs to.
Also add and use a utility function
gimp_image_window_keep_canvas_pos() to ensure that the image in the
window remains fixed when toggling visiblity of docks. One problem:
When GimpDrawTool is active on the canvas, there is flicker. The end
position is correct though.
Also add regression testing for this fix to test-ui.c
app/actions/windows-actions.c | 3 +-
app/actions/windows-commands.c | 9 ++++
app/config/gimpguiconfig.c | 12 +++++
app/config/gimpguiconfig.h | 1 +
app/config/gimprc-blurbs.h | 3 +
app/display/gimpimagewindow.c | 95 ++++++++++++++++++++++++++++++++++++++-
app/tests/test-ui.c | 94 +++++++++++++++++++++++++++++++++++++--
7 files changed, 207 insertions(+), 10 deletions(-)
---
diff --git a/app/actions/windows-actions.c b/app/actions/windows-actions.c
index 8a9832c..bb4dc37 100644
--- a/app/actions/windows-actions.c
+++ b/app/actions/windows-actions.c
@@ -201,8 +201,7 @@ windows_actions_update (GimpActionGroup *group,
gimp_action_group_set_action_active (group, action, (condition) != 0)
SET_ACTIVE ("windows-use-single-window-mode", config->single_window_mode);
- SET_ACTIVE ("windows-hide-docks", (gimp_dialog_factories_get_state () !=
- GIMP_DIALOGS_SHOWN));
+ SET_ACTIVE ("windows-hide-docks", config->hide_docks);
#undef SET_ACTIVE
}
diff --git a/app/actions/windows-commands.c b/app/actions/windows-commands.c
index 7525c44..4c6890c 100644
--- a/app/actions/windows-commands.c
+++ b/app/actions/windows-commands.c
@@ -56,6 +56,11 @@ windows_hide_docks_cmd_callback (GtkAction *action,
gboolean active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
GimpDialogsState state = gimp_dialog_factories_get_state ();
GimpDialogsState new_state = state;
+ Gimp *gimp = NULL;
+ return_if_no_gimp (gimp, data);
+
+ if (GIMP_GUI_CONFIG (gimp->config)->hide_docks == active)
+ return;
/* Make sure the state and toggle action are in sync */
if (active && state == GIMP_DIALOGS_SHOWN)
@@ -65,6 +70,10 @@ windows_hide_docks_cmd_callback (GtkAction *action,
if (state != new_state)
gimp_dialog_factories_set_state (new_state);
+
+ g_object_set (gimp->config,
+ "hide-docks", active,
+ NULL);
}
void
diff --git a/app/config/gimpguiconfig.c b/app/config/gimpguiconfig.c
index 287dfca..d69aef2 100644
--- a/app/config/gimpguiconfig.c
+++ b/app/config/gimpguiconfig.c
@@ -52,6 +52,7 @@ enum
PROP_RESTORE_SESSION,
PROP_SAVE_TOOL_OPTIONS,
PROP_SHOW_TOOLTIPS,
+ PROP_HIDE_DOCKS,
PROP_SINGLE_WINDOW_MODE,
PROP_TEAROFF_MENUS,
PROP_CAN_CHANGE_ACCELS,
@@ -154,6 +155,11 @@ gimp_gui_config_class_init (GimpGuiConfigClass *klass)
TRUE,
GIMP_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_RESTART);
+ GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_HIDE_DOCKS,
+ "hide-docks", HIDE_DOCKS_BLURB,
+ FALSE,
+ GIMP_PARAM_STATIC_STRINGS |
+ GIMP_CONFIG_PARAM_RESTART);
GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_SINGLE_WINDOW_MODE,
"single-window-mode", SINGLE_WINDOW_MODE_BLURB,
FALSE,
@@ -353,6 +359,9 @@ gimp_gui_config_set_property (GObject *object,
case PROP_SHOW_TOOLTIPS:
gui_config->show_tooltips = g_value_get_boolean (value);
break;
+ case PROP_HIDE_DOCKS:
+ gui_config->hide_docks = g_value_get_boolean (value);
+ break;
case PROP_SINGLE_WINDOW_MODE:
gui_config->single_window_mode = g_value_get_boolean (value);
break;
@@ -474,6 +483,9 @@ gimp_gui_config_get_property (GObject *object,
case PROP_SHOW_TOOLTIPS:
g_value_set_boolean (value, gui_config->show_tooltips);
break;
+ case PROP_HIDE_DOCKS:
+ g_value_set_boolean (value, gui_config->hide_docks);
+ break;
case PROP_SINGLE_WINDOW_MODE:
g_value_set_boolean (value, gui_config->single_window_mode);
break;
diff --git a/app/config/gimpguiconfig.h b/app/config/gimpguiconfig.h
index 1e6d7f7..5126c65 100644
--- a/app/config/gimpguiconfig.h
+++ b/app/config/gimpguiconfig.h
@@ -46,6 +46,7 @@ struct _GimpGuiConfig
gboolean restore_session;
gboolean save_tool_options;
gboolean show_tooltips;
+ gboolean hide_docks;
gboolean single_window_mode;
gboolean tearoff_menus;
gboolean can_change_accels;
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index 6a269af..746ee82 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -361,6 +361,9 @@ N_("Show a tooltip when the pointer hovers over an item.")
#define SINGLE_WINDOW_MODE_BLURB \
N_("Use GIMP in a single-window mode.")
+#define HIDE_DOCKS_BLURB \
+N_("Hide docks and other windows, leaving only image windows.")
+
#define SPACE_BAR_ACTION_BLURB \
N_("What to do when the space bar is pressed in the image window.")
diff --git a/app/display/gimpimagewindow.c b/app/display/gimpimagewindow.c
index 425fd8b..e242d68 100644
--- a/app/display/gimpimagewindow.c
+++ b/app/display/gimpimagewindow.c
@@ -50,6 +50,7 @@
#include "gimpdisplayshell-callbacks.h"
#include "gimpdisplayshell-close.h"
#include "gimpdisplayshell-scroll.h"
+#include "gimpdisplayshell-transform.h"
#include "gimpimagewindow.h"
#include "gimpstatusbar.h"
@@ -90,6 +91,14 @@ struct _GimpImageWindowPrivate
gboolean is_empty;
};
+typedef struct
+{
+ GimpImageWindow *window;
+ gint x;
+ gint y;
+} PosCorrectionData;
+
+
#define GIMP_IMAGE_WINDOW_GET_PRIVATE(window) \
G_TYPE_INSTANCE_GET_PRIVATE (window, \
GIMP_TYPE_IMAGE_WINDOW, \
@@ -131,6 +140,10 @@ static void gimp_image_window_show_tooltip (GimpUIManager *man
static void gimp_image_window_hide_tooltip (GimpUIManager *manager,
GimpImageWindow *window);
+static void gimp_image_window_keep_canvas_pos (GimpImageWindow *window);
+static void gimp_image_window_shell_size_allocate (GimpDisplayShell *shell,
+ GtkAllocation *allocation,
+ PosCorrectionData *data);
static gboolean gimp_image_window_shell_events (GtkWidget *widget,
GdkEvent *event,
GimpImageWindow *window);
@@ -344,6 +357,9 @@ gimp_image_window_constructor (GType type,
g_signal_connect_object (config, "notify::single-window-mode",
G_CALLBACK (gimp_image_window_config_notify),
window, G_CONNECT_SWAPPED);
+ g_signal_connect_object (config, "notify::hide-docks",
+ G_CALLBACK (gimp_image_window_config_notify),
+ window, G_CONNECT_SWAPPED);
return object;
}
@@ -1045,10 +1061,15 @@ gimp_image_window_config_notify (GimpImageWindow *window,
{
GimpImageWindowPrivate *private = GIMP_IMAGE_WINDOW_GET_PRIVATE (window);
- if (strcmp (pspec->name, "single-window-mode") == 0)
+ if (strcmp (pspec->name, "single-window-mode") == 0 ||
+ strcmp (pspec->name, "hide-docks") == 0)
{
- gtk_widget_set_visible (private->left_docks, config->single_window_mode);
- gtk_widget_set_visible (private->right_docks, config->single_window_mode);
+ gboolean show_docks = (config->single_window_mode &&
+ ! config->hide_docks);
+
+ gimp_image_window_keep_canvas_pos (window);
+ gtk_widget_set_visible (private->left_docks, show_docks);
+ gtk_widget_set_visible (private->right_docks, show_docks);
}
}
@@ -1067,6 +1088,74 @@ gimp_image_window_hide_tooltip (GimpUIManager *manager,
gimp_statusbar_pop (statusbar, "menu-tooltip");
}
+/**
+ * gimp_image_window_keep_canvas_pos:
+ * @window:
+ *
+ * Stores the coordinate of the current shell image origin in
+ * GtkWindow coordinates and on the first size-allocate sets the
+ * offsets in the shell so the image origin remains the same in
+ * GtkWindow coordinates.
+ *
+ * Exampe use case: The user hides docks attached to the side of image
+ * windows. You want the image to remain fixed on the screen though,
+ * so you use this function to keep the image fixed after the docks
+ * have been hidden.
+ **/
+static void
+gimp_image_window_keep_canvas_pos (GimpImageWindow *window)
+{
+ GimpDisplayShell *shell = gimp_image_window_get_active_shell (window);
+ gint image_origin_shell_x = -1;
+ gint image_origin_shell_y = -1;
+ gint image_origin_window_x = -1;
+ gint image_origin_window_y = -1;
+ PosCorrectionData *data = NULL;
+
+ gimp_display_shell_transform_xy (shell,
+ 0.0, 0.0,
+ &image_origin_shell_x, &image_origin_shell_y,
+ FALSE /*use_offsets*/);
+ gtk_widget_translate_coordinates (GTK_WIDGET (shell),
+ GTK_WIDGET (window),
+ image_origin_shell_x, image_origin_shell_y,
+ &image_origin_window_x, &image_origin_window_y);
+
+ data = g_new0 (PosCorrectionData, 1);
+ data->window = window;
+ data->x = image_origin_window_x;
+ data->y = image_origin_window_y;
+ g_signal_connect_data (shell, "size-allocate",
+ G_CALLBACK (gimp_image_window_shell_size_allocate),
+ data, (GClosureNotify) g_free,
+ G_CONNECT_AFTER);
+}
+
+static void
+gimp_image_window_shell_size_allocate (GimpDisplayShell *shell,
+ GtkAllocation *allocation,
+ PosCorrectionData *data)
+{
+ GimpImageWindow *window = data->window;
+ gint image_origin_shell_x = -1;
+ gint image_origin_shell_y = -1;
+
+ gtk_widget_translate_coordinates (GTK_WIDGET (window),
+ GTK_WIDGET (shell),
+ data->x, data->y,
+ &image_origin_shell_x, &image_origin_shell_y);
+
+ /* Note that the shell offset isn't the offset of the image into the
+ * shell, but the offset of the shell relative to the image,
+ * therefor we need to negate
+ */
+ gimp_display_shell_scroll_set_offset (shell, -image_origin_shell_x, -image_origin_shell_y);
+
+ g_signal_handlers_disconnect_by_func (shell,
+ gimp_image_window_shell_size_allocate,
+ data);
+}
+
static gboolean
gimp_image_window_shell_events (GtkWidget *widget,
GdkEvent *event,
diff --git a/app/tests/test-ui.c b/app/tests/test-ui.c
index 83da321..ef9cd8a 100644
--- a/app/tests/test-ui.c
+++ b/app/tests/test-ui.c
@@ -28,6 +28,8 @@
#include "dialogs/dialogs.h"
#include "display/gimpdisplay.h"
+#include "display/gimpdisplayshell.h"
+#include "display/gimpdisplayshell-transform.h"
#include "display/gimpimagewindow.h"
#include "widgets/gimpdialogfactory.h"
@@ -48,7 +50,10 @@
#include "gimp-app-test-utils.h"
-#define GIMP_UI_POSITION_EPSILON 10
+#define GIMP_UI_WINDOW_POSITION_EPSILON 10
+#define GIMP_UI_WINDOW_POSITION_EPSILON 10
+#define GIMP_UI_POSITION_EPSILON 1
+#define GIMP_UI_POSITION_EPSILON 1
typedef struct
@@ -67,6 +72,10 @@ static void gimp_ui_tab_toggle_dont_change_position (GimpTestFixture
gconstpointer data);
static void gimp_ui_switch_to_single_window_mode (GimpTestFixture *fixture,
gconstpointer data);
+static void gimp_ui_hide_docks_in_single_window_mode (GimpTestFixture *fixture,
+ gconstpointer data);
+static void gimp_ui_show_docks_in_single_window_mode (GimpTestFixture *fixture,
+ gconstpointer data);
static void gimp_ui_switch_back_to_multi_window_mode (GimpTestFixture *fixture,
gconstpointer data);
static GimpUIManager * gimp_ui_get_ui_manager (Gimp *gimp);
@@ -122,6 +131,18 @@ int main(int argc, char **argv)
NULL,
gimp_ui_switch_to_single_window_mode,
NULL);
+ g_test_add ("/gimp-ui/hide-docks-in-single-window-mode",
+ GimpTestFixture,
+ gimp,
+ NULL,
+ gimp_ui_hide_docks_in_single_window_mode,
+ NULL);
+ g_test_add ("/gimp-ui/show-docks-in-single-window-mode",
+ GimpTestFixture,
+ gimp,
+ NULL,
+ gimp_ui_show_docks_in_single_window_mode,
+ NULL);
g_test_add ("/gimp-ui/switch-back-to-multi-window-mode",
GimpTestFixture,
gimp,
@@ -345,10 +366,10 @@ gimp_ui_tab_toggle_dont_change_position (GimpTestFixture *fixture,
gtk_window_get_size (GTK_WINDOW (dock_window),
&w_after_show,
&h_after_show);
- g_assert_cmpint ((int)abs (x_before_hide - x_after_show), <, GIMP_UI_POSITION_EPSILON);
- g_assert_cmpint ((int)abs (y_before_hide - y_after_show), <, GIMP_UI_POSITION_EPSILON);
- g_assert_cmpint ((int)abs (w_before_hide - w_after_show), <, GIMP_UI_POSITION_EPSILON);
- g_assert_cmpint ((int)abs (h_before_hide - h_after_show), <, GIMP_UI_POSITION_EPSILON);
+ g_assert_cmpint ((int)abs (x_before_hide - x_after_show), <=, GIMP_UI_WINDOW_POSITION_EPSILON);
+ g_assert_cmpint ((int)abs (y_before_hide - y_after_show), <=, GIMP_UI_WINDOW_POSITION_EPSILON);
+ g_assert_cmpint ((int)abs (w_before_hide - w_after_show), <=, GIMP_UI_WINDOW_POSITION_EPSILON);
+ g_assert_cmpint ((int)abs (h_before_hide - h_after_show), <=, GIMP_UI_WINDOW_POSITION_EPSILON);
}
static void
@@ -367,6 +388,69 @@ gimp_ui_switch_to_single_window_mode (GimpTestFixture *fixture,
}
static void
+gimp_ui_toggle_docks_in_single_window_mode (Gimp *gimp)
+{
+ GimpDisplay *display = GIMP_DISPLAY (gimp_get_display_iter (gimp)->data);
+ GimpDisplayShell *shell = gimp_display_get_shell (display);
+ GtkWidget *toplevel = GTK_WIDGET (gimp_display_shell_get_window (shell));
+ gint x_temp = -1;
+ gint y_temp = -1;
+ gint x_before_hide = -1;
+ gint y_before_hide = -1;
+ gint x_after_hide = -1;
+ gint y_after_hide = -1;
+ g_assert (shell);
+ g_assert (toplevel);
+
+ /* Get toplevel coordinate of image origin */
+ gimp_test_run_mainloop_until_idle ();
+ gimp_display_shell_transform_xy (shell,
+ 0.0, 0.0,
+ &x_temp, &y_temp,
+ FALSE /*use_offsets*/);
+ gtk_widget_translate_coordinates (GTK_WIDGET (shell),
+ toplevel,
+ x_temp, y_temp,
+ &x_before_hide, &y_before_hide);
+
+ /* Hide all dock windows */
+ gimp_ui_manager_activate_action (gimp_ui_get_ui_manager (gimp),
+ "windows",
+ "windows-hide-docks");
+ gimp_test_run_mainloop_until_idle ();
+
+ /* Get toplevel coordinate of image origin */
+ gimp_test_run_mainloop_until_idle ();
+ gimp_display_shell_transform_xy (shell,
+ 0.0, 0.0,
+ &x_temp, &y_temp,
+ FALSE /*use_offsets*/);
+ gtk_widget_translate_coordinates (GTK_WIDGET (shell),
+ toplevel,
+ x_temp, y_temp,
+ &x_after_hide, &y_after_hide);
+
+ g_assert_cmpint ((int)abs (x_after_hide - x_before_hide), <=, GIMP_UI_POSITION_EPSILON);
+ g_assert_cmpint ((int)abs (y_after_hide - y_before_hide), <=, GIMP_UI_POSITION_EPSILON);
+}
+
+static void
+gimp_ui_hide_docks_in_single_window_mode (GimpTestFixture *fixture,
+ gconstpointer data)
+{
+ Gimp *gimp = GIMP (data);
+ gimp_ui_toggle_docks_in_single_window_mode (gimp);
+}
+
+static void
+gimp_ui_show_docks_in_single_window_mode (GimpTestFixture *fixture,
+ gconstpointer data)
+{
+ Gimp *gimp = GIMP (data);
+ gimp_ui_toggle_docks_in_single_window_mode (gimp);
+}
+
+static void
gimp_ui_switch_back_to_multi_window_mode (GimpTestFixture *fixture,
gconstpointer data)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]