macOS: Implement NSViewContentSelectionInfo protocol for Writing Tools

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 <jan-arve.saether@qt.io>
This commit is contained in:
Tor Arne Vestbø 2024-10-11 12:49:25 +02:00
parent 5effd7ad53
commit ae788f5508
2 changed files with 36 additions and 0 deletions

View File

@ -85,6 +85,11 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMouseMoveHelper);
@interface QNSView (ServicesMenu) <NSServicesMenuRequestor> @interface QNSView (ServicesMenu) <NSServicesMenuRequestor>
@end @end
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(150000)
@interface QNSView (ContentSelectionInfo) <NSViewContentSelectionInfo>
@end
#endif
@interface QT_MANGLE_NAMESPACE(QNSViewMenuHelper) : NSObject @interface QT_MANGLE_NAMESPACE(QNSViewMenuHelper) : NSObject
- (instancetype)initWithView:(QNSView *)theView; - (instancetype)initWithView:(QNSView *)theView;
@end @end

View File

@ -679,4 +679,35 @@
@end @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