From 6f91dc07995da4894fafb7f9405739cae2afc800 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 10 Dec 2021 18:17:58 -0700 Subject: [PATCH] canvas: fix an issue with event coordinate translation by ScrollGroup If there's a grabbed item (GtkCanvas only at present) then unless it belongs to the scroll group used for scroll offset translation, the event coordinates should not be translated, even if the mouse pointer moves into the scroll group. --- libs/canvas/canvas.cc | 18 +++++++++++++++++- libs/canvas/canvas/canvas.h | 6 ++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/libs/canvas/canvas.cc b/libs/canvas/canvas.cc index 5b4e4d1b9c..955b999509 100644 --- a/libs/canvas/canvas.cc +++ b/libs/canvas/canvas.cc @@ -299,6 +299,7 @@ Canvas::window_to_canvas (Duple const & d) const { ScrollGroup* best_group = 0; ScrollGroup* sg = 0; + bool grabbed_item_inside = false; /* if the coordinates are negative, clamp to zero and find the item * that covers that "edge" position. @@ -329,7 +330,11 @@ Canvas::window_to_canvas (Duple const & d) const only group. */ if (!best_group || sg->sensitivity() > best_group->sensitivity()) { + best_group = sg; + + grabbed_item_inside = check_grabbed_item_inside (sg); + if (sg->sensitivity() == (ScrollGroup::ScrollsVertically | ScrollGroup::ScrollsHorizontally)) { /* Can't do any better than this. */ break; @@ -338,7 +343,7 @@ Canvas::window_to_canvas (Duple const & d) const } } - if (best_group) { + if (best_group && (!have_grab() || grabbed_item_inside)) { return d.translate (best_group->scroll_offset()); } @@ -1512,6 +1517,16 @@ GtkCanvas::resize_handler () return false; } +bool +GtkCanvas::check_grabbed_item_inside (Item* possible_parent) const +{ + if (!_grabbed_item) { + return false; + } + + return _grabbed_item->is_descendant_of (*possible_parent); +} + /** Create a GtkCanvaSViewport. * @param hadj Adjustment to use for horizontal scrolling. * @param vadj Adjustment to use for vertica scrolling. @@ -1549,3 +1564,4 @@ GtkCanvasViewport::on_size_request (Gtk::Requisition* req) req->width = width; req->height = height; } + diff --git a/libs/canvas/canvas/canvas.h b/libs/canvas/canvas/canvas.h index 5a5cdddd85..265fbd8ae2 100644 --- a/libs/canvas/canvas/canvas.h +++ b/libs/canvas/canvas/canvas.h @@ -91,6 +91,9 @@ public: /** called to ask the canvas' host to drop keyboard focus on an item */ virtual void unfocus (Item*) = 0; + virtual bool have_grab() const { return false; } + virtual bool check_grabbed_item_inside (Item*) const { return false; } + void render (Rect const &, Cairo::RefPtr const &) const; void prepare_for_render (Rect const &) const; @@ -214,6 +217,9 @@ public: void focus (Item *); void unfocus (Item*); + bool have_grab() const { return _grabbed_item; } + bool check_grabbed_item_inside (Item*) const; + Rect visible_area () const; Coord width() const; Coord height() const;