diff options
| -rw-r--r-- | src/desktop.cpp | 14 | ||||
| -rw-r--r-- | src/desktop.h | 2 | ||||
| -rw-r--r-- | src/display/sp-canvas.cpp | 9 | ||||
| -rw-r--r-- | src/display/sp-canvas.h | 5 | ||||
| -rw-r--r-- | src/ui/tools/tool-base.cpp | 10 | ||||
| -rw-r--r-- | src/widgets/desktop-widget.cpp | 10 |
6 files changed, 36 insertions, 14 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp index a9e318b78..650878968 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -769,23 +769,19 @@ SPItem *SPDesktop::getGroupAtPoint(Geom::Point const &p) const * Returns the mouse point in document coordinates; if mouse is * outside the canvas, returns the center of canvas viewpoint. */ -Geom::Point SPDesktop::point(bool outside_infinite) const +Geom::Point SPDesktop::point(bool outside_canvas) const { Geom::Point p = _widget->getPointer(); Geom::Point pw = sp_canvas_window_to_world (canvas, p); Geom::Rect const r = canvas->getViewbox(); - if (r.interiorContains(pw)) { + if (r.interiorContains(pw) || outside_canvas) { p = w2d(pw); return p; } - if (outside_infinite) { - return Geom::Point(Geom::infinity(), Geom::infinity()); - } else { - Geom::Point r0 = w2d(r.min()); - Geom::Point r1 = w2d(r.max()); - return (r0 + r1) / 2.0; - } + Geom::Point r0 = w2d(r.min()); + Geom::Point r1 = w2d(r.max()); + return (r0 + r1) / 2.0; } diff --git a/src/desktop.h b/src/desktop.h index 1e9c9819f..735e85682 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -324,7 +324,7 @@ public: SPItem *getItemFromListAtPointBottom(const std::vector<SPItem*> &list, Geom::Point const &p) const; SPItem *getItemAtPoint(Geom::Point const &p, bool into_groups, SPItem *upto = nullptr) const; SPItem *getGroupAtPoint(Geom::Point const &p) const; - Geom::Point point(bool outside_infinite = false) const; + Geom::Point point(bool outside_canvas = false) const; void prev_transform(); void next_transform(); diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index cb42f2daf..71478eaeb 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -1012,6 +1012,7 @@ static void sp_canvas_init(SPCanvas *canvas) canvas->_xray = false; canvas->_xray_orig = Geom::Point(); canvas->_changecursor = 0; + canvas->_inside = false; // this could be wrong on start but we update it as far we bo to the other side. bool _is_dragging; #if defined(HAVE_LIBLCMS2) @@ -1167,7 +1168,7 @@ void SPCanvas::handle_size_allocate(GtkWidget *widget, GtkAllocation *allocation // Allocation does not depend on device scale. GtkAllocation old_allocation; gtk_widget_get_allocation(widget, &old_allocation); - + // For HiDPI monitors. canvas->_device_scale = gtk_widget_get_scale_factor( widget ); @@ -2318,7 +2319,11 @@ gint SPCanvas::handle_crossing(GtkWidget *widget, GdkEventCrossing *event) if (event->window != getWindow(canvas)) { return FALSE; } - + if (event->type == GDK_LEAVE_NOTIFY) { + canvas->_inside = false; + } else { + canvas->_inside = true; + } canvas->_state = event->state; return canvas->pickCurrentItem(reinterpret_cast<GdkEvent *>(event)); } diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index b4be65887..9242cce6e 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -99,7 +99,7 @@ struct SPCanvas { private: /// Emits an event for an item in the canvas, be it the current /// item, grabbed item, or focused item, as appropriate. - int emitEvent(GdkEvent *event); + int emitEvent(GdkEvent *event); /// Re-picks the current item in the canvas, based on the event's /// coordinates and emits enter/leave events for items as appropriate. @@ -223,6 +223,9 @@ public: /// Last known modifier state, for deferred repick when a button is down. int _state; + /// Get idf we are outside canvas area + bool _inside; + /** The item containing the mouse pointer, or NULL if none. */ SPCanvasItem *_current_item; diff --git a/src/ui/tools/tool-base.cpp b/src/ui/tools/tool-base.cpp index ee0e27e4b..cadce0c0d 100644 --- a/src/ui/tools/tool-base.cpp +++ b/src/ui/tools/tool-base.cpp @@ -1076,6 +1076,16 @@ void sp_event_context_read(ToolBase *ec, gchar const *key) { gint sp_event_context_root_handler(ToolBase * event_context, GdkEvent * event) { + Geom::Point pos = Geom::Point(0,0); + if ((event->type == GDK_BUTTON_RELEASE || + event->type == GDK_MOTION_NOTIFY) && + !event_context->desktop->canvas->_inside) + { + pos = event_context->desktop->d2w(event_context->desktop->point(true)); + event->motion.x = pos[Geom::X]; + event->motion.y = pos[Geom::Y]; + } + if (!event_context->_uses_snap) { return sp_event_context_virtual_root_handler(event_context, event); } diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 7ddf56eb2..75f48f827 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -508,7 +508,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_style_context_add_provider(style_context, GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER); - g_signal_connect (G_OBJECT (dtw->_canvas), "event", G_CALLBACK (SPDesktopWidget::event), dtw); + g_signal_connect (G_OBJECT (dtw), "event", G_CALLBACK (SPDesktopWidget::event), dtw); gtk_widget_set_hexpand(GTK_WIDGET(dtw->_canvas), TRUE); gtk_widget_set_vexpand(GTK_WIDGET(dtw->_canvas), TRUE); @@ -1000,6 +1000,14 @@ SPDesktopWidget::event(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw) // is over the canvas. This redirection is only done for key events and only if there's no // current item on the canvas, because item events and all mouse events are caught // and passed on by the canvas acetate (I think). --bb + + if ((event->type == GDK_MOTION_NOTIFY || + event->type == GDK_BUTTON_RELEASE) && + !dtw->_canvas->_inside) + { + return sp_desktop_root_handler (nullptr, event, dtw->desktop); + } + if ((event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) && !dtw->_canvas->_current_item) { return sp_desktop_root_handler (nullptr, event, dtw->desktop); |
