mirror of https://github.com/GNOME/gimp.git
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
This commit is contained in:
parent
82a0b95147
commit
18f3be6bd3
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.")
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
@ -366,6 +387,69 @@ gimp_ui_switch_to_single_window_mode (GimpTestFixture *fixture,
|
|||
gimp_test_run_mainloop_until_idle ();
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue