From 446b6f37ba345e65b2e9792d009947a5c802f14b Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 18 Jun 2016 11:12:32 +0200 Subject: [PATCH] Fixes #246: popups are now placed correctly on all platforms --- src/selectiondialog.cc | 32 +++++++++++++++++--------------- src/selectiondialog.h | 1 - src/tooltips.cc | 39 +++++++++++++++++++++------------------ src/tooltips.h | 7 ++++--- 4 files changed, 42 insertions(+), 37 deletions(-) diff --git a/src/selectiondialog.cc b/src/selectiondialog.cc index a27c975..dd3db66 100644 --- a/src/selectiondialog.cc +++ b/src/selectiondialog.cc @@ -99,8 +99,24 @@ void SelectionDialogBase::add_row(const std::string& row) { void SelectionDialogBase::show() { shown=true; - move(); + + //Move + Gdk::Rectangle iter_rect; + text_view.get_iter_location(start_mark->get_iter(), iter_rect); + Gdk::Rectangle visible_rect; + text_view.get_visible_rect(visible_rect); + int buffer_x=std::max(iter_rect.get_x(), visible_rect.get_x()); + int buffer_y=iter_rect.get_y()+iter_rect.get_height(); + int window_x, window_y; + text_view.buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y, window_x, window_y); + int root_x, root_y; + text_view.get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y, root_x, root_y); + window.move(root_x, root_y+1); //TODO: replace 1 with some margin + window.show_all(); + //Need to move before and after show all. Some WM's disregards moves before show_all, + //and Wayland does not position correctly unless move is called before show_all + window.move(root_x, root_y+1); if(list_view_text.get_model()->children().size()>0) { if(!list_view_text.get_selection()->get_selected()) { @@ -133,20 +149,6 @@ void SelectionDialogBase::hide() { list_view_text.clear(); } -void SelectionDialogBase::move() { - Gdk::Rectangle iter_rect; - text_view.get_iter_location(start_mark->get_iter(), iter_rect); - Gdk::Rectangle visible_rect; - text_view.get_visible_rect(visible_rect); - int buffer_x=std::max(iter_rect.get_x(), visible_rect.get_x()); - int buffer_y=iter_rect.get_y()+iter_rect.get_height(); - int window_x, window_y; - text_view.buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y, window_x, window_y); - int root_x, root_y; - text_view.get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y, root_x, root_y); - window.move(root_x, root_y+1); //TODO: replace 1 with some margin -} - void SelectionDialogBase::resize() { if(list_view_text.get_realized()) { int row_width=0, row_height; diff --git a/src/selectiondialog.h b/src/selectiondialog.h index 9b80b89..f73d754 100644 --- a/src/selectiondialog.h +++ b/src/selectiondialog.h @@ -37,7 +37,6 @@ public: void set_cursor_at_last_row(); void show(); void hide(); - void move(); std::function on_hide; std::function on_select; diff --git a/src/tooltips.cc b/src/tooltips.cc index f3815fb..dea87ea 100644 --- a/src/tooltips.cc +++ b/src/tooltips.cc @@ -43,7 +43,7 @@ void Tooltip::update() { activation_rectangle.set_y(location_window_y); } -void Tooltip::adjust(bool disregard_drawn) { +void Tooltip::show(bool disregard_drawn) { if(!window) { //init window window=std::unique_ptr(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP)); @@ -70,8 +70,8 @@ void Tooltip::adjust(bool disregard_drawn) { auto layout=Pango::Layout::create(tooltip_widget->get_pango_context()); layout->set_text(tooltip_widget->get_buffer()->get_text()); - layout->get_pixel_size(tooltip_width, tooltip_height); - tooltip_height+=2; + layout->get_pixel_size(size.first, size.second); + size.second+=2; } //Adjust if tooltip is left of text_view @@ -85,14 +85,14 @@ void Tooltip::adjust(bool disregard_drawn) { text_view.get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x, activation_rectangle.get_y(), root_x, root_y); Gdk::Rectangle rectangle; rectangle.set_x(root_x); - rectangle.set_y(std::max(0, root_y-tooltip_height)); - rectangle.set_width(tooltip_width); - rectangle.set_height(tooltip_height); + rectangle.set_y(std::max(0, root_y-size.second)); + rectangle.set_width(size.first); + rectangle.set_height(size.second); if(!disregard_drawn) { if(Tooltips::drawn_tooltips_rectangle.get_width()!=0) { if(rectangle.intersects(Tooltips::drawn_tooltips_rectangle)) { - int new_y=Tooltips::drawn_tooltips_rectangle.get_y()-tooltip_height; + int new_y=Tooltips::drawn_tooltips_rectangle.get_y()-size.second; if(new_y>=0) rectangle.set_y(new_y); else @@ -104,7 +104,14 @@ void Tooltip::adjust(bool disregard_drawn) { Tooltips::drawn_tooltips_rectangle=rectangle; } - window->move(rectangle.get_x(), rectangle.get_y()); + window->move(rectangle.get_x(), rectangle.get_y()); //Added since selectiondialog gets positioned wrong on Wayland unless move is placed before show_all + window->show_all(); + window->move(rectangle.get_x(), rectangle.get_y()); //Need both since some VM's disregards moves before show_all +} + +void Tooltip::hide() { + if(window) + window->hide(); } void Tooltip::wrap_lines(Glib::RefPtr text_buffer) { @@ -153,28 +160,24 @@ void Tooltips::show(const Gdk::Rectangle& rectangle, bool disregard_drawn) { for(auto &tooltip : tooltip_list) { tooltip.update(); if(rectangle.intersects(tooltip.activation_rectangle)) { - tooltip.adjust(disregard_drawn); - tooltip.window->show_all(); + tooltip.show(disregard_drawn); shown=true; } - else if(tooltip.window) - tooltip.window->hide(); + else + tooltip.hide(); } } void Tooltips::show(bool disregard_drawn) { for(auto &tooltip : tooltip_list) { tooltip.update(); - tooltip.adjust(disregard_drawn); - tooltip.window->show_all(); + tooltip.show(disregard_drawn); shown=true; } } void Tooltips::hide() { - for(auto &tooltip : tooltip_list) { - if(tooltip.window) - tooltip.window->hide(); - } + for(auto &tooltip : tooltip_list) + tooltip.hide(); shown=false; } diff --git a/src/tooltips.h b/src/tooltips.h index 66d87a9..d4a363a 100644 --- a/src/tooltips.h +++ b/src/tooltips.h @@ -10,19 +10,20 @@ public: ~Tooltip(); void update(); - void adjust(bool disregard_drawn=false); + void show(bool disregard_drawn=false); + void hide(); Gdk::Rectangle activation_rectangle; - std::unique_ptr window; Glib::RefPtr start_mark; Glib::RefPtr end_mark; private: + std::unique_ptr window; void wrap_lines(Glib::RefPtr text_buffer); std::function()> create_tooltip_buffer; std::unique_ptr tooltip_widget; Gtk::TextView& text_view; - int tooltip_width, tooltip_height; + std::pair size; }; class Tooltips {