зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1844905 - Part 3. Basic keyboard support. r=masayuki
Implement UIKeyInput protocol to simple basic input. When implementing UITextInput, we need to consider to share cocoa's code. Differential Revision: https://phabricator.services.mozilla.com/D184286
This commit is contained in:
Родитель
23ae49e04d
Коммит
e79a84dad4
|
@ -0,0 +1,65 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef TextInputHandler_h_
|
||||
#define TextInputHandler_h_
|
||||
|
||||
#import <UIKit/UITextInput.h>
|
||||
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/TextEventDispatcherListener.h"
|
||||
#include "mozilla/widget/IMEData.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsWindow;
|
||||
|
||||
namespace mozilla::widget {
|
||||
class TextEventDispatcher;
|
||||
|
||||
// This is the temporary input class. When implementing UITextInpt protocol, we
|
||||
// should share this class with Cocoa's version.
|
||||
class TextInputHandler final : public TextEventDispatcherListener {
|
||||
public:
|
||||
TextInputHandler(nsWindow* aWidget);
|
||||
TextInputHandler() = delete;
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD NotifyIME(TextEventDispatcher* aTextEventDispatcher,
|
||||
const IMENotification& aNotification) override;
|
||||
NS_IMETHOD_(IMENotificationRequests) GetIMENotificationRequests() override;
|
||||
NS_IMETHOD_(void) OnRemovedFrom(TextEventDispatcher* aTextEventDispatcher) override;
|
||||
NS_IMETHOD_(void)
|
||||
WillDispatchKeyboardEvent(TextEventDispatcher* aTextEventDispatcher,
|
||||
WidgetKeyboardEvent& aKeyboardEvent, uint32_t aIndexOfKeypress,
|
||||
void* aData) override;
|
||||
|
||||
// UIKeyInput delegation
|
||||
bool InsertText(NSString* aText);
|
||||
bool HandleCommand(Command aCommand);
|
||||
|
||||
void OnDestroyed();
|
||||
|
||||
private:
|
||||
virtual ~TextInputHandler() = default;
|
||||
|
||||
bool DispatchKeyDownEvent(uint32_t aKeyCode, KeyNameIndex aKeyNameIndex, char16_t aCharCode,
|
||||
nsEventStatus& aStatus);
|
||||
bool DispatchKeyUpEvent(uint32_t aKeyCode, KeyNameIndex aKeyNameIndex, char16_t aCharCode,
|
||||
nsEventStatus& aStatus);
|
||||
bool DispatchKeyPressEvent(uint32_t aKeyCode, KeyNameIndex aKeyNameIndex, char16_t aCharCode,
|
||||
nsEventStatus& aStatus);
|
||||
|
||||
bool EmulateKeyboardEvent(uint32_t aKeyCode, KeyNameIndex aKeyNameIndex, char16_t charCode);
|
||||
|
||||
bool Destroyed() { return !mWidget; }
|
||||
|
||||
nsWindow* mWidget; // weak ref
|
||||
RefPtr<TextEventDispatcher> mDispatcher;
|
||||
};
|
||||
|
||||
} // namespace mozilla::widget
|
||||
#endif
|
|
@ -0,0 +1,254 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "TextInputHandler.h"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/MiscEvents.h"
|
||||
#include "mozilla/TextEventDispatcher.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/WidgetUtils.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWindow.h"
|
||||
|
||||
mozilla::LazyLogModule gIMELog("TextInputHandler");
|
||||
|
||||
namespace mozilla::widget {
|
||||
|
||||
static void GetStringForNSString(const NSString* aSrc, nsAString& aDist) {
|
||||
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||
|
||||
if (!aSrc) {
|
||||
aDist.Truncate();
|
||||
return;
|
||||
}
|
||||
|
||||
aDist.SetLength([aSrc length]);
|
||||
[aSrc getCharacters:reinterpret_cast<unichar*>(aDist.BeginWriting())
|
||||
range:NSMakeRange(0, [aSrc length])];
|
||||
|
||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(TextInputHandler, TextEventDispatcherListener,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
TextInputHandler::TextInputHandler(nsWindow* aWidget)
|
||||
: mWidget(aWidget), mDispatcher(aWidget->GetTextEventDispatcher()) {}
|
||||
|
||||
nsresult TextInputHandler::NotifyIME(TextEventDispatcher* aTextEventDispatcher,
|
||||
const IMENotification& aNotification) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
IMENotificationRequests TextInputHandler::GetIMENotificationRequests() {
|
||||
return IMENotificationRequests();
|
||||
}
|
||||
|
||||
void TextInputHandler::OnRemovedFrom(
|
||||
TextEventDispatcher* aTextEventDispatcher) {}
|
||||
|
||||
void TextInputHandler::WillDispatchKeyboardEvent(
|
||||
TextEventDispatcher* aTextEventDispatcher,
|
||||
WidgetKeyboardEvent& aKeyboardEvent, uint32_t aIndexOfKeypress,
|
||||
void* aData) {}
|
||||
|
||||
bool TextInputHandler::InsertText(NSString* aText) {
|
||||
nsString str;
|
||||
GetStringForNSString(aText, str);
|
||||
|
||||
MOZ_LOG(gIMELog, LogLevel::Info,
|
||||
("%p TextInputHandler::InsertText(aText=%s)", this,
|
||||
NS_ConvertUTF16toUTF8(str).get()));
|
||||
|
||||
if (Destroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (str.Length() == 1) {
|
||||
char16_t charCode = str[0];
|
||||
if (charCode == 0x0a) {
|
||||
return EmulateKeyboardEvent(NS_VK_RETURN, KEY_NAME_INDEX_Enter, charCode);
|
||||
}
|
||||
if (charCode == 0x08) {
|
||||
return EmulateKeyboardEvent(NS_VK_BACK, KEY_NAME_INDEX_Backspace,
|
||||
charCode);
|
||||
}
|
||||
if (uint32_t keyCode = WidgetUtils::ComputeKeyCodeFromChar(charCode)) {
|
||||
return EmulateKeyboardEvent(keyCode, KEY_NAME_INDEX_USE_STRING, charCode);
|
||||
}
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
RefPtr<nsWindow> widget(mWidget);
|
||||
if (!DispatchKeyDownEvent(NS_VK_PROCESSKEY, KEY_NAME_INDEX_Process, 0,
|
||||
status)) {
|
||||
return false;
|
||||
}
|
||||
if (Destroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mDispatcher->CommitComposition(status, &str, nullptr);
|
||||
if (widget->Destroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DispatchKeyUpEvent(NS_VK_PROCESSKEY, KEY_NAME_INDEX_Process, 0, status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TextInputHandler::HandleCommand(Command aCommand) {
|
||||
MOZ_LOG(gIMELog, LogLevel::Info,
|
||||
("%p TextInputHandler::HandleCommand, aCommand=%s", this,
|
||||
ToChar(aCommand)));
|
||||
|
||||
if (Destroyed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aCommand != Command::DeleteCharBackward) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
if (!DispatchKeyDownEvent(NS_VK_BACK, KEY_NAME_INDEX_Backspace, 0, status)) {
|
||||
return true;
|
||||
}
|
||||
if (Destroyed() || status == nsEventStatus_eConsumeNoDefault) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Focus check
|
||||
|
||||
if (!DispatchKeyPressEvent(NS_VK_BACK, KEY_NAME_INDEX_Backspace, 0, status)) {
|
||||
return true;
|
||||
}
|
||||
if (Destroyed() || status == nsEventStatus_eConsumeNoDefault) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Focus check
|
||||
|
||||
DispatchKeyUpEvent(NS_VK_BACK, KEY_NAME_INDEX_Backspace, 0, status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t ComputeKeyModifiers(uint32_t aCharCode) {
|
||||
if (aCharCode >= 'A' && aCharCode <= 'Z') {
|
||||
return MODIFIER_SHIFT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void InitKeyEvent(WidgetKeyboardEvent& aEvent, uint32_t aKeyCode,
|
||||
KeyNameIndex aKeyNameIndex, char16_t aCharCode) {
|
||||
aEvent.mKeyCode = aKeyCode;
|
||||
aEvent.mIsRepeat = false;
|
||||
aEvent.mKeyNameIndex = aKeyNameIndex;
|
||||
// TODO(m_kato):
|
||||
// How to get native key? Then, implement NativeKeyToDOM*.h for iOS
|
||||
aEvent.mCodeNameIndex = CODE_NAME_INDEX_UNKNOWN;
|
||||
if (aEvent.mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) {
|
||||
aEvent.mKeyValue = aCharCode;
|
||||
}
|
||||
aEvent.mModifiers = ComputeKeyModifiers(aCharCode);
|
||||
aEvent.mLocation = eKeyLocationStandard;
|
||||
aEvent.mTimeStamp = TimeStamp::Now();
|
||||
}
|
||||
|
||||
bool TextInputHandler::DispatchKeyDownEvent(uint32_t aKeyCode,
|
||||
KeyNameIndex aKeyNameIndex,
|
||||
char16_t aCharCode,
|
||||
nsEventStatus& aStatus) {
|
||||
MOZ_ASSERT(aKeyCode);
|
||||
MOZ_ASSERT(mWidget);
|
||||
|
||||
WidgetKeyboardEvent keydownEvent(true, eKeyDown, mWidget);
|
||||
InitKeyEvent(keydownEvent, aKeyCode, aKeyNameIndex, aCharCode);
|
||||
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("BeginNativeInputTransaction is failed");
|
||||
return false;
|
||||
}
|
||||
return mDispatcher->DispatchKeyboardEvent(eKeyDown, keydownEvent, aStatus);
|
||||
}
|
||||
|
||||
bool TextInputHandler::DispatchKeyUpEvent(uint32_t aKeyCode,
|
||||
KeyNameIndex aKeyNameIndex,
|
||||
char16_t aCharCode,
|
||||
nsEventStatus& aStatus) {
|
||||
MOZ_ASSERT(aKeyCode);
|
||||
MOZ_ASSERT(mWidget);
|
||||
|
||||
WidgetKeyboardEvent keyupEvent(true, eKeyUp, mWidget);
|
||||
InitKeyEvent(keyupEvent, aKeyCode, aKeyNameIndex, aCharCode);
|
||||
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("BeginNativeInputTransaction is failed");
|
||||
return false;
|
||||
}
|
||||
return mDispatcher->DispatchKeyboardEvent(eKeyUp, keyupEvent, aStatus);
|
||||
}
|
||||
|
||||
bool TextInputHandler::DispatchKeyPressEvent(uint32_t aKeyCode,
|
||||
KeyNameIndex aKeyNameIndex,
|
||||
char16_t aCharCode,
|
||||
nsEventStatus& aStatus) {
|
||||
MOZ_ASSERT(aKeyCode);
|
||||
MOZ_ASSERT(mWidget);
|
||||
|
||||
WidgetKeyboardEvent keypressEvent(true, eKeyPress, mWidget);
|
||||
InitKeyEvent(keypressEvent, aKeyCode, aKeyNameIndex, aCharCode);
|
||||
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("BeginNativeInputTransaction is failed");
|
||||
return false;
|
||||
}
|
||||
return mDispatcher->MaybeDispatchKeypressEvents(keypressEvent, aStatus);
|
||||
}
|
||||
|
||||
bool TextInputHandler::EmulateKeyboardEvent(uint32_t aKeyCode,
|
||||
KeyNameIndex aKeyNameIndex,
|
||||
char16_t aCharCode) {
|
||||
MOZ_ASSERT(aCharCode);
|
||||
|
||||
MOZ_LOG(gIMELog, LogLevel::Info,
|
||||
("%p TextInputHandler::EmulateKeyboardEvent(aKeyCode=%x, "
|
||||
"aKeyNameIndex=%x, aCharCode=%x)",
|
||||
this, aKeyCode, aKeyNameIndex, aCharCode));
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
if (!DispatchKeyDownEvent(aKeyCode, aKeyNameIndex, aCharCode, status)) {
|
||||
return true;
|
||||
}
|
||||
if (Destroyed() || status == nsEventStatus_eConsumeNoDefault) {
|
||||
return true;
|
||||
}
|
||||
// TODO: Focus check
|
||||
|
||||
if (!DispatchKeyPressEvent(aKeyCode, aKeyNameIndex, aCharCode, status)) {
|
||||
return true;
|
||||
}
|
||||
if (Destroyed() || status == nsEventStatus_eConsumeNoDefault) {
|
||||
return true;
|
||||
}
|
||||
// TODO: Focus check
|
||||
|
||||
DispatchKeyUpEvent(aKeyCode, aKeyNameIndex, aCharCode, status);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TextInputHandler::OnDestroyed() { mWidget = nullptr; }
|
||||
|
||||
} // namespace mozilla::widget
|
|
@ -7,12 +7,16 @@
|
|||
with Files("**"):
|
||||
BUG_COMPONENT = ("Core", "Widget")
|
||||
|
||||
with Files("*TextInput*"):
|
||||
BUG_COMPONENT = ("Core", "DOM: UI Events & Focus Handling")
|
||||
|
||||
SOURCES += [
|
||||
"GfxInfo.cpp",
|
||||
"nsAppShell.mm",
|
||||
"nsLookAndFeel.mm",
|
||||
"nsWidgetFactory.mm",
|
||||
"nsWindow.mm",
|
||||
"TextInputHandler.mm",
|
||||
]
|
||||
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
@class UIView;
|
||||
@class ChildView;
|
||||
|
||||
namespace mozilla::widget {
|
||||
class TextInputHandler;
|
||||
}
|
||||
|
||||
class nsWindow final : public nsBaseWidget {
|
||||
typedef nsBaseWidget Inherited;
|
||||
|
||||
|
@ -79,6 +83,13 @@ class nsWindow final : public nsBaseWidget {
|
|||
void SetInputContext(const InputContext& aContext,
|
||||
const InputContextAction& aAction) override;
|
||||
InputContext GetInputContext() override;
|
||||
TextEventDispatcherListener* GetNativeTextEventDispatcherListener() override;
|
||||
|
||||
mozilla::widget::TextInputHandler* GetTextInputHandler() const {
|
||||
return mTextInputHandler;
|
||||
}
|
||||
bool IsVirtualKeyboardDisabled() const;
|
||||
|
||||
/*
|
||||
virtual bool ExecuteNativeKeyBinding(
|
||||
NativeKeyBindingsType aType,
|
||||
|
@ -102,7 +113,9 @@ class nsWindow final : public nsBaseWidget {
|
|||
nsSizeMode mSizeMode;
|
||||
nsTArray<nsWindow*> mChildren;
|
||||
nsWindow* mParent;
|
||||
InputContext mInputContext;
|
||||
|
||||
mozilla::widget::InputContext mInputContext;
|
||||
RefPtr<mozilla::widget::TextInputHandler> mTextInputHandler;
|
||||
|
||||
void OnSizeChanged(const mozilla::gfx::IntSize& aSize);
|
||||
|
||||
|
|
|
@ -27,8 +27,10 @@
|
|||
#include "gfxUtils.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsTArray.h"
|
||||
#include "TextInputHandler.h"
|
||||
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/ProfilerLabels.h"
|
||||
|
@ -70,7 +72,7 @@ class nsAutoRetainUIKitObject {
|
|||
id mObject; // [STRONG]
|
||||
};
|
||||
|
||||
@interface ChildView : UIView {
|
||||
@interface ChildView : UIView <UIKeyInput> {
|
||||
@public
|
||||
nsWindow* mGeckoChild; // weak ref
|
||||
BOOL mWaitingForPaint;
|
||||
|
@ -278,6 +280,17 @@ class nsAutoRetainUIKitObject {
|
|||
widget:mGeckoChild];
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder {
|
||||
if (!mGeckoChild) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (mGeckoChild->IsVirtualKeyboardDisabled()) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplayInRect:(CGRect)aRect {
|
||||
if ([self isUsingMainThreadOpenGL]) {
|
||||
// Draw without calling drawRect. This prevent us from
|
||||
|
@ -441,6 +454,44 @@ class nsAutoRetainUIKitObject {
|
|||
CGContextStrokeRect(aContext, aRect);
|
||||
#endif
|
||||
}
|
||||
|
||||
// UIKeyInput
|
||||
|
||||
- (void)insertText:(NSString*)text {
|
||||
if (!mGeckoChild || mGeckoChild->Destroyed()) {
|
||||
return;
|
||||
}
|
||||
widget::TextInputHandler* textInputHandler =
|
||||
mGeckoChild->GetTextInputHandler();
|
||||
if (!textInputHandler) {
|
||||
return;
|
||||
}
|
||||
textInputHandler->InsertText(text);
|
||||
}
|
||||
|
||||
- (void)deleteBackward {
|
||||
if (!mGeckoChild || mGeckoChild->Destroyed()) {
|
||||
return;
|
||||
}
|
||||
widget::TextInputHandler* textInputHandler =
|
||||
mGeckoChild->GetTextInputHandler();
|
||||
if (!textInputHandler) {
|
||||
return;
|
||||
}
|
||||
textInputHandler->HandleCommand(Command::DeleteCharBackward);
|
||||
}
|
||||
|
||||
- (BOOL)hasText {
|
||||
if (!mGeckoChild || mGeckoChild->Destroyed()) {
|
||||
return NO;
|
||||
}
|
||||
widget::InputContext context = mGeckoChild->GetInputContext();
|
||||
if (context.mIMEState.mEnabled == mozilla::widget::IMEEnabled::Disabled) {
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
nsWindow::nsWindow()
|
||||
|
@ -516,6 +567,8 @@ nsresult nsWindow::Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
|
|||
[nsAppShell::gTopLevelViews addObject:mNativeView];
|
||||
}
|
||||
|
||||
mTextInputHandler = new widget::TextInputHandler(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -527,6 +580,11 @@ void nsWindow::Destroy() {
|
|||
|
||||
if (mParent) mParent->mChildren.RemoveElement(this);
|
||||
|
||||
if (mTextInputHandler) {
|
||||
mTextInputHandler->OnDestroyed();
|
||||
}
|
||||
mTextInputHandler = nullptr;
|
||||
|
||||
[mNativeView widgetDestroyed];
|
||||
|
||||
nsBaseWidget::Destroy();
|
||||
|
@ -723,14 +781,44 @@ nsresult nsWindow::DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
|
|||
|
||||
void nsWindow::SetInputContext(const InputContext& aContext,
|
||||
const InputContextAction& aAction) {
|
||||
// TODO: actually show VKB
|
||||
NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
|
||||
|
||||
mInputContext = aContext;
|
||||
|
||||
if (IsVirtualKeyboardDisabled()) {
|
||||
[mNativeView resignFirstResponder];
|
||||
return;
|
||||
}
|
||||
|
||||
[mNativeView becomeFirstResponder];
|
||||
|
||||
if (aAction.UserMightRequestOpenVKB()) {
|
||||
[mNativeView reloadInputViews];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_IGNORE_BLOCK;
|
||||
}
|
||||
|
||||
mozilla::widget::InputContext nsWindow::GetInputContext() {
|
||||
widget::InputContext nsWindow::GetInputContext() {
|
||||
if (!mTextInputHandler) {
|
||||
InputContext context;
|
||||
context.mIMEState.mEnabled = IMEEnabled::Disabled;
|
||||
context.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
|
||||
return context;
|
||||
}
|
||||
return mInputContext;
|
||||
}
|
||||
|
||||
widget::TextEventDispatcherListener*
|
||||
nsWindow::GetNativeTextEventDispatcherListener() {
|
||||
return mTextInputHandler;
|
||||
}
|
||||
|
||||
bool nsWindow::IsVirtualKeyboardDisabled() const {
|
||||
return mInputContext.mIMEState.mEnabled == IMEEnabled::Disabled ||
|
||||
mInputContext.mHTMLInputMode.EqualsLiteral("none");
|
||||
}
|
||||
|
||||
void nsWindow::SetBackgroundColor(const nscolor& aColor) {
|
||||
mNativeView.backgroundColor = [UIColor colorWithRed:NS_GET_R(aColor)
|
||||
green:NS_GET_G(aColor)
|
||||
|
|
|
@ -27,9 +27,6 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
|
|||
XPIDL_SOURCES += [
|
||||
"nsIMacPreferencesReader.idl",
|
||||
]
|
||||
EXPORTS += [
|
||||
"nsObjCExceptions.h",
|
||||
]
|
||||
EXPORTS.mozilla += [
|
||||
"MacHelpers.h",
|
||||
"MacStringHelpers.h",
|
||||
|
@ -39,6 +36,12 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
|
|||
"MacHelpers.mm",
|
||||
"MacStringHelpers.mm",
|
||||
"nsMacPreferencesReader.mm",
|
||||
]
|
||||
if CONFIG["OS_ARCH"] == "Darwin":
|
||||
EXPORTS += [
|
||||
"nsObjCExceptions.h",
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
"nsObjCExceptions.mm",
|
||||
]
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче