summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTasuku Suzuki <tasuku.suzuki@nokia.com>2012-02-29 13:32:20 +0900
committerQt by Nokia <qt-info@nokia.com>2012-03-12 21:38:51 +0100
commit412dbdf410c765e75c60d1f48143dd6c02a69493 (patch)
tree565cfebe0ad28bc378479093ae84e54e464a3764
parent01e8e9136dfa5d3260de0d318da6aece7214f85a (diff)
Input method on Mac
Restore input method implimentation in Qt4 Task-number: QTBUG-23867 Change-Id: I5d405ccc8b0a73c399d992f6474a0cc38d191157 Reviewed-by: Morten Johan Sørvig <morten.sorvig@nokia.com>
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro2
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm19
-rw-r--r--src/plugins/platforms/cocoa/qcocoainputcontext.h70
-rw-r--r--src/plugins/platforms/cocoa/qcocoainputcontext.mm122
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h1
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h4
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm233
10 files changed, 457 insertions, 5 deletions
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index b953210720..bd70a415d0 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -31,6 +31,7 @@ OBJECTIVE_SOURCES += main.mm \
qmacclipboard.mm \
qmacmime.mm \
qcocoasystemsettings.mm \
+ qcocoainputcontext.mm \
HEADERS += qcocoaintegration.h \
qcocoatheme.h \
@@ -59,6 +60,7 @@ HEADERS += qcocoaintegration.h \
qmacclipboard.h \
qmacmime.h \
qcocoasystemsettings.h \
+ qcocoainputcontext.h \
FORMS += $$PWD/../../../widgets/dialogs/qfiledialog.ui
RESOURCES += qcocoaresources.qrc
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 3e3e8fa507..e5fe664731 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -74,6 +74,8 @@ NSImage *qt_mac_create_nsimage(const QPixmap &pm);
NSSize qt_mac_toNSSize(const QSize &qtSize);
+QColor qt_mac_toQColor(const NSColor *color);
+
QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index ec4399b66c..e41ddf4a9f 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -137,6 +137,25 @@ NSSize qt_mac_toNSSize(const QSize &qtSize)
return NSMakeSize(qtSize.width(), qtSize.height());
}
+QColor qt_mac_toQColor(const NSColor *color)
+{
+ QColor qtColor;
+ NSString *colorSpace = [color colorSpaceName];
+ if (colorSpace == NSDeviceCMYKColorSpace) {
+ CGFloat cyan, magenta, yellow, black, alpha;
+ [color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
+ qtColor.setCmykF(cyan, magenta, yellow, black, alpha);
+ } else {
+ NSColor *tmpColor;
+ tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
+ CGFloat red, green, blue, alpha;
+ [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
+ qtColor.setRgbF(red, green, blue, alpha);
+ }
+ return qtColor;
+}
+
+
// Use this method to keep all the information in the TextSegment. As long as it is ordered
// we are in OK shape, and we can influence that ourselves.
struct KeyPair
diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.h b/src/plugins/platforms/cocoa/qcocoainputcontext.h
new file mode 100644
index 0000000000..172c87e2dc
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoainputcontext.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOAINPUTCONTEXT_H
+#define QCOCOAINPUTCONTEXT_H
+
+#include <QtGui/QPlatformInputContext>
+#include <QtCore/QPointer>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaInputContext : public QPlatformInputContext
+{
+ Q_OBJECT
+public:
+ explicit QCocoaInputContext();
+ ~QCocoaInputContext();
+
+ virtual bool isValid() const { return true; }
+
+ virtual void reset();
+
+private Q_SLOTS:
+ void inputItemChanged();
+
+private:
+ QPointer<QWindow> mWindow;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOCOAINPUTCONTEXT_H
diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
new file mode 100644
index 0000000000..db3488a0f5
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnsview.h"
+#include "qcocoainputcontext.h"
+#include "qcocoanativeinterface.h"
+#include "qcocoaautoreleasepool.h"
+
+#include <QtCore/QRect>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCocoaInputContext
+ \brief Cocoa Input context implementation
+
+ Handles input of foreign characters (particularly East Asian)
+ languages.
+
+ \section1 Testing
+
+ \list
+ \o Select input sources like 'Kotoeri' in Language & Text Preferences
+ \o Compile the \a mainwindows/mdi example and open a text window.
+ \o In the language bar, switch to 'Hiragana'.
+ \o In a text editor control, type the syllable \a 'la'.
+ Underlined characters show up, indicating that there is completion
+ available. Press the Space key two times. A completion popup occurs
+ which shows the options.
+ \endlist
+
+ \section1 Interaction
+
+ Input method support in Cocoa uses NSTextInput protorol. Therefore
+ almost all functionality is implemented in QNSView.
+
+ \ingroup qt-lighthouse-cocoa
+*/
+
+
+
+QCocoaInputContext::QCocoaInputContext()
+ : QPlatformInputContext()
+ , mWindow(QGuiApplication::focusWindow())
+{
+ connect(qApp->inputMethod(), SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged()));
+}
+
+QCocoaInputContext::~QCocoaInputContext()
+{
+}
+
+/*!
+ \brief Cancels a composition.
+*/
+
+void QCocoaInputContext::reset()
+{
+ QPlatformInputContext::reset();
+
+ if (!mWindow) return;
+
+ QCocoaNativeInterface *nativeInterface = qobject_cast<QCocoaNativeInterface *>(QGuiApplication::platformNativeInterface());
+ if (!nativeInterface) return;
+
+ QNSView *view = static_cast<QNSView *>(nativeInterface->nativeResourceForWindow("nsview", mWindow));
+ if (!view) return;
+
+ QCocoaAutoReleasePool pool;
+ NSInputManager *currentIManager = [NSInputManager currentInputManager];
+ if (currentIManager) {
+ [currentIManager markedTextAbandoned:view];
+ [view unmarkText];
+ }
+}
+
+void QCocoaInputContext::inputItemChanged()
+{
+ mWindow = QGuiApplication::focusWindow();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index bf54915365..2389fc2a55 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -89,6 +89,7 @@ public:
QPlatformFontDatabase *fontDatabase() const;
QPlatformNativeInterface *nativeInterface() const;
+ QPlatformInputContext *inputContext() const;
QPlatformAccessibility *accessibility() const;
QPlatformDrag *drag() const;
@@ -98,6 +99,7 @@ private:
QScopedPointer<QPlatformFontDatabase> mFontDb;
QAbstractEventDispatcher *mEventDispatcher;
+ QScopedPointer<QPlatformInputContext> mInputContext;
QScopedPointer<QPlatformAccessibility> mAccessibility;
QScopedPointer<QPlatformTheme> mPlatformTheme;
QList<QCocoaScreen *> mScreens;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 8411a795c1..d490495be4 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -52,6 +52,7 @@
#include "qmenu_mac.h"
#include "qcocoafiledialoghelper.h"
#include "qcocoatheme.h"
+#include "qcocoainputcontext.h"
#include "qmacmime.h"
#include <QtGui/qplatformaccessibility_qpa.h>
@@ -90,6 +91,7 @@ QCocoaScreen::~QCocoaScreen()
QCocoaIntegration::QCocoaIntegration()
: mFontDb(new QCoreTextFontDatabase())
, mEventDispatcher(new QCocoaEventDispatcher())
+ , mInputContext(new QCocoaInputContext)
, mAccessibility(new QPlatformAccessibility)
, mPlatformTheme(new QCocoaTheme)
, mCocoaDrag(new QCocoaDrag)
@@ -195,6 +197,11 @@ QPlatformNativeInterface *QCocoaIntegration::nativeInterface() const
return new QCocoaNativeInterface();
}
+QPlatformInputContext *QCocoaIntegration::inputContext() const
+{
+ return mInputContext.data();
+}
+
QPlatformAccessibility *QCocoaIntegration::accessibility() const
{
return mAccessibility.data();
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 7c6fb38577..d277cb2964 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -48,6 +48,7 @@ class QWidget;
class QCocoaNativeInterface : public QPlatformNativeInterface
{
+ Q_OBJECT
public:
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
};
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 1a1a1cd3b9..b21e9e342f 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -51,12 +51,14 @@ QT_BEGIN_NAMESPACE
class QCocoaWindow;
QT_END_NAMESPACE
-@interface QNSView : NSView {
+@interface QNSView : NSView <NSTextInput> {
CGImageRef m_cgImage;
QWindow *m_window;
QCocoaWindow *m_platformWindow;
Qt::MouseButtons m_buttons;
QAccessibleInterface *m_accessibleRoot;
+ QString m_composingText;
+ bool m_keyEventsAccepted;
QStringList *currentCustomDragTypes;
}
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 9ed3332ba5..6206d53423 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -51,6 +51,7 @@
#include "qcocoadrag.h"
#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QTextFormat>
#include <QtCore/QDebug>
#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
@@ -94,6 +95,7 @@ static QTouchDevice *touchDevice = 0;
m_window = window;
m_platformWindow = platformWindow;
m_accessibleRoot = 0;
+ m_keyEventsAccepted = false;
#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
// prevent rift in space-time continuum, disable
@@ -272,8 +274,15 @@ static QTouchDevice *touchDevice = 0;
- (void)mouseDown:(NSEvent *)theEvent
{
- m_buttons |= Qt::LeftButton;
- [self handleMouseEvent:theEvent];
+ if ([self hasMarkedText]) {
+ NSInputManager* inputManager = [NSInputManager currentInputManager];
+ if ([inputManager wantsToHandleMouseEvents]) {
+ [inputManager handleMouseEvent:theEvent];
+ }
+ } else {
+ m_buttons |= Qt::LeftButton;
+ [self handleMouseEvent:theEvent];
+ }
}
- (void)mouseDragged:(NSEvent *)theEvent
@@ -467,12 +476,228 @@ static QTouchDevice *touchDevice = 0;
- (void)keyDown:(NSEvent *)theEvent
{
- [self handleKeyEvent : theEvent eventType :int(QEvent::KeyPress)];
+ QObject *fo = QGuiApplication::focusObject();
+ m_keyEventsAccepted = false;
+ if (fo) {
+ QInputMethodQueryEvent queryEvent(Qt::ImHints);
+ if (QCoreApplication::sendEvent(fo, &queryEvent)) {
+ Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
+ if (!(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) {
+ [self interpretKeyEvents:[NSArray arrayWithObject: theEvent]];
+ }
+ }
+ }
+
+ if (!m_keyEventsAccepted && m_composingText.isEmpty()) {
+ [self handleKeyEvent : theEvent eventType :int(QEvent::KeyPress)];
+ }
}
- (void)keyUp:(NSEvent *)theEvent
{
- [self handleKeyEvent : theEvent eventType :int(QEvent::KeyRelease)];
+ if (!m_keyEventsAccepted && m_composingText.isEmpty()) {
+ [self handleKeyEvent : theEvent eventType :int(QEvent::KeyRelease)];
+ }
+}
+
+- (void) doCommandBySelector:(SEL)aSelector
+{
+ [self tryToPerform:aSelector with:self];
+}
+
+- (void) insertText:(id)aString
+{
+ QString commitString;
+ if ([aString length]) {
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ commitString = QCFString::toQString(reinterpret_cast<CFStringRef>([aString string]));
+ } else {
+ commitString = QCFString::toQString(reinterpret_cast<CFStringRef>(aString));
+ };
+ }
+ QObject *fo = QGuiApplication::focusObject();
+ if (fo) {
+ QInputMethodEvent e;
+ e.setCommitString(commitString);
+ QCoreApplication::sendEvent(fo, &e);
+ m_keyEventsAccepted = true;
+ }
+
+ m_composingText.clear();
+ }
+
+- (void) setMarkedText:(id)aString selectedRange:(NSRange)selRange
+{
+ QString preeditString;
+
+ QList<QInputMethodEvent::Attribute> attrs;
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selRange.location + selRange.length, 1, QVariant());
+
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ // Preedit string has attribution
+ preeditString = QCFString::toQString(reinterpret_cast<CFStringRef>([aString string]));
+ int composingLength = preeditString.length();
+ int index = 0;
+ // Create attributes for individual sections of preedit text
+ while (index < composingLength) {
+ NSRange effectiveRange;
+ NSRange range = NSMakeRange(index, composingLength-index);
+ NSDictionary *attributes = [aString attributesAtIndex:index
+ longestEffectiveRange:&effectiveRange
+ inRange:range];
+ NSNumber *underlineStyle = [attributes objectForKey:NSUnderlineStyleAttributeName];
+ if (underlineStyle) {
+ QColor clr (Qt::black);
+ NSColor *color = [attributes objectForKey:NSUnderlineColorAttributeName];
+ if (color) {
+ clr = qt_mac_toQColor(color);
+ }
+ QTextCharFormat format;
+ format.setFontUnderline(true);
+ format.setUnderlineColor(clr);
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ effectiveRange.location,
+ effectiveRange.length,
+ format);
+ }
+ index = effectiveRange.location + effectiveRange.length;
+ }
+ } else {
+ // No attributes specified, take only the preedit text.
+ preeditString = QCFString::toQString(reinterpret_cast<CFStringRef>(aString));
+ }
+
+ if (attrs.isEmpty()) {
+ QTextCharFormat format;
+ format.setFontUnderline(true);
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ 0, preeditString.length(), format);
+ }
+
+ m_composingText = preeditString;
+
+ QObject *fo = QGuiApplication::focusObject();
+ if (fo) {
+ QInputMethodEvent e(preeditString, attrs);
+ QCoreApplication::sendEvent(fo, &e);
+ m_keyEventsAccepted = true;
+ }
+}
+
+- (void) unmarkText
+{
+ if (!m_composingText.isEmpty()) {
+ QObject *fo = QGuiApplication::focusObject();
+ if (fo) {
+ QInputMethodEvent e;
+ e.setCommitString(m_composingText);
+ QCoreApplication::sendEvent(fo, &e);
+ }
+ }
+ m_composingText.clear();
+}
+
+- (BOOL) hasMarkedText
+{
+ return (m_composingText.isEmpty() ? NO: YES);
+}
+
+- (NSInteger) conversationIdentifier
+{
+ return (NSInteger)self;
+}
+
+- (NSAttributedString *) attributedSubstringFromRange:(NSRange)theRange
+{
+ QObject *fo = QGuiApplication::focusObject();
+ if (!fo)
+ return nil;
+ QInputMethodQueryEvent queryEvent(Qt::ImCurrentSelection);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return nil;
+
+ QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString();
+ if (selectedText.isEmpty())
+ return nil;
+
+ QCFString string(selectedText.mid(theRange.location, theRange.length));
+ const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
+ return [[[NSAttributedString alloc] initWithString:const_cast<NSString *>(tmpString)] autorelease];
+}
+
+- (NSRange) markedRange
+{
+ NSRange range;
+ if (!m_composingText.isEmpty()) {
+ range.location = 0;
+ range.length = m_composingText.length();
+ } else {
+ range.location = NSNotFound;
+ range.length = 0;
+ }
+ return range;
+}
+
+
+- (NSRange) selectedRange
+{
+ NSRange selRange = {NSNotFound, 0};
+ selRange.location = NSNotFound;
+ selRange.length = 0;
+
+ QObject *fo = QGuiApplication::focusObject();
+ if (!fo)
+ return selRange;
+ QInputMethodQueryEvent queryEvent(Qt::ImCurrentSelection);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return selRange;
+ QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString();
+
+ if (!selectedText.isEmpty()) {
+ selRange.location = 0;
+ selRange.length = selectedText.length();
+ }
+ return selRange;
+}
+
+- (NSRect) firstRectForCharacterRange:(NSRange)theRange
+{
+ Q_UNUSED(theRange);
+ QObject *fo = QGuiApplication::focusObject();
+ if (!fo)
+ return NSZeroRect;
+
+ if (!m_window)
+ return NSZeroRect;
+
+ // The returned rect is always based on the internal cursor.
+ QRect mr = qApp->inputMethod()->cursorRectangle().toRect();
+ QPoint mp = m_window->mapToGlobal(mr.bottomLeft());
+
+ NSRect rect;
+ rect.origin.x = mp.x();
+ rect.origin.y = qt_mac_flipYCoordinate(mp.y());
+ rect.size.width = mr.width();
+ rect.size.height = mr.height();
+ return rect;
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
+{
+ // We dont support cursor movements using mouse while composing.
+ Q_UNUSED(thePoint);
+ return NSNotFound;
+}
+
+- (NSArray*) validAttributesForMarkedText
+{
+ QObject *fo = QGuiApplication::focusObject();
+ if (!fo)
+ return nil;
+
+ // Support only underline color/style.
+ return [NSArray arrayWithObjects:NSUnderlineColorAttributeName,
+ NSUnderlineStyleAttributeName, nil];
}
-(void)registerDragTypes