GUI: Add macOS shift-click selection handler

PR #22284
This commit is contained in:
Luke Memet 2025-02-15 12:04:54 -05:00
commit d75c8d1cbd
5 changed files with 80 additions and 0 deletions

View file

@ -289,6 +289,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
macosdockbadge/badgeview.mm macosdockbadge/badgeview.mm
macutilities.h macutilities.h
macutilities.mm macutilities.mm
macosshiftclickhandler.h
macosshiftclickhandler.cpp
) )
target_link_libraries(qbt_gui PRIVATE objc) target_link_libraries(qbt_gui PRIVATE objc)
endif() endif()

View file

@ -0,0 +1,45 @@
#include "macosshiftclickhandler.h"
#include <QMouseEvent>
#include "transferlistwidget.h"
MacOSShiftClickHandler::MacOSShiftClickHandler(TransferListWidget *parent)
: QObject(parent)
, m_treeView(parent)
{
parent->installEventFilter(this);
}
bool MacOSShiftClickHandler::eventFilter(QObject *watched, QEvent *event)
{
if ((watched == m_treeView) && (event->type() == QEvent::MouseButtonPress))
{
auto *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() != Qt::LeftButton)
return false;
const QModelIndex clickedIndex = m_treeView->indexAt(mouseEvent->pos());
if (!clickedIndex.isValid())
return false;
const Qt::KeyboardModifiers modifiers = mouseEvent->modifiers();
const bool shiftPressed = modifiers.testFlag(Qt::ShiftModifier);
const bool commandPressed = modifiers.testFlag(Qt::ControlModifier);
if (shiftPressed && m_lastClickedIndex.isValid())
{
const QItemSelection selection(m_lastClickedIndex, clickedIndex);
if (commandPressed)
m_treeView->selectionModel()->select(selection, QItemSelectionModel::Select | QItemSelectionModel::Rows);
else
m_treeView->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
m_treeView->selectionModel()->setCurrentIndex(clickedIndex, QItemSelectionModel::NoUpdate);
return true;
}
if (!(modifiers & (Qt::AltModifier | Qt::MetaModifier)))
m_lastClickedIndex = clickedIndex;
}
return false;
}

View file

@ -0,0 +1,23 @@
#pragma once
#include <QObject>
#include <QPersistentModelIndex>
class TransferListWidget;
// Workaround for QTBUG-115838: Shift-click range selection not working properly on macOS
class MacOSShiftClickHandler final : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(MacOSShiftClickHandler)
public:
explicit MacOSShiftClickHandler(TransferListWidget *parent);
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
private:
TransferListWidget *m_treeView;
QPersistentModelIndex m_lastClickedIndex;
};

View file

@ -75,6 +75,7 @@
#ifdef Q_OS_MACOS #ifdef Q_OS_MACOS
#include "macutilities.h" #include "macutilities.h"
#include "macosshiftclickhandler.h"
#endif #endif
namespace namespace
@ -158,6 +159,7 @@ TransferListWidget::TransferListWidget(IGUIApplication *app, QWidget *parent)
setDropIndicatorShown(true); setDropIndicatorShown(true);
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
setAttribute(Qt::WA_MacShowFocusRect, false); setAttribute(Qt::WA_MacShowFocusRect, false);
m_shiftClickHandler = new MacOSShiftClickHandler(this);
#endif #endif
header()->setFirstSectionMovable(true); header()->setFirstSectionMovable(true);
header()->setStretchLastSection(false); header()->setStretchLastSection(false);

View file

@ -52,6 +52,10 @@ enum class CopyInfohashPolicy
Version2 Version2
}; };
#ifdef Q_OS_MACOS
class MacOSShiftClickHandler; // Forward declaration
#endif
class TransferListWidget final : public GUIApplicationComponent<QTreeView> class TransferListWidget final : public GUIApplicationComponent<QTreeView>
{ {
Q_OBJECT Q_OBJECT
@ -137,6 +141,10 @@ private:
QList<BitTorrent::Torrent *> getVisibleTorrents() const; QList<BitTorrent::Torrent *> getVisibleTorrents() const;
int visibleColumnsCount() const; int visibleColumnsCount() const;
#ifdef Q_OS_MACOS
MacOSShiftClickHandler *m_shiftClickHandler = nullptr;
#endif
TransferListModel *m_listModel = nullptr; TransferListModel *m_listModel = nullptr;
TransferListSortModel *m_sortFilterModel = nullptr; TransferListSortModel *m_sortFilterModel = nullptr;
}; };