X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fevent-context.cpp;h=37711e9143fc89a656565280753dbb11a16fe97f;hb=1c2557cd7259a8166f07b7982a44e040a44d4db1;hp=e63df0d2f5eedff819df23361987fe696f2d5c99;hpb=b2c82cd0a29a9d7c756d0afef6aba284323a50ab;p=inkscape.git diff --git a/src/event-context.cpp b/src/event-context.cpp index e63df0d2f..37711e914 100644 --- a/src/event-context.cpp +++ b/src/event-context.cpp @@ -190,6 +190,7 @@ sp_event_context_update_cursor(SPEventContext *ec) } gdk_window_set_cursor(w->window, ec->cursor); } + ec->desktop->waiting_cursor = false; } /** @@ -276,15 +277,23 @@ sp_toggle_selector(SPDesktop *dt) * Calculates and keeps track of scroll acceleration. * Subroutine of sp_event_context_private_root_handler(). */ -static gdouble accelerate_scroll(GdkEvent *event, gdouble acceleration) +static gdouble accelerate_scroll(GdkEvent *event, gdouble acceleration, SPCanvas *canvas) { guint32 time_diff = ((GdkEventKey *) event)->time - scroll_event_time; + glong slowest_buffer = canvas->slowest_buffer / 1000; // the buffer time is in usec, but event time is in msec + + // reduce time interval by the time it took to paint slowest buffer, + // so that acceleration does not hiccup on complex slow-rendering drawings + if ((guint32) slowest_buffer <= time_diff) + time_diff -= slowest_buffer; + else + time_diff = 0; /* key pressed within 500ms ? (1/2 second) */ if (time_diff > 500 || event->key.keyval != scroll_keyval) { - scroll_multiply = 1; + scroll_multiply = 1; // abort acceleration } else { - scroll_multiply += acceleration; + scroll_multiply += acceleration; // continue acceleration } scroll_event_time = ((GdkEventKey *) event)->time; @@ -293,21 +302,6 @@ static gdouble accelerate_scroll(GdkEvent *event, gdouble acceleration) return scroll_multiply; } -// This is a hack that is necessary because when middle-clicking too fast, -// button_press events come for all clicks but there's button_release only -// for the first one. So after a release, we must prohibit the next grab for -// some time, or the grab will be stuck. Perhaps this is caused by some -// wrong handling of events among contexts and not by a GDK bug; -// if someone can fix this properly this would be great. -static gint dontgrab = 0; -static bool -grab_allow_again() -{ - dontgrab--; - if (dontgrab < 0) dontgrab = 0; - return FALSE; // so that it is only called once -} - /** * Main event dispatch, gets called from Gdk. */ @@ -352,16 +346,6 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, switch (event->button.button) { case 2: - - if (dontgrab) - // double-click, still not permitted to grab; - // increase the counter to guard against triple click - { - dontgrab ++; - gtk_timeout_add(250, (GtkFunction) grab_allow_again, NULL); - break; - } - button_w = NR::Point(event->button.x, event->button.y); if (event->button.state == GDK_SHIFT_MASK) { @@ -398,7 +382,6 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, || (panning == 3 && !(event->motion.state & GDK_BUTTON3_MASK))) { /* Gdk seems to lose button release for us sometimes :-( */ panning = 0; - dontgrab = 0; sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); ret = TRUE; @@ -421,10 +404,9 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, gobble_motion_events(panning == 2 ? GDK_BUTTON2_MASK : GDK_BUTTON3_MASK); - NR::Point const motion_w(event->motion.x, - event->motion.y); + NR::Point const motion_w(event->motion.x, event->motion.y); NR::Point const moved_w( motion_w - button_w ); - event_context->desktop->scroll_world(moved_w); + event_context->desktop->scroll_world(moved_w, true); // we're still scrolling, do not redraw ret = TRUE; } } else if (zoom_rb) { @@ -436,47 +418,56 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) { break; // do not drag if we're within tolerance from origin } - - if (within_tolerance) { - Inkscape::Rubberband::get()->start(desktop, motion_dt); - } else { - Inkscape::Rubberband::get()->move(motion_dt); - } - // Once the user has moved farther than tolerance from the original location // (indicating they intend to move the object, not click), then always process the // motion notify coordinates as given (no snapping back to origin) within_tolerance = false; + + if (Inkscape::Rubberband::get()->is_started()) { + Inkscape::Rubberband::get()->move(motion_dt); + } else { + Inkscape::Rubberband::get()->start(desktop, motion_dt); + } } break; case GDK_BUTTON_RELEASE: + xp = yp = 0; if (within_tolerance && (panning || zoom_rb)) { - dontgrab ++; zoom_rb = 0; + if (panning) { + panning = 0; + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), + event->button.time); + } NR::Point const event_w(event->button.x, event->button.y); NR::Point const event_dt(desktop->w2d(event_w)); - double const zoom_power = ( (event->button.state & GDK_SHIFT_MASK) - ? -dontgrab : dontgrab ); desktop->zoom_relative_keep_point(event_dt, - pow(zoom_inc, zoom_power)); - gtk_timeout_add(250, (GtkFunction) grab_allow_again, NULL); + (event->button.state & GDK_SHIFT_MASK) ? 1/zoom_inc : zoom_inc); desktop->updateNow(); - } - if (panning == event->button.button) { + ret = TRUE; + } else if (panning == event->button.button) { panning = 0; sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); + + // in slow complex drawings, some of the motion events are lost; + // to make up for this, we scroll it once again to the button-up event coordinates + // (i.e. canvas will always get scrolled all the way to the mouse release point, + // even if few intermediate steps were visible) + NR::Point const motion_w(event->button.x, event->button.y); + NR::Point const moved_w( motion_w - button_w ); + event_context->desktop->scroll_world(moved_w); desktop->updateNow(); ret = TRUE; } else if (zoom_rb == event->button.button) { zoom_rb = 0; NR::Maybe const b = Inkscape::Rubberband::get()->getRectangle(); - if (b != NR::Nothing() && !within_tolerance) { - desktop->set_display_area(b.assume(), 10); - } Inkscape::Rubberband::get()->stop(); + if (b && !within_tolerance) { + desktop->set_display_area(*b, 10); + } + ret = TRUE; } - xp = yp = 0; break; case GDK_KEY_PRESS: switch (get_group0_keyval(&event->key)) { @@ -510,7 +501,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, case GDK_KP_Left: case GDK_KP_4: if (MOD__CTRL_ONLY) { - int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration)); + int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration, sp_desktop_canvas(desktop))); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); event_context->desktop->scroll_world(i, 0); @@ -521,7 +512,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, case GDK_KP_Up: case GDK_KP_8: if (MOD__CTRL_ONLY) { - int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration)); + int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration, sp_desktop_canvas(desktop))); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); event_context->desktop->scroll_world(0, i); @@ -532,7 +523,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, case GDK_KP_Right: case GDK_KP_6: if (MOD__CTRL_ONLY) { - int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration)); + int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration, sp_desktop_canvas(desktop))); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); event_context->desktop->scroll_world(-i, 0); @@ -543,7 +534,7 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, case GDK_KP_Down: case GDK_KP_2: if (MOD__CTRL_ONLY) { - int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration)); + int i = (int) floor(key_scroll * accelerate_scroll(event, acceleration, sp_desktop_canvas(desktop))); gobble_key_events(get_group0_keyval(&event->key), GDK_CONTROL_MASK); event_context->desktop->scroll_world(0, -i);