Refactored modifier handling of displays and tools. Hopefully finally

2003-10-14  Michael Natterer  <mitch@gimp.org>

	Refactored modifier handling of displays and tools. Hopefully
	finally fixes bug #124135.

	* app/tools/gimptool.[ch] (struct GimpTool): added private members
	"focus_display" and "modifier_state" so tools are aware of their
	modifier state.

	* app/tools/gimptool.[ch]
	* app/tools/tool_manager.[ch]: removed all public modifier_key()
	API and added set_focus_display() and set_modifier_state()
	instead.

	* app/tools/tool_manager.c (tool_manager_select_tool)
	* app/display/gimpdisplay.c (gimp_display_delete): set the
	active_tool's focus_display to NULL.

	* app/display/gimpdisplayshell.[ch] (struct GimpDisplayShell):
	added almost the whole stuff that used to be static variables of
	gimp_display_shell_tool_events(). Cleaned up the struct a bit.

	* app/display/gimpdisplayshell-callbacks.c: removed utility
	function gimp_display_shell_update_tool_modifiers().

	(gimp_display_shell_tool_events):

	- Replaced all calls to gimp_display_shell_update_tool_modifiers()
	  and tool_manager_modifier_key_active() by
	  tool_manager_modifier_state_active().

	- Call tool_manager_focus_display_active() before setting the
	  tool's modifier_state. Set the tool's focus_display to NULL when
	  we get a focus_out event.

	- Don't grab/ungrab the keyboard twice when <space>-selecting the
	  move tool.

	- Removed most static variables and use the new members of
	  GimpDisplayShell. Don't remember any old modifier states since
	  GimpTool does that by itself now.
This commit is contained in:
Michael Natterer 2003-10-14 11:14:28 +00:00 committed by Michael Natterer
parent d452d0d7e8
commit b19deeb311
12 changed files with 280 additions and 191 deletions

View File

@ -1,3 +1,45 @@
2003-10-14 Michael Natterer <mitch@gimp.org>
Refactored modifier handling of displays and tools. Hopefully
finally fixes bug #124135.
* app/tools/gimptool.[ch] (struct GimpTool): added private members
"focus_display" and "modifier_state" so tools are aware of their
modifier state.
* app/tools/gimptool.[ch]
* app/tools/tool_manager.[ch]: removed all public modifier_key()
API and added set_focus_display() and set_modifier_state()
instead.
* app/tools/tool_manager.c (tool_manager_select_tool)
* app/display/gimpdisplay.c (gimp_display_delete): set the
active_tool's focus_display to NULL.
* app/display/gimpdisplayshell.[ch] (struct GimpDisplayShell):
added almost the whole stuff that used to be static variables of
gimp_display_shell_tool_events(). Cleaned up the struct a bit.
* app/display/gimpdisplayshell-callbacks.c: removed utility
function gimp_display_shell_update_tool_modifiers().
(gimp_display_shell_tool_events):
- Replaced all calls to gimp_display_shell_update_tool_modifiers()
and tool_manager_modifier_key_active() by
tool_manager_modifier_state_active().
- Call tool_manager_focus_display_active() before setting the
tool's modifier_state. Set the tool's focus_display to NULL when
we get a focus_out event.
- Don't grab/ungrab the keyboard twice when <space>-selecting the
move tool.
- Removed most static variables and use the new members of
GimpDisplayShell. Don't remember any old modifier states since
GimpTool does that by itself now.
2003-10-13 Manish Singh <yosh@gimp.org> 2003-10-13 Manish Singh <yosh@gimp.org>
* libgimp/Makefile.am: add $(libgimp) to libgimpui_1_3_la_DEPENDENCIES * libgimp/Makefile.am: add $(libgimp) to libgimpui_1_3_la_DEPENDENCIES

View File

@ -245,12 +245,18 @@ gimp_display_delete (GimpDisplay *gdisp)
active_tool = tool_manager_get_active (gdisp->gimage->gimp); active_tool = tool_manager_get_active (gdisp->gimage->gimp);
if (active_tool)
{
if (active_tool->focus_display == gdisp)
tool_manager_focus_display_active (gdisp->gimage->gimp, NULL);
/* clear out the pointer to this gdisp from the active tool */ /* clear out the pointer to this gdisp from the active tool */
if (active_tool && active_tool->gdisp == gdisp) if (active_tool->gdisp == gdisp)
{ {
active_tool->drawable = NULL; active_tool->drawable = NULL;
active_tool->gdisp = NULL; active_tool->gdisp = NULL;
} }
}
/* If this gdisplay was idlerendering at the time when it was deleted, /* If this gdisplay was idlerendering at the time when it was deleted,
* deactivate the idlerendering thread before deletion! * deactivate the idlerendering thread before deletion!

View File

@ -245,12 +245,18 @@ gimp_display_delete (GimpDisplay *gdisp)
active_tool = tool_manager_get_active (gdisp->gimage->gimp); active_tool = tool_manager_get_active (gdisp->gimage->gimp);
if (active_tool)
{
if (active_tool->focus_display == gdisp)
tool_manager_focus_display_active (gdisp->gimage->gimp, NULL);
/* clear out the pointer to this gdisp from the active tool */ /* clear out the pointer to this gdisp from the active tool */
if (active_tool && active_tool->gdisp == gdisp) if (active_tool->gdisp == gdisp)
{ {
active_tool->drawable = NULL; active_tool->drawable = NULL;
active_tool->gdisp = NULL; active_tool->gdisp = NULL;
} }
}
/* If this gdisplay was idlerendering at the time when it was deleted, /* If this gdisplay was idlerendering at the time when it was deleted,
* deactivate the idlerendering thread before deletion! * deactivate the idlerendering thread before deletion!

View File

@ -93,10 +93,6 @@ static void gimp_display_shell_get_device_state (GimpDisplayShell *shell,
static GdkModifierType static GdkModifierType
gimp_display_shell_key_to_state (gint key); gimp_display_shell_key_to_state (gint key);
static void gimp_display_shell_update_tool_modifiers (GimpDisplayShell *shell,
GdkModifierType old_state,
GdkModifierType current_state);
static void gimp_display_shell_origin_menu_position (GtkMenu *menu, static void gimp_display_shell_origin_menu_position (GtkMenu *menu,
gint *x, gint *x,
gint *y, gint *y,
@ -420,17 +416,8 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
gboolean return_val = FALSE; gboolean return_val = FALSE;
gboolean update_cursor = FALSE; gboolean update_cursor = FALSE;
static GdkModifierType button_press_state = 0;
static GdkModifierType space_press_state = 0;
static GimpToolInfo *space_shaded_tool = NULL; static GimpToolInfo *space_shaded_tool = NULL;
static gboolean scrolling = FALSE;
static gint scroll_start_x = 0;
static gint scroll_start_y = 0;
static gboolean button_press_before_focus = FALSE;
if (! canvas->window) if (! canvas->window)
{ {
g_warning ("%s: called unrealized", G_STRLOC); g_warning ("%s: called unrealized", G_STRLOC);
@ -516,9 +503,10 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
* in "click to focus" mode, we did this on BUTTON_PRESS, so * in "click to focus" mode, we did this on BUTTON_PRESS, so
* do it here only if button_press_before_focus is FALSE * do it here only if button_press_before_focus is FALSE
*/ */
if (state && ! button_press_before_focus) if (! shell->button_press_before_focus)
{ {
gimp_display_shell_update_tool_modifiers (shell, 0, state); tool_manager_focus_display_active (gimp, gdisp);
tool_manager_modifier_state_active (gimp, state, gdisp);
tool_manager_oper_update_active (gimp, tool_manager_oper_update_active (gimp,
&image_coords, state, &image_coords, state,
@ -532,18 +520,15 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
/* reset it here to be prepared for the next /* reset it here to be prepared for the next
* FOCUS_IN / BUTTON_PRESS confusion * FOCUS_IN / BUTTON_PRESS confusion
*/ */
button_press_before_focus = FALSE; shell->button_press_before_focus = FALSE;
/* release modifier keys when the canvas loses the focus */ /* release modifier keys when the canvas loses the focus */
if (state) tool_manager_focus_display_active (gimp, NULL);
{
gimp_display_shell_update_tool_modifiers (shell, state, 0);
tool_manager_oper_update_active (gimp, tool_manager_oper_update_active (gimp,
&image_coords, 0, &image_coords, 0,
gdisp); gdisp);
} }
}
/* stop the signal because otherwise gtk+ exposes the whole /* stop the signal because otherwise gtk+ exposes the whole
* canvas to get the non-existant focus indicator drawn * canvas to get the non-existant focus indicator drawn
@ -564,16 +549,14 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
/* in "click to focus" mode, the BUTTON_PRESS arrives before /* in "click to focus" mode, the BUTTON_PRESS arrives before
* FOCUS_IN, so we have to update the tool's modifier state here * FOCUS_IN, so we have to update the tool's modifier state here
*/ */
if (state) tool_manager_focus_display_active (gimp, gdisp);
{ tool_manager_modifier_state_active (gimp, state, gdisp);
gimp_display_shell_update_tool_modifiers (shell, 0, state);
tool_manager_oper_update_active (gimp, tool_manager_oper_update_active (gimp,
&image_coords, state, &image_coords, state,
gdisp); gdisp);
}
button_press_before_focus = TRUE; shell->button_press_before_focus = TRUE;
/* we expect a FOCUS_IN event to follow, but can't rely /* we expect a FOCUS_IN event to follow, but can't rely
* on it, so force one * on it, so force one
@ -617,13 +600,9 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
NULL, NULL, time); NULL, NULL, time);
} }
if (! shell->space_pressed && ! shell->space_release_pending)
gdk_keyboard_grab (canvas->window, FALSE, time); gdk_keyboard_grab (canvas->window, FALSE, time);
/* save the current modifier state because tools don't get
* key events while BUTTON1 is down
*/
button_press_state = state;
if (active_tool && if (active_tool &&
(! gimp_image_is_empty (gimage) || (! gimp_image_is_empty (gimage) ||
gimp_tool_control_handles_empty_image (active_tool->control))) gimp_tool_control_handles_empty_image (active_tool->control)))
@ -669,10 +648,9 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
case 2: case 2:
state |= GDK_BUTTON2_MASK; state |= GDK_BUTTON2_MASK;
scrolling = TRUE; shell->scrolling = TRUE;
shell->scroll_start_x = bevent->x + shell->offset_x;
scroll_start_x = bevent->x + shell->offset_x; shell->scroll_start_y = bevent->y + shell->offset_y;
scroll_start_y = bevent->y + shell->offset_y;
gtk_grab_add (canvas); gtk_grab_add (canvas);
@ -738,49 +716,48 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
} }
} }
gdk_keyboard_ungrab (time); /* update the tool's modifier state because it didn't get
gdk_pointer_ungrab (time);
/* restore the tool's modifier state because it didn't get
* key events while BUTTON1 was down * key events while BUTTON1 was down
*/ */
gimp_display_shell_update_tool_modifiers (shell, tool_manager_focus_display_active (gimp, gdisp);
button_press_state, tool_manager_modifier_state_active (gimp, state, gdisp);
state);
tool_manager_oper_update_active (gimp, tool_manager_oper_update_active (gimp,
&image_coords, state, &image_coords, state,
gdisp); gdisp);
if (shell->space_release_pending) if (! shell->space_pressed && ! shell->space_release_pending)
{
gdk_keyboard_ungrab (time); gdk_keyboard_ungrab (time);
gimp_display_shell_update_tool_modifiers (shell, state, 0); gdk_pointer_ungrab (time);
if (shell->space_release_pending)
{
g_print ("%s: popping move tool\n", G_GNUC_FUNCTION);
gimp_context_set_tool (gimp_get_user_context (gimp), gimp_context_set_tool (gimp_get_user_context (gimp),
space_shaded_tool); space_shaded_tool);
space_shaded_tool = NULL; space_shaded_tool = NULL;
gimp_display_shell_update_tool_modifiers (shell, tool_manager_focus_display_active (gimp, gdisp);
space_press_state, tool_manager_modifier_state_active (gimp, state, gdisp);
state);
tool_manager_oper_update_active (gimp, tool_manager_oper_update_active (gimp,
&image_coords, state, &image_coords, state,
gdisp); gdisp);
shell->space_release_pending = FALSE; shell->space_release_pending = FALSE;
gdk_keyboard_ungrab (time);
} }
break; break;
case 2: case 2:
state &= ~GDK_BUTTON2_MASK; state &= ~GDK_BUTTON2_MASK;
scrolling = FALSE; shell->scrolling = FALSE;
shell->scroll_start_x = 0;
scroll_start_x = 0; shell->scroll_start_y = 0;
scroll_start_y = 0;
gtk_grab_remove (canvas); gtk_grab_remove (canvas);
@ -970,12 +947,12 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
} }
else if (state & GDK_BUTTON2_MASK) else if (state & GDK_BUTTON2_MASK)
{ {
if (scrolling) if (shell->scrolling)
{ {
gimp_display_shell_scroll (shell, gimp_display_shell_scroll (shell,
(scroll_start_x - mevent->x - (shell->scroll_start_x - mevent->x -
shell->offset_x), shell->offset_x),
(scroll_start_y - mevent->y - (shell->scroll_start_y - mevent->y -
shell->offset_y)); shell->offset_y));
} }
} }
@ -996,6 +973,8 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
kevent = (GdkEventKey *) event; kevent = (GdkEventKey *) event;
tool_manager_focus_display_active (gimp, gdisp);
switch (kevent->keyval) switch (kevent->keyval)
{ {
case GDK_Left: case GDK_Right: case GDK_Left: case GDK_Right:
@ -1020,9 +999,6 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
{ {
GimpToolInfo *move_tool_info; GimpToolInfo *move_tool_info;
space_shaded_tool = active_tool->tool_info;
space_press_state = state;
move_tool_info = (GimpToolInfo *) move_tool_info = (GimpToolInfo *)
gimp_container_get_child_by_name (gimp->tool_info_list, gimp_container_get_child_by_name (gimp->tool_info_list,
"gimp-move-tool"); "gimp-move-tool");
@ -1031,12 +1007,15 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
{ {
g_print ("%s: pushing move tool\n", G_GNUC_FUNCTION); g_print ("%s: pushing move tool\n", G_GNUC_FUNCTION);
space_shaded_tool = active_tool->tool_info;
gdk_keyboard_grab (canvas->window, FALSE, time); gdk_keyboard_grab (canvas->window, FALSE, time);
gimp_context_set_tool (gimp_get_user_context (gimp), gimp_context_set_tool (gimp_get_user_context (gimp),
move_tool_info); move_tool_info);
gimp_display_shell_update_tool_modifiers (shell, 0, state); tool_manager_focus_display_active (gimp, gdisp);
tool_manager_modifier_state_active (gimp, state, gdisp);
shell->space_pressed = TRUE; shell->space_pressed = TRUE;
} }
@ -1083,16 +1062,12 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
key = gimp_display_shell_key_to_state (kevent->keyval); key = gimp_display_shell_key_to_state (kevent->keyval);
state |= key; state |= key;
/* For all modifier keys: call the tools modifier_key *and* /* For all modifier keys: call the tools modifier_state *and*
* oper_update method so tools can choose if they are interested * oper_update method so tools can choose if they are interested
* in the release itself or only in the resulting state * in the release itself or only in the resulting state
*/ */
if (! gimp_image_is_empty (gimage)) if (! gimp_image_is_empty (gimage))
{ tool_manager_modifier_state_active (gimp, state, gdisp);
tool_manager_modifier_key_active (gimp,
key, TRUE, state,
gdisp);
}
} }
break; break;
@ -1110,6 +1085,8 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
kevent = (GdkEventKey *) event; kevent = (GdkEventKey *) event;
tool_manager_focus_display_active (gimp, gdisp);
switch (kevent->keyval) switch (kevent->keyval)
{ {
case GDK_space: case GDK_space:
@ -1117,19 +1094,16 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
{ {
g_print ("%s: popping move tool\n", G_GNUC_FUNCTION); g_print ("%s: popping move tool\n", G_GNUC_FUNCTION);
gdk_keyboard_ungrab (time);
gimp_display_shell_update_tool_modifiers (shell, state, 0);
gimp_context_set_tool (gimp_get_user_context (gimp), gimp_context_set_tool (gimp_get_user_context (gimp),
space_shaded_tool); space_shaded_tool);
space_shaded_tool = NULL; space_shaded_tool = NULL;
gimp_display_shell_update_tool_modifiers (shell, tool_manager_focus_display_active (gimp, gdisp);
space_press_state, tool_manager_modifier_state_active (gimp, state, gdisp);
state);
shell->space_pressed = FALSE; shell->space_pressed = FALSE;
gdk_keyboard_ungrab (time);
} }
return_val = TRUE; return_val = TRUE;
@ -1145,16 +1119,12 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
key = gimp_display_shell_key_to_state (kevent->keyval); key = gimp_display_shell_key_to_state (kevent->keyval);
state &= ~key; state &= ~key;
/* For all modifier keys: call the tools modifier_key *and* /* For all modifier keys: call the tools modifier_state *and*
* oper_update method so tools can choose if they are interested * oper_update method so tools can choose if they are interested
* in the press itself or only in the resulting state * in the press itself or only in the resulting state
*/ */
if (! gimp_image_is_empty (gimage)) if (! gimp_image_is_empty (gimage))
{ tool_manager_modifier_state_active (gimp, state, gdisp);
tool_manager_modifier_key_active (gimp,
key, FALSE, state,
gdisp);
}
} }
break; break;
@ -1614,46 +1584,6 @@ gimp_display_shell_key_to_state (gint key)
} }
} }
static void
gimp_display_shell_update_tool_modifiers (GimpDisplayShell *shell,
GdkModifierType old_state,
GdkModifierType current_state)
{
Gimp *gimp;
gimp = shell->gdisp->gimage->gimp;
if ((old_state & GDK_SHIFT_MASK) != (current_state & GDK_SHIFT_MASK))
{
tool_manager_modifier_key_active (gimp,
GDK_SHIFT_MASK,
(current_state & GDK_SHIFT_MASK) ?
TRUE : FALSE,
current_state,
shell->gdisp);
}
if ((old_state & GDK_CONTROL_MASK) != (current_state & GDK_CONTROL_MASK))
{
tool_manager_modifier_key_active (gimp,
GDK_CONTROL_MASK,
(current_state & GDK_CONTROL_MASK) ?
TRUE : FALSE,
current_state,
shell->gdisp);
}
if ((old_state & GDK_MOD1_MASK) != (current_state & GDK_MOD1_MASK))
{
tool_manager_modifier_key_active (gimp,
GDK_MOD1_MASK,
(current_state & GDK_MOD1_MASK) ?
TRUE : FALSE,
current_state,
shell->gdisp);
}
}
static void static void
gimp_display_shell_origin_menu_position (GtkMenu *menu, gimp_display_shell_origin_menu_position (GtkMenu *menu,
gint *x, gint *x,

View File

@ -263,11 +263,10 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->filters = NULL; shell->filters = NULL;
shell->filters_dialog = NULL; shell->filters_dialog = NULL;
shell->space_pressed = FALSE;
shell->space_release_pending = FALSE;
shell->window_state = 0; shell->window_state = 0;
shell->paused_count = 0;
shell->appearance.selection = TRUE; shell->appearance.selection = TRUE;
shell->appearance.active_layer = TRUE; shell->appearance.active_layer = TRUE;
shell->appearance.guides = TRUE; shell->appearance.guides = TRUE;
@ -277,7 +276,8 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->appearance.scrollbars = TRUE; shell->appearance.scrollbars = TRUE;
shell->appearance.statusbar = TRUE; shell->appearance.statusbar = TRUE;
shell->appearance.padding_mode = GIMP_DISPLAY_PADDING_MODE_DEFAULT; shell->appearance.padding_mode = GIMP_DISPLAY_PADDING_MODE_DEFAULT;
gimp_rgba_set (&shell->appearance.padding_color, 1.0, 1.0, 1.0, 1.0); gimp_rgba_set (&shell->appearance.padding_color,
1.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE);
shell->appearance.padding_mode_set = FALSE; shell->appearance.padding_mode_set = FALSE;
shell->fullscreen_appearance.selection = TRUE; shell->fullscreen_appearance.selection = TRUE;
@ -290,10 +290,15 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->fullscreen_appearance.statusbar = FALSE; shell->fullscreen_appearance.statusbar = FALSE;
shell->fullscreen_appearance.padding_mode = GIMP_DISPLAY_PADDING_MODE_CUSTOM; shell->fullscreen_appearance.padding_mode = GIMP_DISPLAY_PADDING_MODE_CUSTOM;
gimp_rgba_set (&shell->fullscreen_appearance.padding_color, gimp_rgba_set (&shell->fullscreen_appearance.padding_color,
0.0, 0.0, 0.0, 1.0); 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
shell->fullscreen_appearance.padding_mode_set = FALSE; shell->fullscreen_appearance.padding_mode_set = FALSE;
shell->paused_count = 0; shell->space_pressed = FALSE;
shell->space_release_pending = FALSE;
shell->scrolling = FALSE;
shell->scroll_start_x = 0;
shell->scroll_start_y = 0;
shell->button_press_before_focus = FALSE;
gtk_window_set_wmclass (GTK_WINDOW (shell), "image_window", "Gimp"); gtk_window_set_wmclass (GTK_WINDOW (shell), "image_window", "Gimp");
gtk_window_set_resizable (GTK_WINDOW (shell), TRUE); gtk_window_set_resizable (GTK_WINDOW (shell), TRUE);

View File

@ -162,20 +162,24 @@ struct _GimpDisplayShell
GList *filters; /* color display conversion stuff */ GList *filters; /* color display conversion stuff */
GtkWidget *filters_dialog; /* color display filter dialog */ GtkWidget *filters_dialog; /* color display filter dialog */
/* the state of gimp_display_shell_tool_events() */
gboolean space_pressed;
gboolean space_release_pending;
GdkWindowState window_state; /* for fullscreen display */ GdkWindowState window_state; /* for fullscreen display */
GimpDisplayShellAppearance appearance;
GimpDisplayShellAppearance fullscreen_appearance;
gint paused_count; gint paused_count;
GQuark vectors_freeze_handler; GQuark vectors_freeze_handler;
GQuark vectors_thaw_handler; GQuark vectors_thaw_handler;
GQuark vectors_visible_handler; GQuark vectors_visible_handler;
GimpDisplayShellAppearance appearance;
GimpDisplayShellAppearance fullscreen_appearance;
/* the state of gimp_display_shell_tool_events() */
gboolean space_pressed;
gboolean space_release_pending;
gboolean scrolling;
gint scroll_start_x;
gint scroll_start_y;
gboolean button_press_before_focus;
}; };
struct _GimpDisplayShellClass struct _GimpDisplayShellClass

View File

@ -263,11 +263,10 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->filters = NULL; shell->filters = NULL;
shell->filters_dialog = NULL; shell->filters_dialog = NULL;
shell->space_pressed = FALSE;
shell->space_release_pending = FALSE;
shell->window_state = 0; shell->window_state = 0;
shell->paused_count = 0;
shell->appearance.selection = TRUE; shell->appearance.selection = TRUE;
shell->appearance.active_layer = TRUE; shell->appearance.active_layer = TRUE;
shell->appearance.guides = TRUE; shell->appearance.guides = TRUE;
@ -277,7 +276,8 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->appearance.scrollbars = TRUE; shell->appearance.scrollbars = TRUE;
shell->appearance.statusbar = TRUE; shell->appearance.statusbar = TRUE;
shell->appearance.padding_mode = GIMP_DISPLAY_PADDING_MODE_DEFAULT; shell->appearance.padding_mode = GIMP_DISPLAY_PADDING_MODE_DEFAULT;
gimp_rgba_set (&shell->appearance.padding_color, 1.0, 1.0, 1.0, 1.0); gimp_rgba_set (&shell->appearance.padding_color,
1.0, 1.0, 1.0, GIMP_OPACITY_OPAQUE);
shell->appearance.padding_mode_set = FALSE; shell->appearance.padding_mode_set = FALSE;
shell->fullscreen_appearance.selection = TRUE; shell->fullscreen_appearance.selection = TRUE;
@ -290,10 +290,15 @@ gimp_display_shell_init (GimpDisplayShell *shell)
shell->fullscreen_appearance.statusbar = FALSE; shell->fullscreen_appearance.statusbar = FALSE;
shell->fullscreen_appearance.padding_mode = GIMP_DISPLAY_PADDING_MODE_CUSTOM; shell->fullscreen_appearance.padding_mode = GIMP_DISPLAY_PADDING_MODE_CUSTOM;
gimp_rgba_set (&shell->fullscreen_appearance.padding_color, gimp_rgba_set (&shell->fullscreen_appearance.padding_color,
0.0, 0.0, 0.0, 1.0); 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
shell->fullscreen_appearance.padding_mode_set = FALSE; shell->fullscreen_appearance.padding_mode_set = FALSE;
shell->paused_count = 0; shell->space_pressed = FALSE;
shell->space_release_pending = FALSE;
shell->scrolling = FALSE;
shell->scroll_start_x = 0;
shell->scroll_start_y = 0;
shell->button_press_before_focus = FALSE;
gtk_window_set_wmclass (GTK_WINDOW (shell), "image_window", "Gimp"); gtk_window_set_wmclass (GTK_WINDOW (shell), "image_window", "Gimp");
gtk_window_set_resizable (GTK_WINDOW (shell), TRUE); gtk_window_set_resizable (GTK_WINDOW (shell), TRUE);

View File

@ -162,20 +162,24 @@ struct _GimpDisplayShell
GList *filters; /* color display conversion stuff */ GList *filters; /* color display conversion stuff */
GtkWidget *filters_dialog; /* color display filter dialog */ GtkWidget *filters_dialog; /* color display filter dialog */
/* the state of gimp_display_shell_tool_events() */
gboolean space_pressed;
gboolean space_release_pending;
GdkWindowState window_state; /* for fullscreen display */ GdkWindowState window_state; /* for fullscreen display */
GimpDisplayShellAppearance appearance;
GimpDisplayShellAppearance fullscreen_appearance;
gint paused_count; gint paused_count;
GQuark vectors_freeze_handler; GQuark vectors_freeze_handler;
GQuark vectors_thaw_handler; GQuark vectors_thaw_handler;
GQuark vectors_visible_handler; GQuark vectors_visible_handler;
GimpDisplayShellAppearance appearance;
GimpDisplayShellAppearance fullscreen_appearance;
/* the state of gimp_display_shell_tool_events() */
gboolean space_pressed;
gboolean space_release_pending;
gboolean scrolling;
gint scroll_start_x;
gint scroll_start_y;
gboolean button_press_before_focus;
}; };
struct _GimpDisplayShellClass struct _GimpDisplayShellClass

