mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 20:30:41 +00:00
bug 1171113 - Add widget/uikit. r=roc (NPOTB)
--HG-- extra : commitid : 1I5FPzgYF3d extra : rebase_source : d96adf156c955a77d3303cf69301d133371244d3
This commit is contained in:
parent
0f79aeadea
commit
7916ef866c
@ -4216,11 +4216,20 @@ pref("layers.offmainthreadcomposition.frame-rate", -1);
|
||||
pref("layers.async-video.enabled", true);
|
||||
pref("layers.async-video-oop.enabled",true);
|
||||
|
||||
#ifdef MOZ_WIDGET_UIKIT
|
||||
pref("layers.async-pan-zoom.enabled", true);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_UIKIT
|
||||
pref("layers.async-pan-zoom.enabled", true);
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
pref("layers.enable-tiles", true);
|
||||
pref("layers.tiled-drawtarget.enabled", true);
|
||||
#endif
|
||||
|
||||
|
||||
// same effect as layers.offmainthreadcomposition.enabled, but specifically for
|
||||
// use with tests.
|
||||
pref("layers.offmainthreadcomposition.testing.enabled", false);
|
||||
|
@ -56,6 +56,7 @@ enum OperatingSystem {
|
||||
DRIVER_OS_OS_X_10_9,
|
||||
DRIVER_OS_OS_X_10_10,
|
||||
DRIVER_OS_ANDROID,
|
||||
DRIVER_OS_IOS,
|
||||
DRIVER_OS_ALL
|
||||
};
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
||||
|
||||
if toolkit in ('cocoa', 'qt', 'android', 'gonk'):
|
||||
if toolkit in ('cocoa', 'qt', 'android', 'gonk', 'uikit'):
|
||||
DIRS += [toolkit]
|
||||
if toolkit in ('qt', 'android', 'gonk', 'gtk2', 'gtk3'):
|
||||
EXPORTS += ['nsIPrintDialogService.h']
|
||||
@ -201,8 +201,8 @@ if toolkit in ('cocoa', 'windows'):
|
||||
'nsBaseClipboard.cpp',
|
||||
]
|
||||
|
||||
if toolkit in ('qt', 'gtk2', 'gtk3', 'cocoa', 'windows',
|
||||
'android', 'gonk'):
|
||||
if toolkit in {'qt', 'gtk2', 'gtk3', 'cocoa', 'windows',
|
||||
'android', 'gonk', 'uikit'}:
|
||||
UNIFIED_SOURCES += [
|
||||
'nsBaseFilePicker.cpp',
|
||||
]
|
||||
|
@ -904,7 +904,8 @@ nsBaseWidget::ComputeShouldAccelerate(bool aDefault)
|
||||
// that XUL widget opts in to acceleration, but that's probably OK.
|
||||
bool accelerateByDefault = nsCocoaFeatures::AccelerateByDefault();
|
||||
#elif defined(XP_WIN) || defined(ANDROID) || \
|
||||
defined(MOZ_GL_PROVIDER) || defined(MOZ_WIDGET_QT)
|
||||
defined(MOZ_GL_PROVIDER) || defined(MOZ_WIDGET_QT) || \
|
||||
defined(MOZ_WIDGET_UIKIT)
|
||||
bool accelerateByDefault = true;
|
||||
#else
|
||||
bool accelerateByDefault = false;
|
||||
|
241
widget/uikit/GfxInfo.cpp
Normal file
241
widget/uikit/GfxInfo.cpp
Normal file
@ -0,0 +1,241 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "GfxInfo.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
|
||||
#endif
|
||||
|
||||
GfxInfo::GfxInfo()
|
||||
{
|
||||
}
|
||||
|
||||
GfxInfo::~GfxInfo()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
GfxInfo::GetD2DEnabled(bool *aEnabled)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GfxInfo::GetDWriteEnabled(bool *aEnabled)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString DWriteVersion; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString cleartypeParameters; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDescription; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDescription2; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterRAM; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterRAM2; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDriver; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDriver2; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDriverVersion; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDriverVersion2; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDriverDate; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDriverDate2; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterVendorID; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterVendorID2; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDeviceID; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDeviceID2; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterSubsysID; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterSubsysID(nsAString & aAdapterSubsysID)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterSubsysID2; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterSubsysID2(nsAString & aAdapterSubsysID)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute boolean isGPU2Active; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const nsTArray<GfxDriverInfo>&
|
||||
GfxInfo::GetGfxDriverInfo()
|
||||
{
|
||||
if (mDriverInfo->IsEmpty()) {
|
||||
APPEND_TO_DRIVER_BLOCKLIST2( DRIVER_OS_ALL,
|
||||
(nsAString&) GfxDriverInfo::GetDeviceVendor(VendorAll), GfxDriverInfo::allDevices,
|
||||
nsIGfxInfo::FEATURE_OPENGL_LAYERS, nsIGfxInfo::FEATURE_STATUS_OK,
|
||||
DRIVER_COMPARISON_IGNORED, GfxDriverInfo::allDriverVersions );
|
||||
}
|
||||
|
||||
return *mDriverInfo;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GfxInfo::GetFeatureStatusImpl(int32_t aFeature,
|
||||
int32_t *aStatus,
|
||||
nsAString & aSuggestedDriverVersion,
|
||||
const nsTArray<GfxDriverInfo>& aDriverInfo,
|
||||
OperatingSystem* aOS /* = nullptr */)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aStatus);
|
||||
aSuggestedDriverVersion.SetIsVoid(true);
|
||||
*aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN;
|
||||
if (aOS)
|
||||
*aOS = DRIVER_OS_IOS;
|
||||
|
||||
// OpenGL layers are never blacklisted on iOS.
|
||||
// This early return is so we avoid potentially slow
|
||||
// GLStrings initialization on startup when we initialize GL layers.
|
||||
if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS ||
|
||||
aFeature == nsIGfxInfo::FEATURE_WEBGL_OPENGL ||
|
||||
aFeature == nsIGfxInfo::FEATURE_WEBGL_MSAA) {
|
||||
*aStatus = nsIGfxInfo::FEATURE_STATUS_OK;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, aOS);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
// Implement nsIGfxInfoDebug
|
||||
|
||||
/* void spoofVendorID (in DOMString aVendorID); */
|
||||
NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* void spoofDeviceID (in unsigned long aDeviceID); */
|
||||
NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* void spoofDriverVersion (in DOMString aDriverVersion); */
|
||||
NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* void spoofOSVersion (in unsigned long aVersion); */
|
||||
NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
78
widget/uikit/GfxInfo.h
Normal file
78
widget/uikit/GfxInfo.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* vim: se cin sw=2 ts=2 et : */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* 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 __mozilla_widget_GfxInfo_h__
|
||||
#define __mozilla_widget_GfxInfo_h__
|
||||
|
||||
#include "GfxInfoBase.h"
|
||||
#include "GfxDriverInfo.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
}
|
||||
|
||||
namespace widget {
|
||||
|
||||
class GfxInfo : public GfxInfoBase
|
||||
{
|
||||
private:
|
||||
~GfxInfo();
|
||||
|
||||
public:
|
||||
GfxInfo();
|
||||
|
||||
// We only declare the subset of nsIGfxInfo that we actually implement. The
|
||||
// rest is brought forward from GfxInfoBase.
|
||||
NS_IMETHOD GetD2DEnabled(bool *aD2DEnabled);
|
||||
NS_IMETHOD GetDWriteEnabled(bool *aDWriteEnabled);
|
||||
NS_IMETHOD GetDWriteVersion(nsAString & aDwriteVersion);
|
||||
NS_IMETHOD GetCleartypeParameters(nsAString & aCleartypeParams);
|
||||
NS_IMETHOD GetAdapterDescription(nsAString & aAdapterDescription);
|
||||
NS_IMETHOD GetAdapterDriver(nsAString & aAdapterDriver);
|
||||
NS_IMETHOD GetAdapterVendorID(nsAString & aAdapterVendorID);
|
||||
NS_IMETHOD GetAdapterDeviceID(nsAString & aAdapterDeviceID);
|
||||
NS_IMETHOD GetAdapterSubsysID(nsAString & aAdapterSubsysID);
|
||||
NS_IMETHOD GetAdapterRAM(nsAString & aAdapterRAM);
|
||||
NS_IMETHOD GetAdapterDriverVersion(nsAString & aAdapterDriverVersion);
|
||||
NS_IMETHOD GetAdapterDriverDate(nsAString & aAdapterDriverDate);
|
||||
NS_IMETHOD GetAdapterDescription2(nsAString & aAdapterDescription);
|
||||
NS_IMETHOD GetAdapterDriver2(nsAString & aAdapterDriver);
|
||||
NS_IMETHOD GetAdapterVendorID2(nsAString & aAdapterVendorID);
|
||||
NS_IMETHOD GetAdapterDeviceID2(nsAString & aAdapterDeviceID);
|
||||
NS_IMETHOD GetAdapterSubsysID2(nsAString & aAdapterSubsysID);
|
||||
NS_IMETHOD GetAdapterRAM2(nsAString & aAdapterRAM);
|
||||
NS_IMETHOD GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion);
|
||||
NS_IMETHOD GetAdapterDriverDate2(nsAString & aAdapterDriverDate);
|
||||
NS_IMETHOD GetIsGPU2Active(bool *aIsGPU2Active);
|
||||
using GfxInfoBase::GetFeatureStatus;
|
||||
using GfxInfoBase::GetFeatureSuggestedDriverVersion;
|
||||
using GfxInfoBase::GetWebGLParameter;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIGFXINFODEBUG
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
virtual nsresult GetFeatureStatusImpl(int32_t aFeature,
|
||||
int32_t *aStatus,
|
||||
nsAString & aSuggestedDriverVersion,
|
||||
const nsTArray<GfxDriverInfo>& aDriverInfo,
|
||||
OperatingSystem* aOS = nullptr);
|
||||
virtual const nsTArray<GfxDriverInfo>& GetGfxDriverInfo();
|
||||
};
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* __mozilla_widget_GfxInfo_h__ */
|
19
widget/uikit/moz.build
Normal file
19
widget/uikit/moz.build
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
SOURCES += [
|
||||
'GfxInfo.cpp',
|
||||
'nsAppShell.mm',
|
||||
'nsLookAndFeel.mm',
|
||||
'nsScreenManager.mm',
|
||||
'nsWidgetFactory.mm',
|
||||
'nsWindow.mm',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'/widget',
|
||||
]
|
57
widget/uikit/nsAppShell.h
Normal file
57
widget/uikit/nsAppShell.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
/*
|
||||
* Runs the main native UIKit run loop, interrupting it as needed to process
|
||||
* Gecko events.
|
||||
*/
|
||||
|
||||
#ifndef nsAppShell_h_
|
||||
#define nsAppShell_h_
|
||||
|
||||
#include "nsBaseAppShell.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <CoreFoundation/CFRunLoop.h>
|
||||
#include <UIKit/UIWindow.h>
|
||||
|
||||
@class AppShellDelegate;
|
||||
|
||||
class nsAppShell : public nsBaseAppShell
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD ResumeNative(void);
|
||||
|
||||
nsAppShell();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_IMETHOD Run(void);
|
||||
NS_IMETHOD Exit(void);
|
||||
// Called by the application delegate
|
||||
void WillTerminate(void);
|
||||
|
||||
static nsAppShell* gAppShell;
|
||||
static UIWindow* gWindow;
|
||||
static NSMutableArray* gTopLevelViews;
|
||||
|
||||
protected:
|
||||
virtual ~nsAppShell();
|
||||
|
||||
static void ProcessGeckoEvents(void* aInfo);
|
||||
virtual void ScheduleNativeEventCallback();
|
||||
virtual bool ProcessNextNativeEvent(bool aMayWait);
|
||||
|
||||
NSAutoreleasePool* mAutoreleasePool;
|
||||
AppShellDelegate* mDelegate;
|
||||
CFRunLoopRef mCFRunLoop;
|
||||
CFRunLoopSourceRef mCFRunLoopSource;
|
||||
|
||||
bool mTerminated;
|
||||
bool mNotifiedWillTerminate;
|
||||
};
|
||||
|
||||
#endif // nsAppShell_h_
|
271
widget/uikit/nsAppShell.mm
Normal file
271
widget/uikit/nsAppShell.mm
Normal file
@ -0,0 +1,271 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#import <UIKit/UIApplication.h>
|
||||
#import <UIKit/UIScreen.h>
|
||||
#import <UIKit/UIWindow.h>
|
||||
#import <UIKit/UIViewController.h>
|
||||
|
||||
#include "nsAppShell.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsMemoryPressure.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
|
||||
nsAppShell *nsAppShell::gAppShell = NULL;
|
||||
UIWindow *nsAppShell::gWindow = nil;
|
||||
NSMutableArray *nsAppShell::gTopLevelViews = [[NSMutableArray alloc] init];
|
||||
|
||||
#define ALOG(args...) fprintf(stderr, args); fprintf(stderr, "\n")
|
||||
|
||||
// ViewController
|
||||
@interface ViewController : UIViewController
|
||||
@end
|
||||
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
- (void)loadView {
|
||||
ALOG("[ViewController loadView]");
|
||||
CGRect r = {{0, 0}, {100, 100}};
|
||||
self.view = [[UIView alloc] initWithFrame:r];
|
||||
[self.view setBackgroundColor:[UIColor lightGrayColor]];
|
||||
// add all of the top level views as children
|
||||
for (UIView* v in nsAppShell::gTopLevelViews) {
|
||||
ALOG("[ViewController.view addSubView:%p]", v);
|
||||
[self.view addSubview:v];
|
||||
}
|
||||
[nsAppShell::gTopLevelViews release];
|
||||
nsAppShell::gTopLevelViews = nil;
|
||||
}
|
||||
@end
|
||||
|
||||
// AppShellDelegate
|
||||
//
|
||||
// Acts as a delegate for the UIApplication
|
||||
|
||||
@interface AppShellDelegate : NSObject <UIApplicationDelegate> {
|
||||
}
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
@end
|
||||
|
||||
@implementation AppShellDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
ALOG("[AppShellDelegate application:didFinishLaunchingWithOptions:]");
|
||||
// We only create one window, since we can only display one window at
|
||||
// a time anyway. Also, iOS 4 fails to display UIWindows if you
|
||||
// create them before calling UIApplicationMain, so this makes more sense.
|
||||
nsAppShell::gWindow = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] retain];
|
||||
self.window = nsAppShell::gWindow;
|
||||
|
||||
self.window.rootViewController = [[ViewController alloc] init];
|
||||
|
||||
// just to make things more visible for now
|
||||
nsAppShell::gWindow.backgroundColor = [UIColor blueColor];
|
||||
[nsAppShell::gWindow makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
ALOG("[AppShellDelegate applicationWillTerminate:]");
|
||||
nsAppShell::gAppShell->WillTerminate();
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
ALOG("[AppShellDelegate applicationDidBecomeActive:]");
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
{
|
||||
ALOG("[AppShellDelegate applicationWillResignActive:]");
|
||||
}
|
||||
|
||||
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
|
||||
{
|
||||
ALOG("[AppShellDelegate applicationDidReceiveMemoryWarning:]");
|
||||
NS_DispatchMemoryPressure(MemPressure_New);
|
||||
}
|
||||
@end
|
||||
|
||||
// nsAppShell implementation
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppShell::ResumeNative(void)
|
||||
{
|
||||
return nsBaseAppShell::ResumeNative();
|
||||
}
|
||||
|
||||
nsAppShell::nsAppShell()
|
||||
: mAutoreleasePool(NULL),
|
||||
mDelegate(NULL),
|
||||
mCFRunLoop(NULL),
|
||||
mCFRunLoopSource(NULL),
|
||||
mTerminated(false),
|
||||
mNotifiedWillTerminate(false)
|
||||
{
|
||||
gAppShell = this;
|
||||
}
|
||||
|
||||
nsAppShell::~nsAppShell()
|
||||
{
|
||||
if (mAutoreleasePool) {
|
||||
[mAutoreleasePool release];
|
||||
mAutoreleasePool = NULL;
|
||||
}
|
||||
|
||||
if (mCFRunLoop) {
|
||||
if (mCFRunLoopSource) {
|
||||
::CFRunLoopRemoveSource(mCFRunLoop, mCFRunLoopSource,
|
||||
kCFRunLoopCommonModes);
|
||||
::CFRelease(mCFRunLoopSource);
|
||||
}
|
||||
::CFRelease(mCFRunLoop);
|
||||
}
|
||||
|
||||
gAppShell = NULL;
|
||||
}
|
||||
|
||||
// Init
|
||||
//
|
||||
// public
|
||||
nsresult
|
||||
nsAppShell::Init()
|
||||
{
|
||||
mAutoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Add a CFRunLoopSource to the main native run loop. The source is
|
||||
// responsible for interrupting the run loop when Gecko events are ready.
|
||||
|
||||
mCFRunLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
|
||||
NS_ENSURE_STATE(mCFRunLoop);
|
||||
::CFRetain(mCFRunLoop);
|
||||
|
||||
CFRunLoopSourceContext context;
|
||||
bzero(&context, sizeof(context));
|
||||
// context.version = 0;
|
||||
context.info = this;
|
||||
context.perform = ProcessGeckoEvents;
|
||||
|
||||
mCFRunLoopSource = ::CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
|
||||
NS_ENSURE_STATE(mCFRunLoopSource);
|
||||
|
||||
::CFRunLoopAddSource(mCFRunLoop, mCFRunLoopSource, kCFRunLoopCommonModes);
|
||||
|
||||
return nsBaseAppShell::Init();
|
||||
}
|
||||
|
||||
// ProcessGeckoEvents
|
||||
//
|
||||
// The "perform" target of mCFRunLoop, called when mCFRunLoopSource is
|
||||
// signalled from ScheduleNativeEventCallback.
|
||||
//
|
||||
// protected static
|
||||
void
|
||||
nsAppShell::ProcessGeckoEvents(void* aInfo)
|
||||
{
|
||||
nsAppShell* self = static_cast<nsAppShell*> (aInfo);
|
||||
self->NativeEventCallback();
|
||||
self->Release();
|
||||
}
|
||||
|
||||
// WillTerminate
|
||||
//
|
||||
// public
|
||||
void
|
||||
nsAppShell::WillTerminate()
|
||||
{
|
||||
mNotifiedWillTerminate = true;
|
||||
if (mTerminated)
|
||||
return;
|
||||
mTerminated = true;
|
||||
// We won't get another chance to process events
|
||||
NS_ProcessPendingEvents(NS_GetCurrentThread());
|
||||
|
||||
// Unless we call nsBaseAppShell::Exit() here, it might not get called
|
||||
// at all.
|
||||
nsBaseAppShell::Exit();
|
||||
}
|
||||
|
||||
// ScheduleNativeEventCallback
|
||||
//
|
||||
// protected virtual
|
||||
void
|
||||
nsAppShell::ScheduleNativeEventCallback()
|
||||
{
|
||||
if (mTerminated)
|
||||
return;
|
||||
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
// This will invoke ProcessGeckoEvents on the main thread.
|
||||
::CFRunLoopSourceSignal(mCFRunLoopSource);
|
||||
::CFRunLoopWakeUp(mCFRunLoop);
|
||||
}
|
||||
|
||||
// ProcessNextNativeEvent
|
||||
//
|
||||
// protected virtual
|
||||
bool
|
||||
nsAppShell::ProcessNextNativeEvent(bool aMayWait)
|
||||
{
|
||||
if (mTerminated)
|
||||
return false;
|
||||
|
||||
NSString* currentMode = nil;
|
||||
NSDate* waitUntil = nil;
|
||||
if (aMayWait)
|
||||
waitUntil = [NSDate distantFuture];
|
||||
NSRunLoop* currentRunLoop = [NSRunLoop currentRunLoop];
|
||||
|
||||
BOOL eventProcessed = NO;
|
||||
do {
|
||||
currentMode = [currentRunLoop currentMode];
|
||||
if (!currentMode)
|
||||
currentMode = NSDefaultRunLoopMode;
|
||||
|
||||
if (aMayWait)
|
||||
eventProcessed = [currentRunLoop runMode:currentMode beforeDate:waitUntil];
|
||||
else
|
||||
[currentRunLoop acceptInputForMode:currentMode beforeDate:waitUntil];
|
||||
} while(eventProcessed && aMayWait);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Run
|
||||
//
|
||||
// public
|
||||
NS_IMETHODIMP
|
||||
nsAppShell::Run(void)
|
||||
{
|
||||
ALOG("nsAppShell::Run");
|
||||
char argv[1][4] = {"app"};
|
||||
UIApplicationMain(1, (char**)argv, nil, @"AppShellDelegate");
|
||||
// UIApplicationMain doesn't exit. :-(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppShell::Exit(void)
|
||||
{
|
||||
if (mTerminated)
|
||||
return NS_OK;
|
||||
|
||||
mTerminated = true;
|
||||
return nsBaseAppShell::Exit();
|
||||
}
|
35
widget/uikit/nsLookAndFeel.h
Normal file
35
widget/uikit/nsLookAndFeel.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 __nsLookAndFeel
|
||||
#define __nsLookAndFeel
|
||||
|
||||
#include "nsXPLookAndFeel.h"
|
||||
|
||||
class nsLookAndFeel: public nsXPLookAndFeel
|
||||
{
|
||||
public:
|
||||
nsLookAndFeel();
|
||||
virtual ~nsLookAndFeel();
|
||||
|
||||
virtual nsresult NativeGetColor(const ColorID aID, nscolor &aResult);
|
||||
virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
|
||||
virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
|
||||
virtual bool GetFontImpl(FontID aID, nsString& aFontName,
|
||||
gfxFontStyle& aFontStyle,
|
||||
float aDevPixPerCSSPixel);
|
||||
virtual char16_t GetPasswordCharacterImpl()
|
||||
{
|
||||
// unicode value for the bullet character, used for password textfields.
|
||||
return 0x2022;
|
||||
}
|
||||
|
||||
static bool UseOverlayScrollbars()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
397
widget/uikit/nsLookAndFeel.mm
Normal file
397
widget/uikit/nsLookAndFeel.mm
Normal file
@ -0,0 +1,397 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#import <UIKit/UIColor.h>
|
||||
#import <UIKit/UIInterface.h>
|
||||
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "gfxFont.h"
|
||||
#include "gfxFontConstants.h"
|
||||
|
||||
nsLookAndFeel::nsLookAndFeel()
|
||||
: nsXPLookAndFeel()
|
||||
{
|
||||
}
|
||||
|
||||
nsLookAndFeel::~nsLookAndFeel()
|
||||
{
|
||||
}
|
||||
|
||||
static nscolor GetColorFromUIColor(UIColor* aColor)
|
||||
{
|
||||
CGColorRef cgColor = [aColor CGColor];
|
||||
CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(cgColor));
|
||||
const CGFloat* components = CGColorGetComponents(cgColor);
|
||||
if (model == kCGColorSpaceModelRGB) {
|
||||
return NS_RGB((unsigned int)(components[0] * 255.0),
|
||||
(unsigned int)(components[1] * 255.0),
|
||||
(unsigned int)(components[2] * 255.0));
|
||||
}
|
||||
else if (model == kCGColorSpaceModelMonochrome) {
|
||||
unsigned int val = (unsigned int)(components[0] * 255.0);
|
||||
return NS_RGBA(val, val, val,
|
||||
(unsigned int)(components[1] * 255.0));
|
||||
}
|
||||
NS_NOTREACHED("Unhandled color space!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLookAndFeel::NativeGetColor(const ColorID aID, nscolor &aResult)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
|
||||
switch (aID) {
|
||||
case eColorID_WindowBackground:
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
break;
|
||||
case eColorID_WindowForeground:
|
||||
aResult = NS_RGB(0x00,0x00,0x00);
|
||||
break;
|
||||
case eColorID_WidgetBackground:
|
||||
aResult = NS_RGB(0xdd,0xdd,0xdd);
|
||||
break;
|
||||
case eColorID_WidgetForeground:
|
||||
aResult = NS_RGB(0x00,0x00,0x00);
|
||||
break;
|
||||
case eColorID_WidgetSelectBackground:
|
||||
aResult = NS_RGB(0x80,0x80,0x80);
|
||||
break;
|
||||
case eColorID_WidgetSelectForeground:
|
||||
aResult = NS_RGB(0x00,0x00,0x80);
|
||||
break;
|
||||
case eColorID_Widget3DHighlight:
|
||||
aResult = NS_RGB(0xa0,0xa0,0xa0);
|
||||
break;
|
||||
case eColorID_Widget3DShadow:
|
||||
aResult = NS_RGB(0x40,0x40,0x40);
|
||||
break;
|
||||
case eColorID_TextBackground:
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
break;
|
||||
case eColorID_TextForeground:
|
||||
aResult = NS_RGB(0x00,0x00,0x00);
|
||||
break;
|
||||
case eColorID_TextSelectBackground:
|
||||
case eColorID_highlight: // CSS2 color
|
||||
aResult = NS_RGB(0xaa,0xaa,0xaa);
|
||||
break;
|
||||
case eColorID__moz_menuhover:
|
||||
aResult = NS_RGB(0xee,0xee,0xee);
|
||||
break;
|
||||
case eColorID_TextSelectForeground:
|
||||
case eColorID_highlighttext: // CSS2 color
|
||||
case eColorID__moz_menuhovertext:
|
||||
GetColor(eColorID_TextSelectBackground, aResult);
|
||||
if (aResult == 0x000000)
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
else
|
||||
aResult = NS_DONT_CHANGE_COLOR;
|
||||
break;
|
||||
case eColorID_IMESelectedRawTextBackground:
|
||||
case eColorID_IMESelectedConvertedTextBackground:
|
||||
case eColorID_IMERawInputBackground:
|
||||
case eColorID_IMEConvertedTextBackground:
|
||||
aResult = NS_TRANSPARENT;
|
||||
break;
|
||||
case eColorID_IMESelectedRawTextForeground:
|
||||
case eColorID_IMESelectedConvertedTextForeground:
|
||||
case eColorID_IMERawInputForeground:
|
||||
case eColorID_IMEConvertedTextForeground:
|
||||
aResult = NS_SAME_AS_FOREGROUND_COLOR;
|
||||
break;
|
||||
case eColorID_IMERawInputUnderline:
|
||||
case eColorID_IMEConvertedTextUnderline:
|
||||
aResult = NS_40PERCENT_FOREGROUND_COLOR;
|
||||
break;
|
||||
case eColorID_IMESelectedRawTextUnderline:
|
||||
case eColorID_IMESelectedConvertedTextUnderline:
|
||||
aResult = NS_SAME_AS_FOREGROUND_COLOR;
|
||||
break;
|
||||
case eColorID_SpellCheckerUnderline:
|
||||
aResult = NS_RGB(0xff, 0, 0);
|
||||
break;
|
||||
|
||||
//
|
||||
// css2 system colors http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
|
||||
//
|
||||
case eColorID_buttontext:
|
||||
case eColorID__moz_buttonhovertext:
|
||||
case eColorID_captiontext:
|
||||
case eColorID_menutext:
|
||||
case eColorID_infotext:
|
||||
case eColorID__moz_menubartext:
|
||||
case eColorID_windowtext:
|
||||
aResult = GetColorFromUIColor([UIColor darkTextColor]);
|
||||
break;
|
||||
case eColorID_activecaption:
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
break;
|
||||
case eColorID_activeborder:
|
||||
aResult = NS_RGB(0x00,0x00,0x00);
|
||||
break;
|
||||
case eColorID_appworkspace:
|
||||
aResult = NS_RGB(0xFF,0xFF,0xFF);
|
||||
break;
|
||||
case eColorID_background:
|
||||
aResult = NS_RGB(0x63,0x63,0xCE);
|
||||
break;
|
||||
case eColorID_buttonface:
|
||||
case eColorID__moz_buttonhoverface:
|
||||
aResult = NS_RGB(0xF0,0xF0,0xF0);
|
||||
break;
|
||||
case eColorID_buttonhighlight:
|
||||
aResult = NS_RGB(0xFF,0xFF,0xFF);
|
||||
break;
|
||||
case eColorID_buttonshadow:
|
||||
aResult = NS_RGB(0xDC,0xDC,0xDC);
|
||||
break;
|
||||
case eColorID_graytext:
|
||||
aResult = NS_RGB(0x44,0x44,0x44);
|
||||
break;
|
||||
case eColorID_inactiveborder:
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
break;
|
||||
case eColorID_inactivecaption:
|
||||
aResult = NS_RGB(0xaa,0xaa,0xaa);
|
||||
break;
|
||||
case eColorID_inactivecaptiontext:
|
||||
aResult = NS_RGB(0x45,0x45,0x45);
|
||||
break;
|
||||
case eColorID_scrollbar:
|
||||
aResult = NS_RGB(0,0,0); //XXX
|
||||
break;
|
||||
case eColorID_threeddarkshadow:
|
||||
aResult = NS_RGB(0xDC,0xDC,0xDC);
|
||||
break;
|
||||
case eColorID_threedshadow:
|
||||
aResult = NS_RGB(0xE0,0xE0,0xE0);
|
||||
break;
|
||||
case eColorID_threedface:
|
||||
aResult = NS_RGB(0xF0,0xF0,0xF0);
|
||||
break;
|
||||
case eColorID_threedhighlight:
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
break;
|
||||
case eColorID_threedlightshadow:
|
||||
aResult = NS_RGB(0xDA,0xDA,0xDA);
|
||||
break;
|
||||
case eColorID_menu:
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
break;
|
||||
case eColorID_infobackground:
|
||||
aResult = NS_RGB(0xFF,0xFF,0xC7);
|
||||
break;
|
||||
case eColorID_windowframe:
|
||||
aResult = NS_RGB(0xaa,0xaa,0xaa);
|
||||
break;
|
||||
case eColorID_window:
|
||||
case eColorID__moz_field:
|
||||
case eColorID__moz_combobox:
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
break;
|
||||
case eColorID__moz_fieldtext:
|
||||
case eColorID__moz_comboboxtext:
|
||||
aResult = GetColorFromUIColor([UIColor darkTextColor]);
|
||||
break;
|
||||
case eColorID__moz_dialog:
|
||||
aResult = NS_RGB(0xaa,0xaa,0xaa);
|
||||
break;
|
||||
case eColorID__moz_dialogtext:
|
||||
case eColorID__moz_cellhighlighttext:
|
||||
case eColorID__moz_html_cellhighlighttext:
|
||||
aResult = GetColorFromUIColor([UIColor darkTextColor]);
|
||||
break;
|
||||
case eColorID__moz_dragtargetzone:
|
||||
case eColorID__moz_mac_chrome_active:
|
||||
case eColorID__moz_mac_chrome_inactive:
|
||||
aResult = NS_RGB(0xaa,0xaa,0xaa);
|
||||
break;
|
||||
case eColorID__moz_mac_focusring:
|
||||
aResult = NS_RGB(0x3F,0x98,0xDD);
|
||||
break;
|
||||
case eColorID__moz_mac_menushadow:
|
||||
aResult = NS_RGB(0xA3,0xA3,0xA3);
|
||||
break;
|
||||
case eColorID__moz_mac_menutextdisable:
|
||||
aResult = NS_RGB(0x88,0x88,0x88);
|
||||
break;
|
||||
case eColorID__moz_mac_menutextselect:
|
||||
aResult = NS_RGB(0xaa,0xaa,0xaa);
|
||||
break;
|
||||
case eColorID__moz_mac_disabledtoolbartext:
|
||||
aResult = NS_RGB(0x3F,0x3F,0x3F);
|
||||
break;
|
||||
case eColorID__moz_mac_menuselect:
|
||||
aResult = NS_RGB(0xaa,0xaa,0xaa);
|
||||
break;
|
||||
case eColorID__moz_buttondefault:
|
||||
aResult = NS_RGB(0xDC,0xDC,0xDC);
|
||||
break;
|
||||
case eColorID__moz_cellhighlight:
|
||||
case eColorID__moz_html_cellhighlight:
|
||||
case eColorID__moz_mac_secondaryhighlight:
|
||||
// For inactive list selection
|
||||
aResult = NS_RGB(0xaa,0xaa,0xaa);
|
||||
break;
|
||||
case eColorID__moz_eventreerow:
|
||||
// Background color of even list rows.
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
break;
|
||||
case eColorID__moz_oddtreerow:
|
||||
// Background color of odd list rows.
|
||||
aResult = NS_TRANSPARENT;
|
||||
break;
|
||||
case eColorID__moz_nativehyperlinktext:
|
||||
// There appears to be no available system defined color. HARDCODING to the appropriate color.
|
||||
aResult = NS_RGB(0x14,0x4F,0xAE);
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Someone asked nsILookAndFeel for a color I don't know about");
|
||||
aResult = NS_RGB(0xff,0xff,0xff);
|
||||
res = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLookAndFeel::GetIntImpl(IntID aID, int32_t &aResult)
|
||||
{
|
||||
nsresult res = nsXPLookAndFeel::GetIntImpl(aID, aResult);
|
||||
if (NS_SUCCEEDED(res))
|
||||
return res;
|
||||
res = NS_OK;
|
||||
|
||||
switch (aID) {
|
||||
case eIntID_CaretBlinkTime:
|
||||
aResult = 567;
|
||||
break;
|
||||
case eIntID_CaretWidth:
|
||||
aResult = 1;
|
||||
break;
|
||||
case eIntID_ShowCaretDuringSelection:
|
||||
aResult = 0;
|
||||
break;
|
||||
case eIntID_SelectTextfieldsOnKeyFocus:
|
||||
// Select textfield content when focused by kbd
|
||||
// used by nsEventStateManager::sTextfieldSelectModel
|
||||
aResult = 1;
|
||||
break;
|
||||
case eIntID_SubmenuDelay:
|
||||
aResult = 200;
|
||||
break;
|
||||
case eIntID_MenusCanOverlapOSBar:
|
||||
// xul popups are not allowed to overlap the menubar.
|
||||
aResult = 0;
|
||||
break;
|
||||
case eIntID_SkipNavigatingDisabledMenuItem:
|
||||
aResult = 1;
|
||||
break;
|
||||
case eIntID_DragThresholdX:
|
||||
case eIntID_DragThresholdY:
|
||||
aResult = 4;
|
||||
break;
|
||||
case eIntID_ScrollArrowStyle:
|
||||
aResult = eScrollArrow_None;
|
||||
break;
|
||||
case eIntID_ScrollSliderStyle:
|
||||
aResult = eScrollThumbStyle_Proportional;
|
||||
break;
|
||||
case eIntID_TreeOpenDelay:
|
||||
aResult = 1000;
|
||||
break;
|
||||
case eIntID_TreeCloseDelay:
|
||||
aResult = 1000;
|
||||
break;
|
||||
case eIntID_TreeLazyScrollDelay:
|
||||
aResult = 150;
|
||||
break;
|
||||
case eIntID_TreeScrollDelay:
|
||||
aResult = 100;
|
||||
break;
|
||||
case eIntID_TreeScrollLinesMax:
|
||||
aResult = 3;
|
||||
break;
|
||||
case eIntID_DWMCompositor:
|
||||
case eIntID_WindowsClassic:
|
||||
case eIntID_WindowsDefaultTheme:
|
||||
case eIntID_TouchEnabled:
|
||||
aResult = 0;
|
||||
res = NS_ERROR_NOT_IMPLEMENTED;
|
||||
break;
|
||||
case eIntID_MacGraphiteTheme:
|
||||
aResult = 0;
|
||||
break;
|
||||
case eIntID_TabFocusModel:
|
||||
aResult = 1; // default to just textboxes
|
||||
break;
|
||||
case eIntID_ScrollToClick:
|
||||
aResult = 0;
|
||||
break;
|
||||
case eIntID_ChosenMenuItemsShouldBlink:
|
||||
aResult = 1;
|
||||
break;
|
||||
case eIntID_IMERawInputUnderlineStyle:
|
||||
case eIntID_IMEConvertedTextUnderlineStyle:
|
||||
case eIntID_IMESelectedRawTextUnderlineStyle:
|
||||
case eIntID_IMESelectedConvertedTextUnderline:
|
||||
aResult = NS_STYLE_TEXT_DECORATION_STYLE_SOLID;
|
||||
break;
|
||||
case eIntID_SpellCheckerUnderlineStyle:
|
||||
aResult = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED;
|
||||
break;
|
||||
default:
|
||||
aResult = 0;
|
||||
res = NS_ERROR_FAILURE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLookAndFeel::GetFloatImpl(FloatID aID, float &aResult)
|
||||
{
|
||||
nsresult res = nsXPLookAndFeel::GetFloatImpl(aID, aResult);
|
||||
if (NS_SUCCEEDED(res))
|
||||
return res;
|
||||
res = NS_OK;
|
||||
|
||||
switch (aID) {
|
||||
case eFloatID_IMEUnderlineRelativeSize:
|
||||
aResult = 2.0f;
|
||||
break;
|
||||
case eFloatID_SpellCheckerUnderlineRelativeSize:
|
||||
aResult = 2.0f;
|
||||
break;
|
||||
default:
|
||||
aResult = -1.0;
|
||||
res = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
nsLookAndFeel::GetFontImpl(FontID aID, nsString &aFontName,
|
||||
gfxFontStyle &aFontStyle,
|
||||
float aDevPixPerCSSPixel)
|
||||
{
|
||||
// hack for now
|
||||
if (aID == eFont_Window || aID == eFont_Document) {
|
||||
aFontStyle.style = NS_FONT_STYLE_NORMAL;
|
||||
aFontStyle.weight = NS_FONT_WEIGHT_NORMAL;
|
||||
aFontStyle.stretch = NS_FONT_STRETCH_NORMAL;
|
||||
aFontStyle.size = 14 * aDevPixPerCSSPixel;
|
||||
aFontStyle.systemFont = true;
|
||||
|
||||
aFontName.AssignLiteral("sans-serif");
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO: implement more here?
|
||||
return false;
|
||||
}
|
56
widget/uikit/nsScreenManager.h
Normal file
56
widget/uikit/nsScreenManager.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 nsScreenManager_h_
|
||||
#define nsScreenManager_h_
|
||||
|
||||
#include "nsBaseScreen.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
@class UIScreen;
|
||||
|
||||
class UIKitScreen : public nsBaseScreen
|
||||
{
|
||||
public:
|
||||
explicit UIKitScreen (UIScreen* screen);
|
||||
~UIKitScreen () {}
|
||||
|
||||
NS_IMETHOD GetId(uint32_t* outId) {
|
||||
*outId = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetAvailRect(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetRectDisplayPix(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetAvailRectDisplayPix(int32_t* aLeft, int32_t* aTop, int32_t* aWidth, int32_t* aHeight);
|
||||
NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth);
|
||||
NS_IMETHOD GetColorDepth(int32_t* aColorDepth);
|
||||
NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor);
|
||||
|
||||
private:
|
||||
UIScreen* mScreen;
|
||||
};
|
||||
|
||||
class UIKitScreenManager : public nsIScreenManager
|
||||
{
|
||||
public:
|
||||
UIKitScreenManager ();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_DECL_NSISCREENMANAGER
|
||||
|
||||
static nsIntRect GetBounds();
|
||||
|
||||
private:
|
||||
virtual ~UIKitScreenManager () {}
|
||||
//TODO: support >1 screen, iPad supports external displays
|
||||
nsCOMPtr<nsIScreen> mScreen;
|
||||
};
|
||||
|
||||
#endif // nsScreenManager_h_
|
146
widget/uikit/nsScreenManager.mm
Normal file
146
widget/uikit/nsScreenManager.mm
Normal file
@ -0,0 +1,146 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#import <UIKit/UIScreen.h>
|
||||
|
||||
#include "gfxPoint.h"
|
||||
#include "nsScreenManager.h"
|
||||
#include "nsAppShell.h"
|
||||
|
||||
static nsIntRect gScreenBounds;
|
||||
static bool gScreenBoundsSet = false;
|
||||
|
||||
UIKitScreen::UIKitScreen(UIScreen* aScreen)
|
||||
{
|
||||
mScreen = [aScreen retain];
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreen::GetRect(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
|
||||
{
|
||||
return GetRectDisplayPix(outX, outY, outWidth, outHeight);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreen::GetAvailRect(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
|
||||
{
|
||||
return GetAvailRectDisplayPix(outX, outY, outWidth, outHeight);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreen::GetRectDisplayPix(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
|
||||
{
|
||||
nsIntRect rect = UIKitScreenManager::GetBounds();
|
||||
*outX = rect.x;
|
||||
*outY = rect.y;
|
||||
*outWidth = rect.width;
|
||||
*outHeight = rect.height;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreen::GetAvailRectDisplayPix(int32_t *outX, int32_t *outY, int32_t *outWidth, int32_t *outHeight)
|
||||
{
|
||||
CGRect rect = [mScreen applicationFrame];
|
||||
CGFloat scale = [mScreen scale];
|
||||
|
||||
*outX = rect.origin.x * scale;
|
||||
*outY = rect.origin.y * scale;
|
||||
*outWidth = rect.size.width * scale;
|
||||
*outHeight = rect.size.height * scale;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreen::GetPixelDepth(int32_t *aPixelDepth)
|
||||
{
|
||||
// Close enough.
|
||||
*aPixelDepth = 24;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreen::GetColorDepth(int32_t *aColorDepth)
|
||||
{
|
||||
return GetPixelDepth(aColorDepth);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreen::GetContentsScaleFactor(double* aContentsScaleFactor)
|
||||
{
|
||||
*aContentsScaleFactor = [mScreen scale];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(UIKitScreenManager, nsIScreenManager)
|
||||
|
||||
UIKitScreenManager::UIKitScreenManager()
|
||||
: mScreen(new UIKitScreen([UIScreen mainScreen]))
|
||||
{
|
||||
}
|
||||
|
||||
nsIntRect
|
||||
UIKitScreenManager::GetBounds()
|
||||
{
|
||||
if (!gScreenBoundsSet) {
|
||||
CGRect rect = [[UIScreen mainScreen] bounds];
|
||||
CGFloat scale = [[UIScreen mainScreen] scale];
|
||||
gScreenBounds.x = rect.origin.x * scale;
|
||||
gScreenBounds.y = rect.origin.y * scale;
|
||||
gScreenBounds.width = rect.size.width * scale;
|
||||
gScreenBounds.height = rect.size.height * scale;
|
||||
gScreenBoundsSet = true;
|
||||
}
|
||||
printf("UIKitScreenManager::GetBounds: %d %d %d %d\n",
|
||||
gScreenBounds.x, gScreenBounds.y, gScreenBounds.width, gScreenBounds.height);
|
||||
return gScreenBounds;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreenManager::GetPrimaryScreen(nsIScreen** outScreen)
|
||||
{
|
||||
NS_IF_ADDREF(*outScreen = mScreen.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreenManager::ScreenForRect(int32_t inLeft,
|
||||
int32_t inTop,
|
||||
int32_t inWidth,
|
||||
int32_t inHeight,
|
||||
nsIScreen** outScreen)
|
||||
{
|
||||
return GetPrimaryScreen(outScreen);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreenManager::ScreenForId(uint32_t id,
|
||||
nsIScreen** outScreen)
|
||||
{
|
||||
return GetPrimaryScreen(outScreen);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreenManager::ScreenForNativeWidget(void* aWidget, nsIScreen** outScreen)
|
||||
{
|
||||
return GetPrimaryScreen(outScreen);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreenManager::GetNumberOfScreens(uint32_t* aNumberOfScreens)
|
||||
{
|
||||
//TODO: support multiple screens
|
||||
*aNumberOfScreens = 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UIKitScreenManager::GetSystemDefaultScale(float* aScale)
|
||||
{
|
||||
*aScale = [UIScreen mainScreen].scale;
|
||||
return NS_OK;
|
||||
}
|
71
widget/uikit/nsWidgetFactory.mm
Normal file
71
widget/uikit/nsWidgetFactory.mm
Normal file
@ -0,0 +1,71 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nsIFactory.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
|
||||
#include "nsWidgetsCID.h"
|
||||
|
||||
#include "nsAppShell.h"
|
||||
#include "nsAppShellSingleton.h"
|
||||
#include "nsLookAndFeel.h"
|
||||
#include "nsScreenManager.h"
|
||||
#include "nsWindow.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(UIKitScreenManager)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
|
||||
|
||||
#include "GfxInfo.h"
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
// This constructor should really be shared with all platforms.
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init)
|
||||
}
|
||||
}
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_WINDOW_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CHILD_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SCREENMANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor },
|
||||
{ &kNS_CHILD_CID, false, nullptr, nsWindowConstructor },
|
||||
{ &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, nullptr, UIKitScreenManagerConstructor },
|
||||
{ &kNS_GFXINFO_CID, false, nullptr, mozilla::widget::GfxInfoConstructor },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{ "@mozilla.org/widgets/window/uikit;1", &kNS_WINDOW_CID },
|
||||
{ "@mozilla.org/widgets/childwindow/uikit;1", &kNS_CHILD_CID },
|
||||
{ "@mozilla.org/widget/appshell/uikit;1", &kNS_APPSHELL_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID },
|
||||
{ "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
static void
|
||||
nsWidgetUIKitModuleDtor()
|
||||
{
|
||||
nsLookAndFeel::Shutdown();
|
||||
nsAppShellShutdown();
|
||||
}
|
||||
|
||||
static const mozilla::Module kWidgetModule = {
|
||||
mozilla::Module::kVersion,
|
||||
kWidgetCIDs,
|
||||
kWidgetContracts,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nsAppShellInit,
|
||||
nsWidgetUIKitModuleDtor
|
||||
};
|
||||
|
||||
NSMODULE_DEFN(nsWidgetUIKitModule) = &kWidgetModule;
|
136
widget/uikit/nsWindow.h
Normal file
136
widget/uikit/nsWindow.h
Normal file
@ -0,0 +1,136 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 NSWINDOW_H_
|
||||
#define NSWINDOW_H_
|
||||
|
||||
#include "nsBaseWidget.h"
|
||||
#include "gfxPoint.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
@class UIWindow;
|
||||
@class UIView;
|
||||
@class ChildView;
|
||||
class gfxASurface;
|
||||
|
||||
class nsWindow :
|
||||
public nsBaseWidget
|
||||
{
|
||||
typedef nsBaseWidget Inherited;
|
||||
|
||||
public:
|
||||
nsWindow();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
//
|
||||
// nsIWidget
|
||||
//
|
||||
|
||||
NS_IMETHOD Create(nsIWidget *aParent,
|
||||
nsNativeWidget aNativeParent,
|
||||
const nsIntRect &aRect,
|
||||
nsWidgetInitData *aInitData = nullptr) override;
|
||||
NS_IMETHOD Destroy() override;
|
||||
NS_IMETHOD Show(bool aState) override;
|
||||
NS_IMETHOD Enable(bool aState) override {
|
||||
return NS_OK;
|
||||
}
|
||||
virtual bool IsEnabled() const override {
|
||||
return true;
|
||||
}
|
||||
NS_IMETHOD SetModal(bool aState) override;
|
||||
virtual bool IsVisible() const override {
|
||||
return mVisible;
|
||||
}
|
||||
NS_IMETHOD SetFocus(bool aState=false) override;
|
||||
virtual mozilla::LayoutDeviceIntPoint WidgetToScreenOffset() override;
|
||||
|
||||
virtual void SetBackgroundColor(const nscolor &aColor) override;
|
||||
virtual void* GetNativeData(uint32_t aDataType) override;
|
||||
|
||||
NS_IMETHOD ConstrainPosition(bool aAllowSlop,
|
||||
int32_t *aX, int32_t *aY) override;
|
||||
NS_IMETHOD Move(double aX, double aY) override;
|
||||
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
|
||||
nsIWidget *aWidget, bool aActivate) override;
|
||||
NS_IMETHOD SetSizeMode(int32_t aMode) override;
|
||||
void EnteredFullScreen(bool aFullScreen);
|
||||
NS_IMETHOD Resize(double aWidth, double aHeight, bool aRepaint) override;
|
||||
NS_IMETHOD Resize(double aX, double aY, double aWidth, double aHeight, bool aRepaint) override;
|
||||
NS_IMETHOD GetScreenBounds(nsIntRect &aRect) override;
|
||||
void ReportMoveEvent();
|
||||
void ReportSizeEvent();
|
||||
void ReportSizeModeEvent(int32_t aMode);
|
||||
|
||||
CGFloat BackingScaleFactor();
|
||||
void BackingScaleFactorChanged();
|
||||
virtual float GetDPI() override {
|
||||
//XXX: terrible
|
||||
return 326.0f;
|
||||
}
|
||||
virtual double GetDefaultScaleInternal() override {
|
||||
return BackingScaleFactor();
|
||||
}
|
||||
virtual int32_t RoundsWidgetCoordinatesTo() override;
|
||||
|
||||
NS_IMETHOD SetTitle(const nsAString& aTitle) override {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD Invalidate(const nsIntRect &aRect) override;
|
||||
virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations) override;
|
||||
NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
|
||||
nsEventStatus& aStatus) override;
|
||||
NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener,
|
||||
bool aDoCapture) override {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void WillPaintWindow();
|
||||
bool PaintWindow(nsIntRegion aRegion);
|
||||
|
||||
bool HasModalDescendents() { return false; }
|
||||
|
||||
//NS_IMETHOD NotifyIME(const IMENotification& aIMENotification) override;
|
||||
NS_IMETHOD_(void) SetInputContext(
|
||||
const InputContext& aContext,
|
||||
const InputContextAction& aAction);
|
||||
NS_IMETHOD_(InputContext) GetInputContext();
|
||||
/*
|
||||
NS_IMETHOD_(bool) ExecuteNativeKeyBinding(
|
||||
NativeKeyBindingsType aType,
|
||||
const mozilla::WidgetKeyboardEvent& aEvent,
|
||||
DoCommandCallback aCallback,
|
||||
void* aCallbackData) override;
|
||||
*/
|
||||
|
||||
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsWindow();
|
||||
void BringToFront();
|
||||
nsWindow *FindTopLevel();
|
||||
bool IsTopLevel();
|
||||
nsresult GetCurrentOffset(uint32_t &aOffset, uint32_t &aLength);
|
||||
nsresult DeleteRange(int aOffset, int aLen);
|
||||
|
||||
void TearDownView();
|
||||
|
||||
ChildView* mNativeView;
|
||||
bool mVisible;
|
||||
nsTArray<nsWindow*> mChildren;
|
||||
nsWindow* mParent;
|
||||
InputContext mInputContext;
|
||||
|
||||
void OnSizeChanged(const gfxIntSize& aSize);
|
||||
|
||||
static void DumpWindows();
|
||||
static void DumpWindows(const nsTArray<nsWindow*>& wins, int indent = 0);
|
||||
static void LogWindow(nsWindow *win, int index, int indent);
|
||||
};
|
||||
|
||||
#endif /* NSWINDOW_H_ */
|
901
widget/uikit/nsWindow.mm
Normal file
901
widget/uikit/nsWindow.mm
Normal file
@ -0,0 +1,901 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#import <UIKit/UIEvent.h>
|
||||
#import <UIKit/UIGraphics.h>
|
||||
#import <UIKit/UIInterface.h>
|
||||
#import <UIKit/UIScreen.h>
|
||||
#import <UIKit/UITapGestureRecognizer.h>
|
||||
#import <UIKit/UITouch.h>
|
||||
#import <UIKit/UIView.h>
|
||||
#import <UIKit/UIViewController.h>
|
||||
#import <UIKit/UIWindow.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "nsWindow.h"
|
||||
#include "nsScreenManager.h"
|
||||
#include "nsAppShell.h"
|
||||
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "gfxQuartzSurface.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsRegion.h"
|
||||
#include "Layers.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "mozilla/BasicEvents.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
#define ALOG(args...) fprintf(stderr, args); fprintf(stderr, "\n")
|
||||
|
||||
static LayoutDeviceIntPoint
|
||||
UIKitPointsToDevPixels(CGPoint aPoint, CGFloat aBackingScale)
|
||||
{
|
||||
return LayoutDeviceIntPoint(NSToIntRound(aPoint.x * aBackingScale),
|
||||
NSToIntRound(aPoint.y * aBackingScale));
|
||||
}
|
||||
|
||||
static CGRect
|
||||
DevPixelsToUIKitPoints(const nsIntRect& aRect, CGFloat aBackingScale)
|
||||
{
|
||||
return CGRectMake((CGFloat)aRect.x / aBackingScale,
|
||||
(CGFloat)aRect.y / aBackingScale,
|
||||
(CGFloat)aRect.width / aBackingScale,
|
||||
(CGFloat)aRect.height / aBackingScale);
|
||||
}
|
||||
|
||||
// Used to retain a Cocoa object for the remainder of a method's execution.
|
||||
class nsAutoRetainUIKitObject {
|
||||
public:
|
||||
nsAutoRetainUIKitObject(id anObject)
|
||||
{
|
||||
mObject = [anObject retain];
|
||||
}
|
||||
~nsAutoRetainUIKitObject()
|
||||
{
|
||||
[mObject release];
|
||||
}
|
||||
private:
|
||||
id mObject; // [STRONG]
|
||||
};
|
||||
|
||||
@interface ChildView : UIView
|
||||
{
|
||||
@public
|
||||
nsWindow* mGeckoChild; // weak ref
|
||||
BOOL mWaitingForPaint;
|
||||
CFMutableDictionaryRef mTouches;
|
||||
int mNextTouchID;
|
||||
}
|
||||
// sets up our view, attaching it to its owning gecko view
|
||||
- (id)initWithFrame:(CGRect)inFrame geckoChild:(nsWindow*)inChild;
|
||||
// Our Gecko child was Destroy()ed
|
||||
- (void)widgetDestroyed;
|
||||
// Tear down this ChildView
|
||||
- (void)delayedTearDown;
|
||||
- (void)sendMouseEvent:(int) aType point:(LayoutDeviceIntPoint)aPoint widget:(nsWindow*)aWindow;
|
||||
- (void)handleTap:(UITapGestureRecognizer *)sender;
|
||||
- (BOOL)isUsingMainThreadOpenGL;
|
||||
- (void)drawUsingOpenGL;
|
||||
- (void)drawUsingOpenGLCallback;
|
||||
- (void)sendTouchEvent:(int) aType touches:(NSSet*)aTouches widget:(nsWindow*)aWindow;
|
||||
// Event handling (UIResponder)
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
|
||||
@end
|
||||
|
||||
@implementation ChildView
|
||||
+ (Class)layerClass {
|
||||
return [CAEAGLLayer class];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)inFrame geckoChild:(nsWindow*)inChild
|
||||
{
|
||||
self.multipleTouchEnabled = YES;
|
||||
if ((self = [super initWithFrame:inFrame])) {
|
||||
mGeckoChild = inChild;
|
||||
}
|
||||
ALOG("[ChildView[%p] initWithFrame:] (mGeckoChild = %p)", (void*)self, (void*)mGeckoChild);
|
||||
self.opaque = YES;
|
||||
self.alpha = 1.0;
|
||||
|
||||
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
|
||||
initWithTarget:self action:@selector(handleTap:)];
|
||||
tapRecognizer.numberOfTapsRequired = 1;
|
||||
[self addGestureRecognizer:tapRecognizer];
|
||||
|
||||
mTouches = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
|
||||
mNextTouchID = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)widgetDestroyed
|
||||
{
|
||||
mGeckoChild = nullptr;
|
||||
CFRelease(mTouches);
|
||||
}
|
||||
|
||||
- (void)delayedTearDown
|
||||
{
|
||||
[self removeFromSuperview];
|
||||
[self release];
|
||||
}
|
||||
|
||||
- (void)sendMouseEvent:(int) aType point:(LayoutDeviceIntPoint)aPoint widget:(nsWindow*)aWindow
|
||||
{
|
||||
WidgetMouseEvent event(true, aType, aWindow,
|
||||
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
|
||||
|
||||
event.refPoint = aPoint;
|
||||
event.clickCount = 1;
|
||||
event.button = WidgetMouseEvent::eLeftButton;
|
||||
event.time = PR_IntervalNow();
|
||||
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
||||
|
||||
nsEventStatus status;
|
||||
aWindow->DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
- (void)handleTap:(UITapGestureRecognizer *)sender
|
||||
{
|
||||
if (sender.state == UIGestureRecognizerStateEnded) {
|
||||
ALOG("[ChildView[%p] handleTap]", self);
|
||||
LayoutDeviceIntPoint lp = UIKitPointsToDevPixels([sender locationInView:self], [self contentScaleFactor]);
|
||||
[self sendMouseEvent:NS_MOUSE_MOVE point:lp widget:mGeckoChild];
|
||||
[self sendMouseEvent:NS_MOUSE_BUTTON_DOWN point:lp widget:mGeckoChild];
|
||||
[self sendMouseEvent:NS_MOUSE_BUTTON_UP point:lp widget:mGeckoChild];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sendTouchEvent:(int) aType touches:(NSSet*)aTouches widget:(nsWindow*)aWindow
|
||||
{
|
||||
WidgetTouchEvent event(true, aType, aWindow);
|
||||
//XXX: I think nativeEvent.timestamp * 1000 is probably usable here but
|
||||
// I don't care that much right now.
|
||||
event.time = PR_IntervalNow();
|
||||
event.touches.SetCapacity(aTouches.count);
|
||||
for (UITouch* touch in aTouches) {
|
||||
LayoutDeviceIntPoint loc = UIKitPointsToDevPixels([touch locationInView:self], [self contentScaleFactor]);
|
||||
void* value;
|
||||
if (!CFDictionaryGetValueIfPresent(mTouches, touch, (const void**)&value)) {
|
||||
// This shouldn't happen.
|
||||
NS_ASSERTION(false, "Got a touch that we didn't know about");
|
||||
continue;
|
||||
}
|
||||
int id = reinterpret_cast<int>(value);
|
||||
nsRefPtr<Touch> t = new Touch(id,
|
||||
loc,
|
||||
nsIntPoint([touch majorRadius], [touch majorRadius]),
|
||||
0.0f,
|
||||
1.0f);
|
||||
event.refPoint = loc;
|
||||
event.touches.AppendElement(t);
|
||||
}
|
||||
aWindow->DispatchAPZAwareEvent(&event);
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
ALOG("[ChildView[%p] touchesBegan", self);
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
for (UITouch* touch : touches) {
|
||||
CFDictionaryAddValue(mTouches, touch, (void*)mNextTouchID);
|
||||
mNextTouchID++;
|
||||
}
|
||||
[self sendTouchEvent:NS_TOUCH_START touches:[event allTouches] widget:mGeckoChild];
|
||||
}
|
||||
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
ALOG("[ChildView[%p] touchesCancelled", self);
|
||||
[self sendTouchEvent:NS_TOUCH_CANCEL touches:touches widget:mGeckoChild];
|
||||
for (UITouch* touch : touches) {
|
||||
CFDictionaryRemoveValue(mTouches, touch);
|
||||
}
|
||||
if (CFDictionaryGetCount(mTouches) == 0) {
|
||||
mNextTouchID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
ALOG("[ChildView[%p] touchesEnded", self);
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
[self sendTouchEvent:NS_TOUCH_END touches:touches widget:mGeckoChild];
|
||||
for (UITouch* touch : touches) {
|
||||
CFDictionaryRemoveValue(mTouches, touch);
|
||||
}
|
||||
if (CFDictionaryGetCount(mTouches) == 0) {
|
||||
mNextTouchID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
ALOG("[ChildView[%p] touchesMoved", self);
|
||||
if (!mGeckoChild)
|
||||
return;
|
||||
|
||||
[self sendTouchEvent:NS_TOUCH_MOVE touches:[event allTouches] widget:mGeckoChild];
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplayInRect:(CGRect)aRect
|
||||
{
|
||||
if ([self isUsingMainThreadOpenGL]) {
|
||||
// Draw without calling drawRect. This prevent us from
|
||||
// needing to access the normal window buffer surface unnecessarily, so we
|
||||
// waste less time synchronizing the two surfaces.
|
||||
if (!mWaitingForPaint) {
|
||||
mWaitingForPaint = YES;
|
||||
// Use NSRunLoopCommonModes instead of the default NSDefaultRunLoopMode
|
||||
// so that the timer also fires while a native menu is open.
|
||||
[self performSelector:@selector(drawUsingOpenGLCallback)
|
||||
withObject:nil
|
||||
afterDelay:0
|
||||
inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isUsingMainThreadOpenGL
|
||||
{
|
||||
if (!mGeckoChild || ![self window])
|
||||
return NO;
|
||||
|
||||
return mGeckoChild->GetLayerManager(nullptr)->GetBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL;
|
||||
}
|
||||
|
||||
- (void)drawUsingOpenGL
|
||||
{
|
||||
ALOG("drawUsingOpenGL");
|
||||
PROFILER_LABEL("ChildView", "drawUsingOpenGL",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
|
||||
if (!mGeckoChild->IsVisible())
|
||||
return;
|
||||
|
||||
mWaitingForPaint = NO;
|
||||
|
||||
nsIntRect geckoBounds;
|
||||
mGeckoChild->GetBounds(geckoBounds);
|
||||
nsIntRegion region(geckoBounds);
|
||||
|
||||
mGeckoChild->PaintWindow(region);
|
||||
}
|
||||
|
||||
// Called asynchronously after setNeedsDisplay in order to avoid entering the
|
||||
// normal drawing machinery.
|
||||
- (void)drawUsingOpenGLCallback
|
||||
{
|
||||
if (mWaitingForPaint) {
|
||||
[self drawUsingOpenGL];
|
||||
}
|
||||
}
|
||||
|
||||
// The display system has told us that a portion of our view is dirty. Tell
|
||||
// gecko to paint it
|
||||
- (void)drawRect:(CGRect)aRect
|
||||
{
|
||||
CGContextRef cgContext = UIGraphicsGetCurrentContext();
|
||||
[self drawRect:aRect inContext:cgContext];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)aRect inContext:(CGContextRef)aContext
|
||||
{
|
||||
#ifdef DEBUG_UPDATE
|
||||
nsIntRect geckoBounds;
|
||||
mGeckoChild->GetBounds(geckoBounds);
|
||||
|
||||
fprintf (stderr, "---- Update[%p][%p] [%f %f %f %f] cgc: %p\n gecko bounds: [%d %d %d %d]\n",
|
||||
self, mGeckoChild,
|
||||
aRect.origin.x, aRect.origin.y, aRect.size.width, aRect.size.height, aContext,
|
||||
geckoBounds.x, geckoBounds.y, geckoBounds.width, geckoBounds.height);
|
||||
|
||||
CGAffineTransform xform = CGContextGetCTM(aContext);
|
||||
fprintf (stderr, " xform in: [%f %f %f %f %f %f]\n", xform.a, xform.b, xform.c, xform.d, xform.tx, xform.ty);
|
||||
#endif
|
||||
|
||||
if (true) {
|
||||
// For Gecko-initiated repaints in OpenGL mode, drawUsingOpenGL is
|
||||
// directly called from a delayed perform callback - without going through
|
||||
// drawRect.
|
||||
// Paints that come through here are triggered by something that Cocoa
|
||||
// controls, for example by window resizing or window focus changes.
|
||||
|
||||
// Do GL composition and return.
|
||||
[self drawUsingOpenGL];
|
||||
return;
|
||||
}
|
||||
PROFILER_LABEL("ChildView", "drawRect",
|
||||
js::ProfileEntry::Category::GRAPHICS);
|
||||
|
||||
// The CGContext that drawRect supplies us with comes with a transform that
|
||||
// scales one user space unit to one Cocoa point, which can consist of
|
||||
// multiple dev pixels. But Gecko expects its supplied context to be scaled
|
||||
// to device pixels, so we need to reverse the scaling.
|
||||
double scale = mGeckoChild->BackingScaleFactor();
|
||||
CGContextSaveGState(aContext);
|
||||
CGContextScaleCTM(aContext, 1.0 / scale, 1.0 / scale);
|
||||
|
||||
CGSize viewSize = [self bounds].size;
|
||||
nsIntSize backingSize(viewSize.width * scale, viewSize.height * scale);
|
||||
|
||||
CGContextSaveGState(aContext);
|
||||
|
||||
nsIntRegion region = nsIntRect(NSToIntRound(aRect.origin.x * scale),
|
||||
NSToIntRound(aRect.origin.y * scale),
|
||||
NSToIntRound(aRect.size.width * scale),
|
||||
NSToIntRound(aRect.size.height * scale));
|
||||
|
||||
// Create Cairo objects.
|
||||
nsRefPtr<gfxQuartzSurface> targetSurface;
|
||||
|
||||
nsRefPtr<gfxContext> targetContext;
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(gfx::BackendType::COREGRAPHICS)) {
|
||||
RefPtr<gfx::DrawTarget> dt =
|
||||
gfx::Factory::CreateDrawTargetForCairoCGContext(aContext,
|
||||
gfx::IntSize(backingSize.width,
|
||||
backingSize.height));
|
||||
dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
|
||||
targetContext = new gfxContext(dt);
|
||||
} else if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(gfx::BackendType::CAIRO)) {
|
||||
// This is dead code unless you mess with prefs, but keep it around for
|
||||
// debugging.
|
||||
targetSurface = new gfxQuartzSurface(aContext, backingSize);
|
||||
targetSurface->SetAllowUseAsSource(false);
|
||||
RefPtr<gfx::DrawTarget> dt =
|
||||
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(targetSurface,
|
||||
gfx::IntSize(backingSize.width,
|
||||
backingSize.height));
|
||||
dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
|
||||
targetContext = new gfxContext(dt);
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE("COREGRAPHICS is the only supported backed");
|
||||
}
|
||||
|
||||
// Set up the clip region.
|
||||
nsIntRegionRectIterator iter(region);
|
||||
targetContext->NewPath();
|
||||
for (;;) {
|
||||
const nsIntRect* r = iter.Next();
|
||||
if (!r)
|
||||
break;
|
||||
targetContext->Rectangle(gfxRect(r->x, r->y, r->width, r->height));
|
||||
}
|
||||
targetContext->Clip();
|
||||
|
||||
//nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
bool painted = false;
|
||||
if (mGeckoChild->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
|
||||
nsBaseWidget::AutoLayerManagerSetup
|
||||
setupLayerManager(mGeckoChild, targetContext, BufferMode::BUFFER_NONE);
|
||||
painted = mGeckoChild->PaintWindow(region);
|
||||
} else if (mGeckoChild->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
|
||||
// We only need this so that we actually get DidPaintWindow fired
|
||||
painted = mGeckoChild->PaintWindow(region);
|
||||
}
|
||||
|
||||
targetContext = nullptr;
|
||||
targetSurface = nullptr;
|
||||
|
||||
CGContextRestoreGState(aContext);
|
||||
|
||||
// Undo the scale transform so that from now on the context is in
|
||||
// CocoaPoints again.
|
||||
CGContextRestoreGState(aContext);
|
||||
if (!painted && [self isOpaque]) {
|
||||
// Gecko refused to draw, but we've claimed to be opaque, so we have to
|
||||
// draw something--fill with white.
|
||||
CGContextSetRGBFillColor(aContext, 1, 1, 1, 1);
|
||||
CGContextFillRect(aContext, aRect);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UPDATE
|
||||
fprintf (stderr, "---- update done ----\n");
|
||||
|
||||
#if 0
|
||||
CGContextSetRGBStrokeColor (aContext,
|
||||
((((unsigned long)self) & 0xff)) / 255.0,
|
||||
((((unsigned long)self) & 0xff00) >> 8) / 255.0,
|
||||
((((unsigned long)self) & 0xff0000) >> 16) / 255.0,
|
||||
0.5);
|
||||
#endif
|
||||
CGContextSetRGBStrokeColor(aContext, 1, 0, 0, 0.8);
|
||||
CGContextSetLineWidth(aContext, 4.0);
|
||||
CGContextStrokeRect(aContext, aRect);
|
||||
#endif
|
||||
}
|
||||
@end
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, Inherited)
|
||||
|
||||
nsWindow::nsWindow()
|
||||
: mNativeView(nullptr),
|
||||
mVisible(false),
|
||||
mParent(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsWindow::~nsWindow()
|
||||
{
|
||||
[mNativeView widgetDestroyed]; // Safe if mNativeView is nil.
|
||||
TearDownView(); // Safe if called twice.
|
||||
}
|
||||
|
||||
void nsWindow::TearDownView()
|
||||
{
|
||||
if (!mNativeView)
|
||||
return;
|
||||
|
||||
[mNativeView performSelectorOnMainThread:@selector(delayedTearDown) withObject:nil waitUntilDone:false];
|
||||
mNativeView = nil;
|
||||
}
|
||||
|
||||
bool
|
||||
nsWindow::IsTopLevel()
|
||||
{
|
||||
return mWindowType == eWindowType_toplevel ||
|
||||
mWindowType == eWindowType_dialog ||
|
||||
mWindowType == eWindowType_invisible;
|
||||
}
|
||||
|
||||
//
|
||||
// nsIWidget
|
||||
//
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Create(nsIWidget *aParent,
|
||||
nsNativeWidget aNativeParent,
|
||||
const nsIntRect &aRect,
|
||||
nsWidgetInitData *aInitData)
|
||||
{
|
||||
ALOG("nsWindow[%p]::Create %p/%p [%d %d %d %d]", (void*)this, (void*)aParent, (void*)aNativeParent, aRect.x, aRect.y, aRect.width, aRect.height);
|
||||
nsWindow* parent = (nsWindow*) aParent;
|
||||
ChildView* nativeParent = (ChildView*)aNativeParent;
|
||||
|
||||
if (parent == nullptr && nativeParent)
|
||||
parent = nativeParent->mGeckoChild;
|
||||
if (parent && nativeParent == nullptr)
|
||||
nativeParent = parent->mNativeView;
|
||||
|
||||
// for toplevel windows, bounds are fixed to full screen size
|
||||
if (parent == nullptr) {
|
||||
if (nsAppShell::gWindow == nil) {
|
||||
mBounds = UIKitScreenManager::GetBounds();
|
||||
}
|
||||
else {
|
||||
CGRect cgRect = [nsAppShell::gWindow bounds];
|
||||
mBounds.x = cgRect.origin.x;
|
||||
mBounds.y = cgRect.origin.y;
|
||||
mBounds.width = cgRect.size.width;
|
||||
mBounds.height = cgRect.size.height;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mBounds = aRect;
|
||||
}
|
||||
|
||||
ALOG("nsWindow[%p]::Create bounds: %d %d %d %d", (void*)this,
|
||||
mBounds.x, mBounds.y, mBounds.width, mBounds.height);
|
||||
|
||||
// Set defaults which can be overriden from aInitData in BaseCreate
|
||||
mWindowType = eWindowType_toplevel;
|
||||
mBorderStyle = eBorderStyle_default;
|
||||
|
||||
Inherited::BaseCreate(aParent, mBounds, aInitData);
|
||||
|
||||
NS_ASSERTION(IsTopLevel() || parent, "non top level window doesn't have a parent!");
|
||||
|
||||
mNativeView = [[ChildView alloc] initWithFrame:DevPixelsToUIKitPoints(mBounds, BackingScaleFactor()) geckoChild:this];
|
||||
mNativeView.hidden = YES;
|
||||
|
||||
if (parent) {
|
||||
parent->mChildren.AppendElement(this);
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
if (nativeParent) {
|
||||
[nativeParent addSubview:mNativeView];
|
||||
} else if (nsAppShell::gWindow) {
|
||||
[nsAppShell::gWindow.rootViewController.view addSubview:mNativeView];
|
||||
}
|
||||
else {
|
||||
[nsAppShell::gTopLevelViews addObject:mNativeView];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Destroy(void)
|
||||
{
|
||||
for (uint32_t i = 0; i < mChildren.Length(); ++i) {
|
||||
// why do we still have children?
|
||||
mChildren[i]->SetParent(nullptr);
|
||||
}
|
||||
|
||||
if (mParent)
|
||||
mParent->mChildren.RemoveElement(this);
|
||||
|
||||
[mNativeView widgetDestroyed];
|
||||
|
||||
nsBaseWidget::Destroy();
|
||||
|
||||
//ReportDestroyEvent();
|
||||
|
||||
TearDownView();
|
||||
|
||||
nsBaseWidget::OnDestroy();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::ConfigureChildren(const nsTArray<nsIWidget::Configuration>& config)
|
||||
{
|
||||
for (uint32_t i = 0; i < config.Length(); ++i) {
|
||||
nsWindow *childWin = (nsWindow*) config[i].mChild.get();
|
||||
childWin->Resize(config[i].mBounds.x,
|
||||
config[i].mBounds.y,
|
||||
config[i].mBounds.width,
|
||||
config[i].mBounds.height,
|
||||
false);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::ReparentNativeWidget(nsIWidget* aNewParent)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Show(bool aState)
|
||||
{
|
||||
if (aState != mVisible) {
|
||||
mNativeView.hidden = aState ? NO : YES;
|
||||
if (aState) {
|
||||
UIView* parentView = mParent ? mParent->mNativeView : nsAppShell::gWindow.rootViewController.view;
|
||||
[parentView bringSubviewToFront:mNativeView];
|
||||
[mNativeView setNeedsDisplay];
|
||||
}
|
||||
mVisible = aState;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::SetModal(bool aModal)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::ConstrainPosition(bool aAllowSlop,
|
||||
int32_t *aX,
|
||||
int32_t *aY)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Move(double aX, double aY)
|
||||
{
|
||||
if (!mNativeView || (mBounds.x == aX && mBounds.y == aY))
|
||||
return NS_OK;
|
||||
|
||||
//XXX: handle this
|
||||
// The point we have is in Gecko coordinates (origin top-left). Convert
|
||||
// it to Cocoa ones (origin bottom-left).
|
||||
mBounds.x = aX;
|
||||
mBounds.y = aY;
|
||||
|
||||
mNativeView.frame = DevPixelsToUIKitPoints(mBounds, BackingScaleFactor());
|
||||
|
||||
if (mVisible)
|
||||
[mNativeView setNeedsDisplay];
|
||||
|
||||
ReportMoveEvent();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Resize(double aX, double aY,
|
||||
double aWidth, double aHeight,
|
||||
bool aRepaint)
|
||||
{
|
||||
BOOL isMoving = (mBounds.x != aX || mBounds.y != aY);
|
||||
BOOL isResizing = (mBounds.width != aWidth || mBounds.height != aHeight);
|
||||
if (!mNativeView || (!isMoving && !isResizing))
|
||||
return NS_OK;
|
||||
|
||||
if (isMoving) {
|
||||
mBounds.x = aX;
|
||||
mBounds.y = aY;
|
||||
}
|
||||
if (isResizing) {
|
||||
mBounds.width = aWidth;
|
||||
mBounds.height = aHeight;
|
||||
}
|
||||
|
||||
[mNativeView setFrame:DevPixelsToUIKitPoints(mBounds, BackingScaleFactor())];
|
||||
|
||||
if (mVisible && aRepaint)
|
||||
[mNativeView setNeedsDisplay];
|
||||
|
||||
if (isMoving)
|
||||
ReportMoveEvent();
|
||||
|
||||
if (isResizing)
|
||||
ReportSizeEvent();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsWindow::Resize(double aWidth, double aHeight, bool aRepaint)
|
||||
{
|
||||
if (!mNativeView || (mBounds.width == aWidth && mBounds.height == aHeight))
|
||||
return NS_OK;
|
||||
|
||||
mBounds.width = aWidth;
|
||||
mBounds.height = aHeight;
|
||||
|
||||
[mNativeView setFrame:DevPixelsToUIKitPoints(mBounds, BackingScaleFactor())];
|
||||
|
||||
if (mVisible && aRepaint)
|
||||
[mNativeView setNeedsDisplay];
|
||||
|
||||
ReportSizeEvent();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
|
||||
nsIWidget *aWidget,
|
||||
bool aActivate)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::SetSizeMode(int32_t aMode)
|
||||
{
|
||||
if (aMode == static_cast<int32_t>(mSizeMode)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
mSizeMode = static_cast<nsSizeMode>(aMode);
|
||||
if (aMode == nsSizeMode_Maximized || aMode == nsSizeMode_Fullscreen) {
|
||||
// Resize to fill screen
|
||||
rv = nsBaseWidget::MakeFullScreen(true);
|
||||
}
|
||||
ReportSizeModeEvent(aMode);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::Invalidate(const nsIntRect &aRect)
|
||||
{
|
||||
if (!mNativeView || !mVisible)
|
||||
return NS_OK;
|
||||
|
||||
MOZ_RELEASE_ASSERT(GetLayerManager()->GetBackendType() != LayersBackend::LAYERS_CLIENT,
|
||||
"Shouldn't need to invalidate with accelerated OMTC layers!");
|
||||
|
||||
|
||||
[mNativeView setNeedsLayout];
|
||||
[mNativeView setNeedsDisplayInRect:DevPixelsToUIKitPoints(mBounds, BackingScaleFactor())];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::SetFocus(bool aRaise)
|
||||
{
|
||||
[[mNativeView window] makeKeyWindow];
|
||||
[mNativeView becomeFirstResponder];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsWindow::WillPaintWindow()
|
||||
{
|
||||
if (mWidgetListener) {
|
||||
mWidgetListener->WillPaintWindow(this);
|
||||
}
|
||||
}
|
||||
|
||||
bool nsWindow::PaintWindow(nsIntRegion aRegion)
|
||||
{
|
||||
if (!mWidgetListener)
|
||||
return false;
|
||||
|
||||
bool returnValue = false;
|
||||
returnValue = mWidgetListener->PaintWindow(this, aRegion);
|
||||
|
||||
if (mWidgetListener) {
|
||||
mWidgetListener->DidPaintWindow();
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void nsWindow::ReportMoveEvent()
|
||||
{
|
||||
NotifyWindowMoved(mBounds.x, mBounds.y);
|
||||
}
|
||||
|
||||
void nsWindow::ReportSizeModeEvent(int32_t aMode)
|
||||
{
|
||||
if (mWidgetListener) {
|
||||
// This is terrible.
|
||||
nsSizeMode theMode;
|
||||
switch (aMode) {
|
||||
case nsSizeMode_Maximized:
|
||||
theMode = nsSizeMode_Maximized;
|
||||
break;
|
||||
case nsSizeMode_Fullscreen:
|
||||
theMode = nsSizeMode_Fullscreen;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
mWidgetListener->SizeModeChanged(theMode);
|
||||
}
|
||||
}
|
||||
|
||||
void nsWindow::ReportSizeEvent()
|
||||
{
|
||||
if (mWidgetListener) {
|
||||
nsIntRect innerBounds;
|
||||
GetClientBounds(innerBounds);
|
||||
mWidgetListener->WindowResized(this, innerBounds.width, innerBounds.height);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::GetScreenBounds(nsIntRect &aRect)
|
||||
{
|
||||
LayoutDeviceIntPoint p = WidgetToScreenOffset();
|
||||
|
||||
aRect.x = p.x;
|
||||
aRect.y = p.y;
|
||||
aRect.width = mBounds.width;
|
||||
aRect.height = mBounds.height;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset()
|
||||
{
|
||||
LayoutDeviceIntPoint offset(0, 0);
|
||||
if (mParent) {
|
||||
offset = mParent->WidgetToScreenOffset();
|
||||
}
|
||||
|
||||
CGPoint temp = [mNativeView convertPoint:temp toView:nil];
|
||||
|
||||
if (!mParent && nsAppShell::gWindow) {
|
||||
// convert to screen coords
|
||||
temp = [nsAppShell::gWindow convertPoint:temp toWindow:nil];
|
||||
}
|
||||
|
||||
offset.x += temp.x;
|
||||
offset.y += temp.y;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindow::DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
|
||||
nsEventStatus& aStatus)
|
||||
{
|
||||
aStatus = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIWidget> kungFuDeathGrip = do_QueryInterface(aEvent->widget);
|
||||
|
||||
if (mWidgetListener)
|
||||
aStatus = mWidgetListener->HandleEvent(aEvent, mUseAttachedEvents);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsWindow::SetInputContext(const InputContext& aContext,
|
||||
const InputContextAction& aAction)
|
||||
{
|
||||
//TODO: actually show VKB
|
||||
mInputContext = aContext;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(mozilla::widget::InputContext)
|
||||
nsWindow::GetInputContext()
|
||||
{
|
||||
mInputContext.mNativeIMEContext = nullptr;
|
||||
return mInputContext;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::SetBackgroundColor(const nscolor &aColor)
|
||||
{
|
||||
mNativeView.backgroundColor = [UIColor colorWithRed:NS_GET_R(aColor)
|
||||
green:NS_GET_G(aColor)
|
||||
blue:NS_GET_B(aColor)
|
||||
alpha:NS_GET_A(aColor)];
|
||||
}
|
||||
|
||||
void* nsWindow::GetNativeData(uint32_t aDataType)
|
||||
{
|
||||
void* retVal = nullptr;
|
||||
|
||||
switch (aDataType)
|
||||
{
|
||||
case NS_NATIVE_WIDGET:
|
||||
case NS_NATIVE_DISPLAY:
|
||||
retVal = (void*)mNativeView;
|
||||
break;
|
||||
|
||||
case NS_NATIVE_WINDOW:
|
||||
retVal = [mNativeView window];
|
||||
break;
|
||||
|
||||
case NS_NATIVE_GRAPHIC:
|
||||
NS_ERROR("Requesting NS_NATIVE_GRAPHIC on a UIKit child view!");
|
||||
break;
|
||||
|
||||
case NS_NATIVE_OFFSETX:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
case NS_NATIVE_OFFSETY:
|
||||
retVal = 0;
|
||||
break;
|
||||
|
||||
case NS_NATIVE_PLUGIN_PORT:
|
||||
// not implemented
|
||||
break;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
CGFloat
|
||||
nsWindow::BackingScaleFactor()
|
||||
{
|
||||
if (mNativeView) {
|
||||
return [mNativeView contentScaleFactor];
|
||||
}
|
||||
return [UIScreen mainScreen].scale;
|
||||
}
|
||||
|
||||
int32_t
|
||||
nsWindow::RoundsWidgetCoordinatesTo()
|
||||
{
|
||||
if (BackingScaleFactor() == 2.0) {
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user