commit 48935368fdcbb3e0b997ac047929e8ad3c4f7fcc
parent a7acc4fbef9521d9cbef6940cd0051790212a542
Author: cfillion <cfillion@users.noreply.github.com>
Date: Thu, 28 Nov 2019 14:25:18 -0500
listview: fix column customization context menu on Linux
Diffstat:
2 files changed, 51 insertions(+), 31 deletions(-)
diff --git a/src/listview.cpp b/src/listview.cpp
@@ -377,20 +377,51 @@ int ListView::selectionSize() const
return ListView_GetSelectedCount(handle());
}
-int ListView::itemUnderMouse(bool *overIcon) const
+bool ListView::headerHitTest(const int x, const int y) const
+{
+#ifdef _WIN32
+ RECT rect;
+ GetWindowRect(ListView_GetHeader(handle()), &rect);
+
+ const int headerHeight = rect.bottom - rect.top;
+#elif __APPLE__
+ // On macOS the ListView's zero client y coordinate is the first item's
+ // position including its scroll offset.
+ // ListView_GetScroll is not available in REAPER-provided SWELL
+ POINT scroll;
+ ListView_GetScroll(handle(), &scroll);
+
+ const int headerHeight = scroll.y;
+#else
+ const int headerHeight = SWELL_GetListViewHeaderHeight(handle());
+#endif
+
+ POINT point{x, y};
+ ScreenToClient(handle(), &point);
+
+ return point.y <= headerHeight;
+}
+
+int ListView::itemUnder(const int x, const int y, bool *overIcon) const
{
- LVHITTESTINFO info{};
- GetCursorPos(&info.pt);
- ScreenToClient(handle(), &info.pt);
- ListView_SubItemHitTest(handle(), &info);
+ LVHITTESTINFO test{{x, y}};
+ ScreenToClient(handle(), &test.pt);
+ ListView_SubItemHitTest(handle(), &test);
if(overIcon) {
- *overIcon = info.iSubItem == 0 &&
- (info.flags & (LVHT_ONITEMICON | LVHT_ONITEMSTATEICON)) != 0 &&
- (info.flags & LVHT_ONITEMLABEL) == 0;
+ *overIcon = test.iSubItem == 0 &&
+ (test.flags & (LVHT_ONITEMICON | LVHT_ONITEMSTATEICON)) != 0 &&
+ (test.flags & LVHT_ONITEMLABEL) == 0;
}
- return translateBack(info.iItem);
+ return translateBack(test.iItem);
+}
+
+int ListView::itemUnderMouse(bool *overIcon) const
+{
+ POINT point;
+ GetCursorPos(&point);
+ return itemUnder(point.x, point.y, overIcon);
}
int ListView::scroll() const
@@ -440,36 +471,19 @@ bool ListView::onContextMenu(HWND dialog, int x, int y)
{
SetFocus(handle());
- POINT point{x, y};
- ScreenToClient(handle(), &point);
+ const bool keyboardTrigger = x < 0;
-#ifdef _WIN32
- HWND header = ListView_GetHeader(handle());
- RECT rect;
- GetWindowRect(header, &rect);
- const int headerHeight = rect.bottom - rect.top;
-#else
- // point.y is negative on macOS when hovering the header
- constexpr int headerHeight = 0;
-
- #ifdef __APPLE__
- POINT scroll;
- ListView_GetScroll(handle(), &scroll);
- point.y -= scroll.y;
- #endif
-#endif
-
- if(point.y < headerHeight && x != -1) {
+ if(!keyboardTrigger && headerHitTest(x, y)) {
if(m_customizable) // show menu only if header is customizable
headerMenu(x, y);
return true;
}
- int index = itemUnderMouse();
-
#ifdef ListView_GetItemPosition // unsuported by SWELL
+ int index;
+
// adjust the context menu's position when using Shift+F10 on Windows
- if(x == -1) {
+ if(keyboardTrigger) {
index = currentIndex();
// find the location of the current item or of the first item
@@ -483,6 +497,10 @@ bool ListView::onContextMenu(HWND dialog, int x, int y)
x = std::max(controlRect.left, std::min(itemPos.x, controlRect.right));
y = std::max(controlRect.top, std::min(itemPos.y, controlRect.bottom));
}
+ else
+ index = itemUnder(x, y);
+#else
+ const int index = itemUnder(x, y);
#endif
Menu menu;
diff --git a/src/listview.hpp b/src/listview.hpp
@@ -120,6 +120,8 @@ public:
void enableIcons();
int currentIndex() const;
+ bool headerHitTest(int x, int y) const;
+ int itemUnder(int x, int y, bool *overIcon = nullptr) const;
int itemUnderMouse(bool *overIcon = nullptr) const;
int scroll() const;