Browse Source

Fixes #246: popups are now placed correctly on all platforms

merge-requests/365/head
eidheim 10 years ago
parent
commit
446b6f37ba
  1. 32
      src/selectiondialog.cc
  2. 1
      src/selectiondialog.h
  3. 39
      src/tooltips.cc
  4. 7
      src/tooltips.h

32
src/selectiondialog.cc

@ -99,8 +99,24 @@ void SelectionDialogBase::add_row(const std::string& row) {
void SelectionDialogBase::show() { void SelectionDialogBase::show() {
shown=true; 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(); 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_model()->children().size()>0) {
if(!list_view_text.get_selection()->get_selected()) { if(!list_view_text.get_selection()->get_selected()) {
@ -133,20 +149,6 @@ void SelectionDialogBase::hide() {
list_view_text.clear(); 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() { void SelectionDialogBase::resize() {
if(list_view_text.get_realized()) { if(list_view_text.get_realized()) {
int row_width=0, row_height; int row_width=0, row_height;

1
src/selectiondialog.h

@ -37,7 +37,6 @@ public:
void set_cursor_at_last_row(); void set_cursor_at_last_row();
void show(); void show();
void hide(); void hide();
void move();
std::function<void()> on_hide; std::function<void()> on_hide;
std::function<void(const std::string& selected, bool hide_window)> on_select; std::function<void(const std::string& selected, bool hide_window)> on_select;

39
src/tooltips.cc

@ -43,7 +43,7 @@ void Tooltip::update() {
activation_rectangle.set_y(location_window_y); activation_rectangle.set_y(location_window_y);
} }
void Tooltip::adjust(bool disregard_drawn) { void Tooltip::show(bool disregard_drawn) {
if(!window) { if(!window) {
//init window //init window
window=std::unique_ptr<Gtk::Window>(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP)); window=std::unique_ptr<Gtk::Window>(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()); auto layout=Pango::Layout::create(tooltip_widget->get_pango_context());
layout->set_text(tooltip_widget->get_buffer()->get_text()); layout->set_text(tooltip_widget->get_buffer()->get_text());
layout->get_pixel_size(tooltip_width, tooltip_height); layout->get_pixel_size(size.first, size.second);
tooltip_height+=2; size.second+=2;
} }
//Adjust if tooltip is left of text_view //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); 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; Gdk::Rectangle rectangle;
rectangle.set_x(root_x); rectangle.set_x(root_x);
rectangle.set_y(std::max(0, root_y-tooltip_height)); rectangle.set_y(std::max(0, root_y-size.second));
rectangle.set_width(tooltip_width); rectangle.set_width(size.first);
rectangle.set_height(tooltip_height); rectangle.set_height(size.second);
if(!disregard_drawn) { if(!disregard_drawn) {
if(Tooltips::drawn_tooltips_rectangle.get_width()!=0) { if(Tooltips::drawn_tooltips_rectangle.get_width()!=0) {
if(rectangle.intersects(Tooltips::drawn_tooltips_rectangle)) { 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) if(new_y>=0)
rectangle.set_y(new_y); rectangle.set_y(new_y);
else else
@ -104,7 +104,14 @@ void Tooltip::adjust(bool disregard_drawn) {
Tooltips::drawn_tooltips_rectangle=rectangle; 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<Gtk::TextBuffer> text_buffer) { void Tooltip::wrap_lines(Glib::RefPtr<Gtk::TextBuffer> text_buffer) {
@ -153,28 +160,24 @@ void Tooltips::show(const Gdk::Rectangle& rectangle, bool disregard_drawn) {
for(auto &tooltip : tooltip_list) { for(auto &tooltip : tooltip_list) {
tooltip.update(); tooltip.update();
if(rectangle.intersects(tooltip.activation_rectangle)) { if(rectangle.intersects(tooltip.activation_rectangle)) {
tooltip.adjust(disregard_drawn); tooltip.show(disregard_drawn);
tooltip.window->show_all();
shown=true; shown=true;
} }
else if(tooltip.window) else
tooltip.window->hide(); tooltip.hide();
} }
} }
void Tooltips::show(bool disregard_drawn) { void Tooltips::show(bool disregard_drawn) {
for(auto &tooltip : tooltip_list) { for(auto &tooltip : tooltip_list) {
tooltip.update(); tooltip.update();
tooltip.adjust(disregard_drawn); tooltip.show(disregard_drawn);
tooltip.window->show_all();
shown=true; shown=true;
} }
} }
void Tooltips::hide() { void Tooltips::hide() {
for(auto &tooltip : tooltip_list) { for(auto &tooltip : tooltip_list)
if(tooltip.window) tooltip.hide();
tooltip.window->hide();
}
shown=false; shown=false;
} }

7
src/tooltips.h

@ -10,19 +10,20 @@ public:
~Tooltip(); ~Tooltip();
void update(); void update();
void adjust(bool disregard_drawn=false); void show(bool disregard_drawn=false);
void hide();
Gdk::Rectangle activation_rectangle; Gdk::Rectangle activation_rectangle;
std::unique_ptr<Gtk::Window> window;
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark; Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark; Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
private: private:
std::unique_ptr<Gtk::Window> window;
void wrap_lines(Glib::RefPtr<Gtk::TextBuffer> text_buffer); void wrap_lines(Glib::RefPtr<Gtk::TextBuffer> text_buffer);
std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer; std::function<Glib::RefPtr<Gtk::TextBuffer>()> create_tooltip_buffer;
std::unique_ptr<Gtk::TextView> tooltip_widget; std::unique_ptr<Gtk::TextView> tooltip_widget;
Gtk::TextView& text_view; Gtk::TextView& text_view;
int tooltip_width, tooltip_height; std::pair<int, int> size;
}; };
class Tooltips { class Tooltips {

Loading…
Cancel
Save