Fix incorrect selection behavior when building against GTK 4 (#4168)

View-relative coordinates were treated as bin window-relative, leading to
incorrect selected item calculation.

Broken since the introduction of GTK 4 support in #3916.
This commit is contained in:
Mike Gelfand 2022-11-14 19:27:15 +01:00 committed by GitHub
parent f8d981349e
commit 1d9159fffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 12 deletions

View File

@ -118,7 +118,7 @@ private:
****
***/
void MainWindow::Impl::on_popup_menu([[maybe_unused]] double view_x, [[maybe_unused]] double view_y)
void MainWindow::Impl::on_popup_menu([[maybe_unused]] double event_x, [[maybe_unused]] double event_y)
{
if (popup_menu_ == nullptr)
{
@ -136,6 +136,9 @@ void MainWindow::Impl::on_popup_menu([[maybe_unused]] double view_x, [[maybe_unu
}
#if GTKMM_CHECK_VERSION(4, 0, 0)
int view_x = 0;
int view_y = 0;
view_->convert_bin_window_to_widget_coords(static_cast<int>(event_x), static_cast<int>(event_y), view_x, view_y);
double window_x = 0;
double window_y = 0;
view_->translate_coordinates(window_, view_x, view_y, window_x, window_y);

View File

@ -278,8 +278,8 @@ void gtr_add_torrent_error_dialog(Gtk::Widget& child, tr_torrent* duplicate_torr
if the row they right-click on isn't selected, select it. */
bool on_tree_view_button_pressed(
Gtk::TreeView& view,
double view_x,
double view_y,
double event_x,
double event_y,
bool context_menu_requested,
std::function<void(double, double)> const& callback)
{
@ -288,7 +288,7 @@ bool on_tree_view_button_pressed(
Gtk::TreeModel::Path path;
if (auto const selection = view.get_selection();
view.get_path_at_pos((int)view_x, (int)view_y, path) && !selection->is_selected(path))
view.get_path_at_pos(static_cast<int>(event_x), static_cast<int>(event_y), path) && !selection->is_selected(path))
{
selection->unselect_all();
selection->select(path);
@ -296,7 +296,7 @@ bool on_tree_view_button_pressed(
if (callback)
{
callback(view_x, view_y);
callback(event_x, event_y);
}
return true;
@ -307,9 +307,9 @@ bool on_tree_view_button_pressed(
/* if the user clicked in an empty area of the list,
* clear all the selections. */
bool on_tree_view_button_released(Gtk::TreeView& view, double view_x, double view_y)
bool on_tree_view_button_released(Gtk::TreeView& view, double event_x, double event_y)
{
if (Gtk::TreeModel::Path path; !view.get_path_at_pos((int)view_x, (int)view_y, path))
if (Gtk::TreeModel::Path path; !view.get_path_at_pos(static_cast<int>(event_x), static_cast<int>(event_y), path))
{
view.get_selection()->unselect_all();
}
@ -329,10 +329,15 @@ void setup_tree_view_button_event_handling(
if (press_callback)
{
controller->signal_pressed().connect(
[&view, press_callback, controller](int /*n_press*/, double event_x, double event_y)
[&view, press_callback, controller](int /*n_press*/, double view_x, double view_y)
{
int event_x = 0;
int event_y = 0;
view.convert_widget_to_bin_window_coords(static_cast<int>(view_x), static_cast<int>(view_y), event_x, event_y);
auto* const sequence = controller->get_current_sequence();
auto const event = controller->get_last_event(sequence);
if (event->get_event_type() == TR_GDK_EVENT_TYPE(BUTTON_PRESS) &&
press_callback(
event->get_button(),
@ -349,10 +354,15 @@ void setup_tree_view_button_event_handling(
if (release_callback)
{
controller->signal_released().connect(
[&view, release_callback, controller](int /*n_press*/, double event_x, double event_y)
[&view, release_callback, controller](int /*n_press*/, double view_x, double view_y)
{
int event_x = 0;
int event_y = 0;
view.convert_widget_to_bin_window_coords(static_cast<int>(view_x), static_cast<int>(view_y), event_x, event_y);
auto* const sequence = controller->get_current_sequence();
auto const event = controller->get_last_event(sequence);
if (event->get_event_type() == TR_GDK_EVENT_TYPE(BUTTON_RELEASE) && release_callback(event_x, event_y))
{
controller->set_sequence_state(sequence, Gtk::EventSequenceState::CLAIMED);

View File

@ -211,13 +211,13 @@ void gtr_add_torrent_error_dialog(Gtk::Widget& window_or_child, tr_torrent* dupl
if the row they right-click on isn't selected, select it. */
bool on_tree_view_button_pressed(
Gtk::TreeView& view,
double view_x,
double view_y,
double event_x,
double event_y,
bool context_menu_requested,
std::function<void(double, double)> const& callback = {});
/* if the click didn't specify a row, clear the selection */
bool on_tree_view_button_released(Gtk::TreeView& view, double view_x, double view_y);
bool on_tree_view_button_released(Gtk::TreeView& view, double event_x, double event_y);
using TrGdkModifierType = IF_GTKMM4(Gdk::ModifierType, guint);