From ae788f5508a11c8f3f7e3d89b3536f7ec9786639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 11 Oct 2024 12:49:25 +0200 Subject: [PATCH] macOS: Implement NSViewContentSelectionInfo protocol for Writing Tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The protocol is documented (in the header) to be used for context menu placement, but is also used for placement of the Writing Tools dialog. We don't have a way to request the selection rectangle via our input method protocol, so for now we have to use some crude heuristics based on the cursor and anchor rectangle. This quickly falls apart for multi line selections, but should not be any worse than the behavior we have today where we effectively report the entire QWindow rect, placing the Writing Tools popup outside the window. With this patch we at least place the popup relative to the focus widget. Pick-to: 6.8 Change-Id: I28053aab93a42133ae2ccc552fcb4172bf55a634 Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/cocoa/qnsview.mm | 5 +++ .../platforms/cocoa/qnsview_complextext.mm | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 7289c66ea65..560cada5fb4 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -85,6 +85,11 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMouseMoveHelper); @interface QNSView (ServicesMenu) @end +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000) +@interface QNSView (ContentSelectionInfo) +@end +#endif + @interface QT_MANGLE_NAMESPACE(QNSViewMenuHelper) : NSObject - (instancetype)initWithView:(QNSView *)theView; @end diff --git a/src/plugins/platforms/cocoa/qnsview_complextext.mm b/src/plugins/platforms/cocoa/qnsview_complextext.mm index 046578a617b..bd8038e647c 100644 --- a/src/plugins/platforms/cocoa/qnsview_complextext.mm +++ b/src/plugins/platforms/cocoa/qnsview_complextext.mm @@ -679,4 +679,35 @@ @end +#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000) +@implementation QNSView (ContentSelectionInfo) +/* + This method is used by AppKit for positioning of context menus in + response to the context menu keyboard hotkey, and for placement of + the Writing Tools popup. +*/ +- (NSRect)selectionAnchorRect +{ + if (queryInputMethod(self.focusObject)) { + // We don't have a way of querying the selection rectangle via + // the input method protocol (yet), so we use crude heuristics. + const auto *inputMethod = qApp->inputMethod(); + auto cursorRect = inputMethod->cursorRectangle(); + auto anchorRect = inputMethod->anchorRectangle(); + auto selectionRect = cursorRect.united(anchorRect); + if (cursorRect.top() != anchorRect.top()) { + // Multi line selection. Assume the selections extends to + // the entire width of the input item. This does not account + // for center-aligned text and a bunch of other cases. FIXME + auto itemClipRect = inputMethod->inputItemClipRectangle(); + selectionRect.setLeft(itemClipRect.left()); + selectionRect.setRight(itemClipRect.right()); + } + return selectionRect.toCGRect(); + } else { + return NSZeroRect; + } +} +@end +#endif // macOS 15 SDK