mirror of https://github.com/GNOME/gimp.git
app: don't do any queue_resize() in the canvas' size-allocate callback
which means we can't setup scrollbars there. Move the code to a GtkTickCallback which runs before the next frame after the size-allocate. Also put the center_image_on_size_allocate() code there because it has to run after the canvas' tick callback, and the order of tick callbacks can't be controlled. As a side effect we now have a flag in GimpDisplayShell which indicates that there will be a size allocate before the next frame, so simply skip drawing the canvas completely. This fixes new images jumping around when they are first shown.
This commit is contained in:
parent
478d18f6c5
commit
c0480f502d
|
@ -118,23 +118,23 @@ gimp_display_shell_canvas_realize (GtkWidget *canvas,
|
||||||
shell->xfer = gimp_display_xfer_realize (GTK_WIDGET(shell));
|
shell->xfer = gimp_display_xfer_realize (GTK_WIDGET(shell));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static gboolean
|
||||||
gimp_display_shell_canvas_size_allocate (GtkWidget *widget,
|
gimp_display_shell_canvas_tick (GtkWidget *widget,
|
||||||
GtkAllocation *allocation,
|
GdkFrameClock *frame_clock,
|
||||||
GimpDisplayShell *shell)
|
GimpDisplayShell *shell)
|
||||||
{
|
{
|
||||||
/* are we in destruction? */
|
GtkAllocation allocation;
|
||||||
if (! shell->display || ! gimp_display_get_shell (shell->display))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ((shell->disp_width != allocation->width) ||
|
gtk_widget_get_allocation (widget, &allocation);
|
||||||
(shell->disp_height != allocation->height))
|
|
||||||
|
if ((shell->disp_width != allocation.width) ||
|
||||||
|
(shell->disp_height != allocation.height))
|
||||||
{
|
{
|
||||||
if (shell->zoom_on_resize &&
|
if (shell->zoom_on_resize &&
|
||||||
shell->disp_width > 64 &&
|
shell->disp_width > 64 &&
|
||||||
shell->disp_height > 64 &&
|
shell->disp_height > 64 &&
|
||||||
allocation->width > 64 &&
|
allocation.width > 64 &&
|
||||||
allocation->height > 64)
|
allocation.height > 64)
|
||||||
{
|
{
|
||||||
gdouble scale = gimp_zoom_model_get_factor (shell->zoom);
|
gdouble scale = gimp_zoom_model_get_factor (shell->zoom);
|
||||||
gint offset_x;
|
gint offset_x;
|
||||||
|
@ -145,8 +145,8 @@ gimp_display_shell_canvas_size_allocate (GtkWidget *widget,
|
||||||
/* multiply the zoom_factor with the ratio of the new and
|
/* multiply the zoom_factor with the ratio of the new and
|
||||||
* old canvas diagonals
|
* old canvas diagonals
|
||||||
*/
|
*/
|
||||||
scale *= (sqrt (SQR (allocation->width) +
|
scale *= (sqrt (SQR (allocation.width) +
|
||||||
SQR (allocation->height)) /
|
SQR (allocation.height)) /
|
||||||
sqrt (SQR (shell->disp_width) +
|
sqrt (SQR (shell->disp_width) +
|
||||||
SQR (shell->disp_height)));
|
SQR (shell->disp_height)));
|
||||||
|
|
||||||
|
@ -159,8 +159,8 @@ gimp_display_shell_canvas_size_allocate (GtkWidget *widget,
|
||||||
shell->offset_y = SCALEY (shell, offset_y);
|
shell->offset_y = SCALEY (shell, offset_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
shell->disp_width = allocation->width;
|
shell->disp_width = allocation.width;
|
||||||
shell->disp_height = allocation->height;
|
shell->disp_height = allocation.height;
|
||||||
|
|
||||||
/* When we size-allocate due to resize of the top level window,
|
/* When we size-allocate due to resize of the top level window,
|
||||||
* we want some additional logic. Don't apply it on
|
* we want some additional logic. Don't apply it on
|
||||||
|
@ -210,12 +210,34 @@ gimp_display_shell_canvas_size_allocate (GtkWidget *widget,
|
||||||
gimp_display_shell_scroll_clamp_and_update (shell);
|
gimp_display_shell_scroll_clamp_and_update (shell);
|
||||||
gimp_display_shell_scaled (shell);
|
gimp_display_shell_scaled (shell);
|
||||||
|
|
||||||
/* Reset */
|
|
||||||
shell->size_allocate_from_configure_event = FALSE;
|
shell->size_allocate_from_configure_event = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shell->size_allocate_center_image)
|
||||||
|
{
|
||||||
|
gimp_display_shell_scroll_center_image (shell, TRUE, TRUE);
|
||||||
|
|
||||||
|
shell->size_allocate_center_image = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* undo size request from gimp_display_shell_constructed() */
|
/* undo size request from gimp_display_shell_constructed() */
|
||||||
gtk_widget_set_size_request (widget, -1, -1);
|
gtk_widget_set_size_request (widget, -1, -1);
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gimp_display_shell_canvas_size_allocate (GtkWidget *widget,
|
||||||
|
GtkAllocation *allocation,
|
||||||
|
GimpDisplayShell *shell)
|
||||||
|
{
|
||||||
|
/* are we in destruction? */
|
||||||
|
if (! shell->display || ! gimp_display_get_shell (shell->display))
|
||||||
|
return;
|
||||||
|
|
||||||
|
gtk_widget_add_tick_callback (widget,
|
||||||
|
(GtkTickCallback) gimp_display_shell_canvas_tick,
|
||||||
|
shell, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -227,6 +249,12 @@ gimp_display_shell_canvas_draw (GtkWidget *widget,
|
||||||
if (! shell->display || ! gimp_display_get_shell (shell->display))
|
if (! shell->display || ! gimp_display_get_shell (shell->display))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
/* we will scroll around in the next tick anyway, so we just can as
|
||||||
|
* well skip the drawing of this frame and wait for the next
|
||||||
|
*/
|
||||||
|
if (shell->size_allocate_center_image)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
/* ignore events on overlays */
|
/* ignore events on overlays */
|
||||||
if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
|
if (gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
|
||||||
{
|
{
|
||||||
|
|
|
@ -389,60 +389,6 @@ gimp_display_shell_scroll_center_image (GimpDisplayShell *shell,
|
||||||
gimp_display_shell_scroll (shell, offset_x, offset_y);
|
gimp_display_shell_scroll (shell, offset_x, offset_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GimpDisplayShell *shell;
|
|
||||||
gboolean vertically;
|
|
||||||
gboolean horizontally;
|
|
||||||
} CenterImageData;
|
|
||||||
|
|
||||||
static void
|
|
||||||
gimp_display_shell_scroll_center_image_callback (GtkWidget *canvas,
|
|
||||||
GtkAllocation *allocation,
|
|
||||||
CenterImageData *data)
|
|
||||||
{
|
|
||||||
g_signal_handlers_disconnect_by_func (canvas,
|
|
||||||
gimp_display_shell_scroll_center_image_callback,
|
|
||||||
data);
|
|
||||||
|
|
||||||
gimp_display_shell_scroll_center_image (data->shell,
|
|
||||||
data->horizontally,
|
|
||||||
data->vertically);
|
|
||||||
|
|
||||||
g_slice_free (CenterImageData, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gimp_display_shell_scroll_center_image_on_size_allocate:
|
|
||||||
* @shell:
|
|
||||||
*
|
|
||||||
* Centers the image in the display as soon as the canvas has got its
|
|
||||||
* new size.
|
|
||||||
*
|
|
||||||
* Only call this if you are sure the canvas size will change.
|
|
||||||
* (Otherwise the signal connection and centering will lurk until the
|
|
||||||
* canvas size is changed e.g. by toggling the rulers.)
|
|
||||||
**/
|
|
||||||
void
|
|
||||||
gimp_display_shell_scroll_center_image_on_size_allocate (GimpDisplayShell *shell,
|
|
||||||
gboolean horizontally,
|
|
||||||
gboolean vertically)
|
|
||||||
{
|
|
||||||
CenterImageData *data;
|
|
||||||
|
|
||||||
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
|
|
||||||
|
|
||||||
data = g_slice_new (CenterImageData);
|
|
||||||
|
|
||||||
data->shell = shell;
|
|
||||||
data->horizontally = horizontally;
|
|
||||||
data->vertically = vertically;
|
|
||||||
|
|
||||||
g_signal_connect (shell->canvas, "size-allocate",
|
|
||||||
G_CALLBACK (gimp_display_shell_scroll_center_image_callback),
|
|
||||||
data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gimp_display_shell_scroll_get_scaled_viewport:
|
* gimp_display_shell_scroll_get_scaled_viewport:
|
||||||
* @shell:
|
* @shell:
|
||||||
|
|
|
@ -40,10 +40,6 @@ void gimp_display_shell_scroll_center_image_xy (GimpDisplayShell *shell,
|
||||||
void gimp_display_shell_scroll_center_image (GimpDisplayShell *shell,
|
void gimp_display_shell_scroll_center_image (GimpDisplayShell *shell,
|
||||||
gboolean horizontally,
|
gboolean horizontally,
|
||||||
gboolean vertically);
|
gboolean vertically);
|
||||||
void gimp_display_shell_scroll_center_image_on_size_allocate
|
|
||||||
(GimpDisplayShell *shell,
|
|
||||||
gboolean horizontally,
|
|
||||||
gboolean vertically);
|
|
||||||
|
|
||||||
void gimp_display_shell_scroll_get_scaled_viewport (GimpDisplayShell *shell,
|
void gimp_display_shell_scroll_get_scaled_viewport (GimpDisplayShell *shell,
|
||||||
gint *x,
|
gint *x,
|
||||||
|
|
|
@ -675,8 +675,7 @@ gimp_display_shell_constructed (GObject *object)
|
||||||
* not even finished creating the display shell, we can safely
|
* not even finished creating the display shell, we can safely
|
||||||
* assume we will get a size-allocate later.
|
* assume we will get a size-allocate later.
|
||||||
*/
|
*/
|
||||||
gimp_display_shell_scroll_center_image_on_size_allocate (shell,
|
shell->size_allocate_center_image = TRUE;
|
||||||
TRUE, TRUE);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1411,11 +1410,6 @@ gimp_display_shell_fill (GimpDisplayShell *shell,
|
||||||
gimp_display_shell_set_initial_scale (shell, scale, NULL, NULL);
|
gimp_display_shell_set_initial_scale (shell, scale, NULL, NULL);
|
||||||
gimp_display_shell_scale_update (shell);
|
gimp_display_shell_scale_update (shell);
|
||||||
|
|
||||||
/* center the image so subsequent stuff only moves it a little in
|
|
||||||
* the center
|
|
||||||
*/
|
|
||||||
gimp_display_shell_scroll_center_image (shell, TRUE, TRUE);
|
|
||||||
|
|
||||||
gimp_display_shell_sync_config (shell, config);
|
gimp_display_shell_sync_config (shell, config);
|
||||||
|
|
||||||
gimp_image_window_suspend_keep_pos (window);
|
gimp_image_window_suspend_keep_pos (window);
|
||||||
|
@ -1432,7 +1426,7 @@ gimp_display_shell_fill (GimpDisplayShell *shell,
|
||||||
/* A size-allocate will always occur because the scrollbars will
|
/* A size-allocate will always occur because the scrollbars will
|
||||||
* become visible forcing the canvas to become smaller
|
* become visible forcing the canvas to become smaller
|
||||||
*/
|
*/
|
||||||
gimp_display_shell_scroll_center_image_on_size_allocate (shell, TRUE, TRUE);
|
shell->size_allocate_center_image = TRUE;
|
||||||
|
|
||||||
if (shell->blink_timeout_id)
|
if (shell->blink_timeout_id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -178,6 +178,7 @@ struct _GimpDisplayShell
|
||||||
gboolean zoom_on_resize;
|
gboolean zoom_on_resize;
|
||||||
|
|
||||||
gboolean size_allocate_from_configure_event;
|
gboolean size_allocate_from_configure_event;
|
||||||
|
gboolean size_allocate_center_image;
|
||||||
|
|
||||||
/* the state of gimp_display_shell_tool_events() */
|
/* the state of gimp_display_shell_tool_events() */
|
||||||
GdkDevice *grab_pointer;
|
GdkDevice *grab_pointer;
|
||||||
|
|
Loading…
Reference in New Issue