Re: Viewport diagonal scrolling redraw



On 02/16/2011 01:41 PM, rendaw wrote:

On February 16, 2011 at 12:45 PM jcupitt gmail com wrote:

> On 16 February 2011 04:48, Rendaw <rendaw zarbosoft com> wrote:
> > As a side note, does gdk_window_process_updates() preserve mouse motion > > events when the MOTION_HINT mask is set? I also had motion event queuing > > problems (I would stop moving the mouse but the screen would continually
> > redraw for a few seconds until it had caught up) before I moved the
> > gtk_adjustment_set_value()'s out of the motion handling code and into a
> > g_idle_add callback.
>
> I don't know how to get silky diagonal scrolling easily, but I can
> help here (I think). The solution I found was to calculate all mouse
> movement relative to the root window, not the window being scrolled.
>
> In the motion event, there are a couple of fields called x_root and
> y_root. Record these on button down together with the scroll position
> of the underlying window, then during motion, scroll the window to the
> position found by subtracting the start x_root from the current x_root
> plus the original x.
>
> This makes these feedback effects (which can be bizarre and horrible)
> impossible.
>
> John

Ah thanks, I might try that, it might be a bit cleaner than what I have now. That problem isn't actually feedback, I think -- but repeated expose events not being dropped (despite the motion hint, because of gdk_window_process_updates). It's more like watching a slo-mo video of your previous actions. The feedback thing I have licked for now.


I got a hack working for the multiple adjustment update horizontal and vertical jerking!

Summary of the problem: I want to scroll diagonally, so I change the values of both horizontal and vertical adjustments. However, each adjustment value update triggers a window refresh, so for large scrolls the image flashes off to the side before being drawn at the final location.

My solution: If I'm chaging both adjustment values, I suppress the horizontal one (since I'm updating it first) using g_signal_handlers_block_matched, and unblock it after the horizontal adjustment update.

if (SuppressFirst)
    g_signal_handlers_block_matched(Adjustment, G_SIGNAL_MATCH_DATA,
        g_signal_lookup("value-changed", G_TYPE_FROM_INSTANCE(Adjustment)),
        0, NULL, NULL, GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(Scroller))));
gtk_adjustment_set_value(...);
if (SuppressFirst)
    g_signal_handlers_unblock_matched(Adjustment, G_SIGNAL_MATCH_DATA,
        g_signal_lookup("value-changed", G_TYPE_FROM_INSTANCE(Adjustment)),
        0, NULL, NULL, GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(Scroller))));

Then I update the second adjustment, which causes the viewport to do all the updating it didn't do before (-- it doesn't have separate methods for handling horizontal and vertical updates, thankfully). Pretty nasty, but not as nasty as before!

I'm open to better solutions, if there are any.

Cheers,
Rendaw



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]