summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/desktop.cpp14
-rw-r--r--src/desktop.h2
-rw-r--r--src/display/sp-canvas.cpp9
-rw-r--r--src/display/sp-canvas.h5
-rw-r--r--src/ui/tools/tool-base.cpp10
-rw-r--r--src/widgets/desktop-widget.cpp10
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);