X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fevent-context.cpp;h=76fe7263683df89dbb1d21efdd29d48363b912fb;hb=ad4b3133547bb79aa1362ab40512d31267868c82;hp=42557abdca71a990a428f04d82a82817eda3ddd2;hpb=dbe32b890d08ee7a085dcee01234f24e32db5ee1;p=inkscape.git diff --git a/src/event-context.cpp b/src/event-context.cpp index 42557abdc..76fe72636 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) { @@ -450,38 +432,53 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, } 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)) { + // GDK insists on stealing these keys (F1 for no idea what, tab for cycling widgets + // in the editing window). So we resteal them back and run our regular shortcut + // invoker on them. unsigned int shortcut; + case GDK_Tab: + case GDK_ISO_Left_Tab: case GDK_F1: - /* Grab it away from Gtk */ shortcut = get_group0_keyval(&event->key); if (event->key.state & GDK_SHIFT_MASK) shortcut |= SP_SHORTCUT_SHIFT_MASK; @@ -492,22 +489,6 @@ static gint sp_event_context_private_root_handler(SPEventContext *event_context, ret = sp_shortcut_invoke(shortcut, desktop); break; - case GDK_Tab: // disable tab/shift-tab which cycle widget focus - case GDK_ISO_Left_Tab: // they will get different functions - if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { - ret = TRUE; - } else { - /* Grab it away from Gtk */ - shortcut = get_group0_keyval(&event->key); - if (event->key.state & GDK_SHIFT_MASK) - shortcut |= SP_SHORTCUT_SHIFT_MASK; - if (event->key.state & GDK_CONTROL_MASK) - shortcut |= SP_SHORTCUT_CONTROL_MASK; - if (event->key.state & GDK_MOD1_MASK) - shortcut |= SP_SHORTCUT_ALT_MASK; - ret = sp_shortcut_invoke(shortcut, desktop); - } - break; case GDK_W: case GDK_w: case GDK_F4: @@ -521,7 +502,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); @@ -532,7 +513,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); @@ -543,7 +524,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); @@ -554,7 +535,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);