View File

@ -165,6 +165,8 @@ gimp_tool_init (GimpTool *tool)
tool->control = g_object_new (GIMP_TYPE_TOOL_CONTROL, NULL); tool->control = g_object_new (GIMP_TYPE_TOOL_CONTROL, NULL);
tool->gdisp = NULL; tool->gdisp = NULL;
tool->drawable = NULL; tool->drawable = NULL;
tool->focus_display = NULL;
tool->modifier_state = 0;
} }
static void static void
@ -421,6 +423,30 @@ gimp_tool_motion (GimpTool *tool,
GIMP_TOOL_GET_CLASS (tool)->motion (tool, coords, time, state, gdisp); GIMP_TOOL_GET_CLASS (tool)->motion (tool, coords, time, state, gdisp);
} }
void
gimp_tool_set_focus_display (GimpTool *tool,
GimpDisplay *gdisp)
{
g_return_if_fail (GIMP_IS_TOOL (tool));
g_return_if_fail (gdisp == NULL || GIMP_IS_DISPLAY (gdisp));
#ifdef DEBUG_FOCUS
g_print ("gimp_tool_set_focus_display: gdisp: %p focus_display: %p\n",
gdisp, tool->focus_display);
#endif
if (gdisp != tool->focus_display)
{
if (tool->focus_display)
{
if (tool->modifier_state != 0)
gimp_tool_set_modifier_state (tool, 0, tool->focus_display);
}
tool->focus_display = gdisp;
}
}
void void
gimp_tool_arrow_key (GimpTool *tool, gimp_tool_arrow_key (GimpTool *tool,
GdkEventKey *kevent, GdkEventKey *kevent,
@ -428,11 +454,12 @@ gimp_tool_arrow_key (GimpTool *tool,
{ {
g_return_if_fail (GIMP_IS_TOOL (tool)); g_return_if_fail (GIMP_IS_TOOL (tool));
g_return_if_fail (GIMP_IS_DISPLAY (gdisp)); g_return_if_fail (GIMP_IS_DISPLAY (gdisp));
g_return_if_fail (gdisp == tool->focus_display);
GIMP_TOOL_GET_CLASS (tool)->arrow_key (tool, kevent, gdisp); GIMP_TOOL_GET_CLASS (tool)->arrow_key (tool, kevent, gdisp);
} }
void static void
gimp_tool_modifier_key (GimpTool *tool, gimp_tool_modifier_key (GimpTool *tool,
GdkModifierType key, GdkModifierType key,
gboolean press, gboolean press,
@ -441,10 +468,50 @@ gimp_tool_modifier_key (GimpTool *tool,
{ {
g_return_if_fail (GIMP_IS_TOOL (tool)); g_return_if_fail (GIMP_IS_TOOL (tool));
g_return_if_fail (GIMP_IS_DISPLAY (gdisp)); g_return_if_fail (GIMP_IS_DISPLAY (gdisp));
g_return_if_fail (gdisp == tool->focus_display);
GIMP_TOOL_GET_CLASS (tool)->modifier_key (tool, key, press, state, gdisp); GIMP_TOOL_GET_CLASS (tool)->modifier_key (tool, key, press, state, gdisp);
} }
void
gimp_tool_set_modifier_state (GimpTool *tool,
GdkModifierType state,
GimpDisplay *gdisp)
{
g_return_if_fail (GIMP_IS_TOOL (tool));
g_return_if_fail (GIMP_IS_DISPLAY (gdisp));
#ifdef DEBUG_FOCUS
g_print ("gimp_tool_set_modifier_state: gdisp: %p focus_display: %p\n",
gdisp, tool->focus_display);
#endif
g_return_if_fail (gdisp == tool->focus_display);
if ((tool->modifier_state & GDK_SHIFT_MASK) != (state & GDK_SHIFT_MASK))
{
gimp_tool_modifier_key (tool, GDK_SHIFT_MASK,
(state & GDK_SHIFT_MASK) ? TRUE : FALSE, state,
gdisp);
}
if ((tool->modifier_state & GDK_CONTROL_MASK) != (state & GDK_CONTROL_MASK))
{
gimp_tool_modifier_key (tool, GDK_CONTROL_MASK,
(state & GDK_CONTROL_MASK) ? TRUE : FALSE, state,
gdisp);
}
if ((tool->modifier_state & GDK_MOD1_MASK) != (state & GDK_MOD1_MASK))
{
gimp_tool_modifier_key (tool, GDK_MOD1_MASK,
(state & GDK_MOD1_MASK) ? TRUE : FALSE, state,
gdisp);
}
tool->modifier_state = state;
}
void void
gimp_tool_oper_update (GimpTool *tool, gimp_tool_oper_update (GimpTool *tool,
GimpCoords *coords, GimpCoords *coords,
@ -484,9 +551,7 @@ gimp_tool_push_status (GimpTool *tool,
statusbar = statusbar =
GIMP_STATUSBAR (GIMP_DISPLAY_SHELL (tool->gdisp->shell)->statusbar); GIMP_STATUSBAR (GIMP_DISPLAY_SHELL (tool->gdisp->shell)->statusbar);
gimp_statusbar_push (statusbar, gimp_statusbar_push (statusbar, G_OBJECT_TYPE_NAME (tool), message);
G_OBJECT_TYPE_NAME (tool),
message);
} }
void void
@ -506,8 +571,7 @@ gimp_tool_push_status_coords (GimpTool *tool,
statusbar = statusbar =
GIMP_STATUSBAR (GIMP_DISPLAY_SHELL (tool->gdisp->shell)->statusbar); GIMP_STATUSBAR (GIMP_DISPLAY_SHELL (tool->gdisp->shell)->statusbar);
gimp_statusbar_push_coords (statusbar, gimp_statusbar_push_coords (statusbar, G_OBJECT_TYPE_NAME (tool),
G_OBJECT_TYPE_NAME (tool),
title, x, separator, y); title, x, separator, y);
} }
@ -522,8 +586,7 @@ gimp_tool_pop_status (GimpTool *tool)
statusbar = statusbar =
GIMP_STATUSBAR (GIMP_DISPLAY_SHELL (tool->gdisp->shell)->statusbar); GIMP_STATUSBAR (GIMP_DISPLAY_SHELL (tool->gdisp->shell)->statusbar);
gimp_statusbar_pop (statusbar, gimp_statusbar_pop (statusbar, G_OBJECT_TYPE_NAME (tool));
G_OBJECT_TYPE_NAME (tool));
} }
void void
@ -537,7 +600,5 @@ gimp_tool_set_cursor (GimpTool *tool,
g_return_if_fail (GIMP_IS_DISPLAY (gdisp)); g_return_if_fail (GIMP_IS_DISPLAY (gdisp));
gimp_display_shell_set_cursor (GIMP_DISPLAY_SHELL (gdisp->shell), gimp_display_shell_set_cursor (GIMP_DISPLAY_SHELL (gdisp->shell),
cursor, cursor, tool_cursor, modifier);
tool_cursor,
modifier);
} }

View File

@ -45,6 +45,13 @@ struct _GimpTool
GimpDisplay *gdisp; /* pointer to currently active gdisp */ GimpDisplay *gdisp; /* pointer to currently active gdisp */
GimpDrawable *drawable; /* pointer to the tool's current drawable */ GimpDrawable *drawable; /* pointer to the tool's current drawable */
/* focus_display and modifier_state are *private* state of
* gimp_tool_set_focus_display() and gimp_tool_set_modifier_state().
* ignore them in tool implementations, they don't exist!
*/
GimpDisplay *focus_display;
GdkModifierType modifier_state;
}; };
struct _GimpToolClass struct _GimpToolClass
@ -122,9 +129,10 @@ void gimp_tool_motion (GimpTool *tool,
void gimp_tool_arrow_key (GimpTool *tool, void gimp_tool_arrow_key (GimpTool *tool,
GdkEventKey *kevent, GdkEventKey *kevent,
GimpDisplay *gdisp); GimpDisplay *gdisp);
void gimp_tool_modifier_key (GimpTool *tool,
GdkModifierType key, void gimp_tool_set_focus_display (GimpTool *tool,
gboolean press, GimpDisplay *gdisp);
void gimp_tool_set_modifier_state (GimpTool *tool,
GdkModifierType state, GdkModifierType state,
GimpDisplay *gdisp); GimpDisplay *gdisp);

View File

@ -158,6 +158,8 @@ tool_manager_select_tool (Gimp *gimp,
if (gdisp) if (gdisp)
tool_manager_control_active (gimp, HALT, gdisp); tool_manager_control_active (gimp, HALT, gdisp);
tool_manager_focus_display_active (gimp, NULL);
g_object_unref (tool_manager->active_tool); g_object_unref (tool_manager->active_tool);
} }
@ -339,9 +341,24 @@ tool_manager_arrow_key_active (Gimp *gimp,
} }
void void
tool_manager_modifier_key_active (Gimp *gimp, tool_manager_focus_display_active (Gimp *gimp,
GdkModifierType key, GimpDisplay *gdisp)
gboolean press, {
GimpToolManager *tool_manager;
g_return_if_fail (GIMP_IS_GIMP (gimp));
tool_manager = tool_manager_get (gimp);
if (tool_manager->active_tool)
{
gimp_tool_set_focus_display (tool_manager->active_tool,
gdisp);
}
}
void
tool_manager_modifier_state_active (Gimp *gimp,
GdkModifierType state, GdkModifierType state,
GimpDisplay *gdisp) GimpDisplay *gdisp)
{ {
@ -353,8 +370,8 @@ tool_manager_modifier_key_active (Gimp *gimp,
if (tool_manager->active_tool) if (tool_manager->active_tool)
{ {
gimp_tool_modifier_key (tool_manager->active_tool, gimp_tool_set_modifier_state (tool_manager->active_tool,
key, press, state, state,
gdisp); gdisp);
} }
} }
@ -404,7 +421,6 @@ tool_manager_cursor_update_active (Gimp *gimp,
static GQuark tool_manager_quark = 0; static GQuark tool_manager_quark = 0;
static GimpToolManager * static GimpToolManager *
tool_manager_get (Gimp *gimp) tool_manager_get (Gimp *gimp)
{ {

View File

@ -56,11 +56,13 @@ void tool_manager_motion_active (Gimp *gimp,
void tool_manager_arrow_key_active (Gimp *gimp, void tool_manager_arrow_key_active (Gimp *gimp,
GdkEventKey *kevent, GdkEventKey *kevent,
GimpDisplay *gdisp); GimpDisplay *gdisp);
void tool_manager_modifier_key_active (Gimp *gimp,
GdkModifierType key, void tool_manager_focus_display_active (Gimp *gimp,
gboolean press, GimpDisplay *gdisp);
void tool_manager_modifier_state_active (Gimp *gimp,
GdkModifierType state, GdkModifierType state,
GimpDisplay *gdisp); GimpDisplay *gdisp);
void tool_manager_oper_update_active (Gimp *gimp, void tool_manager_oper_update_active (Gimp *gimp,
GimpCoords *coords, GimpCoords *coords,
GdkModifierType state, GdkModifierType state,