1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=8 et :
- */
- /* 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 "base/basictypes.h"
- #include "ClientLayerManager.h"
- #include "gfxPlatform.h"
- #include "mozilla/dom/TabChild.h"
- #include "mozilla/Hal.h"
- #include "mozilla/IMEStateManager.h"
- #include "mozilla/layers/APZChild.h"
- #include "mozilla/layers/PLayerTransactionChild.h"
- #include "mozilla/Preferences.h"
- #include "mozilla/TextComposition.h"
- #include "mozilla/TextEvents.h"
- #include "mozilla/Unused.h"
- #include "PuppetWidget.h"
- #include "nsContentUtils.h"
- #include "nsIWidgetListener.h"
- #include "imgIContainer.h"
- #include "nsView.h"
- using namespace mozilla;
- using namespace mozilla::dom;
- using namespace mozilla::hal;
- using namespace mozilla::gfx;
- using namespace mozilla::layers;
- using namespace mozilla::widget;
- static void
- InvalidateRegion(nsIWidget* aWidget, const LayoutDeviceIntRegion& aRegion)
- {
- for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) {
- aWidget->Invalidate(iter.Get());
- }
- }
- /*static*/ already_AddRefed<nsIWidget>
- nsIWidget::CreatePuppetWidget(TabChild* aTabChild)
- {
- MOZ_ASSERT(!aTabChild || nsIWidget::UsePuppetWidgets(),
- "PuppetWidgets not allowed in this configuration");
- nsCOMPtr<nsIWidget> widget = new PuppetWidget(aTabChild);
- return widget.forget();
- }
- namespace mozilla {
- namespace widget {
- static bool
- IsPopup(const nsWidgetInitData* aInitData)
- {
- return aInitData && aInitData->mWindowType == eWindowType_popup;
- }
- static bool
- MightNeedIMEFocus(const nsWidgetInitData* aInitData)
- {
- // In the puppet-widget world, popup widgets are just dummies and
- // shouldn't try to mess with IME state.
- #ifdef MOZ_CROSS_PROCESS_IME
- return !IsPopup(aInitData);
- #else
- return false;
- #endif
- }
- // Arbitrary, fungible.
- const size_t PuppetWidget::kMaxDimension = 4000;
- NS_IMPL_ISUPPORTS_INHERITED0(PuppetWidget, nsBaseWidget)
- PuppetWidget::PuppetWidget(TabChild* aTabChild)
- : mTabChild(aTabChild)
- , mMemoryPressureObserver(nullptr)
- , mDPI(-1)
- , mRounding(-1)
- , mDefaultScale(-1)
- , mCursorHotspotX(0)
- , mCursorHotspotY(0)
- , mNativeKeyCommandsValid(false)
- {
- MOZ_COUNT_CTOR(PuppetWidget);
- mSingleLineCommands.SetCapacity(4);
- mMultiLineCommands.SetCapacity(4);
- mRichTextCommands.SetCapacity(4);
- // Setting 'Unknown' means "not yet cached".
- mInputContext.mIMEState.mEnabled = IMEState::UNKNOWN;
- }
- PuppetWidget::~PuppetWidget()
- {
- MOZ_COUNT_DTOR(PuppetWidget);
- Destroy();
- }
- void
- PuppetWidget::InfallibleCreate(nsIWidget* aParent,
- nsNativeWidget aNativeParent,
- const LayoutDeviceIntRect& aRect,
- nsWidgetInitData* aInitData)
- {
- MOZ_ASSERT(!aNativeParent, "got a non-Puppet native parent");
- BaseCreate(nullptr, aInitData);
- mBounds = aRect;
- mEnabled = true;
- mVisible = true;
- mDrawTarget = gfxPlatform::GetPlatform()->
- CreateOffscreenContentDrawTarget(IntSize(1, 1), SurfaceFormat::B8G8R8A8);
- mNeedIMEStateInit = MightNeedIMEFocus(aInitData);
- PuppetWidget* parent = static_cast<PuppetWidget*>(aParent);
- if (parent) {
- parent->SetChild(this);
- mLayerManager = parent->GetLayerManager();
- }
- else {
- Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, false);
- }
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- mMemoryPressureObserver = new MemoryPressureObserver(this);
- obs->AddObserver(mMemoryPressureObserver, "memory-pressure", false);
- }
- }
- nsresult
- PuppetWidget::Create(nsIWidget* aParent,
- nsNativeWidget aNativeParent,
- const LayoutDeviceIntRect& aRect,
- nsWidgetInitData* aInitData)
- {
- InfallibleCreate(aParent, aNativeParent, aRect, aInitData);
- return NS_OK;
- }
- void
- PuppetWidget::InitIMEState()
- {
- MOZ_ASSERT(mTabChild);
- if (mNeedIMEStateInit) {
- mContentCache.Clear();
- mTabChild->SendUpdateContentCache(mContentCache);
- mIMEPreferenceOfParent = nsIMEUpdatePreference();
- mNeedIMEStateInit = false;
- }
- }
- already_AddRefed<nsIWidget>
- PuppetWidget::CreateChild(const LayoutDeviceIntRect& aRect,
- nsWidgetInitData* aInitData,
- bool aForceUseIWidgetParent)
- {
- bool isPopup = IsPopup(aInitData);
- nsCOMPtr<nsIWidget> widget = nsIWidget::CreatePuppetWidget(mTabChild);
- return ((widget &&
- NS_SUCCEEDED(widget->Create(isPopup ? nullptr: this, nullptr, aRect,
- aInitData))) ?
- widget.forget() : nullptr);
- }
- void
- PuppetWidget::Destroy()
- {
- if (mOnDestroyCalled) {
- return;
- }
- mOnDestroyCalled = true;
- Base::OnDestroy();
- Base::Destroy();
- mPaintTask.Revoke();
- if (mMemoryPressureObserver) {
- mMemoryPressureObserver->Remove();
- }
- mMemoryPressureObserver = nullptr;
- mChild = nullptr;
- if (mLayerManager) {
- mLayerManager->Destroy();
- }
- mLayerManager = nullptr;
- mTabChild = nullptr;
- }
- NS_IMETHODIMP
- PuppetWidget::Show(bool aState)
- {
- NS_ASSERTION(mEnabled,
- "does it make sense to Show()/Hide() a disabled widget?");
- bool wasVisible = mVisible;
- mVisible = aState;
- if (mChild) {
- mChild->mVisible = aState;
- }
- if (!wasVisible && mVisible) {
- // The previously attached widget listener is handy if
- // we're transitioning from page to page without dropping
- // layers (since we'll continue to show the old layers
- // associated with that old widget listener). If the
- // PuppetWidget was hidden, those layers are dropped,
- // so the previously attached widget listener is really
- // of no use anymore (and is actually actively harmful - see
- // bug 1323586).
- mPreviouslyAttachedWidgetListener = nullptr;
- Resize(mBounds.width, mBounds.height, false);
- Invalidate(mBounds);
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetWidget::Resize(double aWidth,
- double aHeight,
- bool aRepaint)
- {
- LayoutDeviceIntRect oldBounds = mBounds;
- mBounds.SizeTo(LayoutDeviceIntSize(NSToIntRound(aWidth),
- NSToIntRound(aHeight)));
- if (mChild) {
- return mChild->Resize(aWidth, aHeight, aRepaint);
- }
- // XXX: roc says that |aRepaint| dictates whether or not to
- // invalidate the expanded area
- if (oldBounds.Size() < mBounds.Size() && aRepaint) {
- LayoutDeviceIntRegion dirty(mBounds);
- dirty.Sub(dirty, oldBounds);
- InvalidateRegion(this, dirty);
- }
- // call WindowResized() on both the current listener, and possibly
- // also the previous one if we're in a state where we're drawing that one
- // because the current one is paint suppressed
- if (!oldBounds.IsEqualEdges(mBounds) && mAttachedWidgetListener) {
- if (GetCurrentWidgetListener() &&
- GetCurrentWidgetListener() != mAttachedWidgetListener) {
- GetCurrentWidgetListener()->WindowResized(this, mBounds.width, mBounds.height);
- }
- mAttachedWidgetListener->WindowResized(this, mBounds.width, mBounds.height);
- }
- return NS_OK;
- }
- nsresult
- PuppetWidget::ConfigureChildren(const nsTArray<Configuration>& aConfigurations)
- {
- for (uint32_t i = 0; i < aConfigurations.Length(); ++i) {
- const Configuration& configuration = aConfigurations[i];
- PuppetWidget* w = static_cast<PuppetWidget*>(configuration.mChild.get());
- NS_ASSERTION(w->GetParent() == this,
- "Configured widget is not a child");
- w->SetWindowClipRegion(configuration.mClipRegion, true);
- LayoutDeviceIntRect bounds = w->GetBounds();
- if (bounds.Size() != configuration.mBounds.Size()) {
- w->Resize(configuration.mBounds.x, configuration.mBounds.y,
- configuration.mBounds.width, configuration.mBounds.height,
- true);
- } else if (bounds.TopLeft() != configuration.mBounds.TopLeft()) {
- w->Move(configuration.mBounds.x, configuration.mBounds.y);
- }
- w->SetWindowClipRegion(configuration.mClipRegion, false);
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetWidget::SetFocus(bool aRaise)
- {
- if (aRaise && mTabChild) {
- mTabChild->SendRequestFocus(true);
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetWidget::Invalidate(const LayoutDeviceIntRect& aRect)
- {
- #ifdef DEBUG
- debug_DumpInvalidate(stderr, this, &aRect, "PuppetWidget", 0);
- #endif
- if (mChild) {
- return mChild->Invalidate(aRect);
- }
- mDirtyRegion.Or(mDirtyRegion, aRect);
- if (!mDirtyRegion.IsEmpty() && !mPaintTask.IsPending()) {
- mPaintTask = new PaintTask(this);
- return NS_DispatchToCurrentThread(mPaintTask.get());
- }
- return NS_OK;
- }
- void
- PuppetWidget::InitEvent(WidgetGUIEvent& event, LayoutDeviceIntPoint* aPoint)
- {
- if (nullptr == aPoint) {
- event.mRefPoint = LayoutDeviceIntPoint(0, 0);
- } else {
- // use the point override if provided
- event.mRefPoint = *aPoint;
- }
- event.mTime = PR_Now() / 1000;
- }
- NS_IMETHODIMP
- PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus)
- {
- #ifdef DEBUG
- debug_DumpEvent(stdout, event->mWidget, event, "PuppetWidget", 0);
- #endif
- MOZ_ASSERT(!mChild || mChild->mWindowType == eWindowType_popup,
- "Unexpected event dispatch!");
- AutoCacheNativeKeyCommands autoCache(this);
- if (event->mFlags.mIsSynthesizedForTests && !mNativeKeyCommandsValid) {
- WidgetKeyboardEvent* keyEvent = event->AsKeyboardEvent();
- if (keyEvent) {
- mTabChild->RequestNativeKeyBindings(&autoCache, keyEvent);
- }
- }
- if (event->mClass == eCompositionEventClass) {
- // Store the latest native IME context of parent process's widget or
- // TextEventDispatcher if it's in this process.
- WidgetCompositionEvent* compositionEvent = event->AsCompositionEvent();
- #ifdef DEBUG
- if (mNativeIMEContext.IsValid() &&
- mNativeIMEContext != compositionEvent->mNativeIMEContext) {
- RefPtr<TextComposition> composition =
- IMEStateManager::GetTextCompositionFor(this);
- MOZ_ASSERT(!composition,
- "When there is composition caused by old native IME context, "
- "composition events caused by different native IME context are not "
- "allowed");
- }
- #endif // #ifdef DEBUG
- mNativeIMEContext = compositionEvent->mNativeIMEContext;
- }
- aStatus = nsEventStatus_eIgnore;
- if (GetCurrentWidgetListener()) {
- aStatus = GetCurrentWidgetListener()->HandleEvent(event, mUseAttachedEvents);
- }
- return NS_OK;
- }
- nsEventStatus
- PuppetWidget::DispatchInputEvent(WidgetInputEvent* aEvent)
- {
- if (!AsyncPanZoomEnabled()) {
- nsEventStatus status = nsEventStatus_eIgnore;
- DispatchEvent(aEvent, status);
- return status;
- }
- if (!mTabChild) {
- return nsEventStatus_eIgnore;
- }
- switch (aEvent->mClass) {
- case eWheelEventClass:
- Unused <<
- mTabChild->SendDispatchWheelEvent(*aEvent->AsWheelEvent());
- break;
- case eMouseEventClass:
- Unused <<
- mTabChild->SendDispatchMouseEvent(*aEvent->AsMouseEvent());
- break;
- case eKeyboardEventClass:
- Unused <<
- mTabChild->SendDispatchKeyboardEvent(*aEvent->AsKeyboardEvent());
- break;
- default:
- MOZ_ASSERT_UNREACHABLE("unsupported event type");
- }
- return nsEventStatus_eIgnore;
- }
- nsresult
- PuppetWidget::SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
- int32_t aNativeKeyCode,
- uint32_t aModifierFlags,
- const nsAString& aCharacters,
- const nsAString& aUnmodifiedCharacters,
- nsIObserver* aObserver)
- {
- AutoObserverNotifier notifier(aObserver, "keyevent");
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- mTabChild->SendSynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
- aModifierFlags, nsString(aCharacters), nsString(aUnmodifiedCharacters),
- notifier.SaveObserver());
- return NS_OK;
- }
- nsresult
- PuppetWidget::SynthesizeNativeMouseEvent(mozilla::LayoutDeviceIntPoint aPoint,
- uint32_t aNativeMessage,
- uint32_t aModifierFlags,
- nsIObserver* aObserver)
- {
- AutoObserverNotifier notifier(aObserver, "mouseevent");
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- mTabChild->SendSynthesizeNativeMouseEvent(aPoint, aNativeMessage,
- aModifierFlags, notifier.SaveObserver());
- return NS_OK;
- }
- nsresult
- PuppetWidget::SynthesizeNativeMouseMove(mozilla::LayoutDeviceIntPoint aPoint,
- nsIObserver* aObserver)
- {
- AutoObserverNotifier notifier(aObserver, "mousemove");
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- mTabChild->SendSynthesizeNativeMouseMove(aPoint, notifier.SaveObserver());
- return NS_OK;
- }
- nsresult
- PuppetWidget::SynthesizeNativeMouseScrollEvent(mozilla::LayoutDeviceIntPoint aPoint,
- uint32_t aNativeMessage,
- double aDeltaX,
- double aDeltaY,
- double aDeltaZ,
- uint32_t aModifierFlags,
- uint32_t aAdditionalFlags,
- nsIObserver* aObserver)
- {
- AutoObserverNotifier notifier(aObserver, "mousescrollevent");
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- mTabChild->SendSynthesizeNativeMouseScrollEvent(aPoint, aNativeMessage,
- aDeltaX, aDeltaY, aDeltaZ, aModifierFlags, aAdditionalFlags,
- notifier.SaveObserver());
- return NS_OK;
- }
- nsresult
- PuppetWidget::SynthesizeNativeTouchPoint(uint32_t aPointerId,
- TouchPointerState aPointerState,
- LayoutDeviceIntPoint aPoint,
- double aPointerPressure,
- uint32_t aPointerOrientation,
- nsIObserver* aObserver)
- {
- AutoObserverNotifier notifier(aObserver, "touchpoint");
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- mTabChild->SendSynthesizeNativeTouchPoint(aPointerId, aPointerState,
- aPoint, aPointerPressure, aPointerOrientation,
- notifier.SaveObserver());
- return NS_OK;
- }
- nsresult
- PuppetWidget::SynthesizeNativeTouchTap(LayoutDeviceIntPoint aPoint,
- bool aLongTap,
- nsIObserver* aObserver)
- {
- AutoObserverNotifier notifier(aObserver, "touchtap");
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- mTabChild->SendSynthesizeNativeTouchTap(aPoint, aLongTap,
- notifier.SaveObserver());
- return NS_OK;
- }
- nsresult
- PuppetWidget::ClearNativeTouchSequence(nsIObserver* aObserver)
- {
- AutoObserverNotifier notifier(aObserver, "cleartouch");
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- mTabChild->SendClearNativeTouchSequence(notifier.SaveObserver());
- return NS_OK;
- }
-
- void
- PuppetWidget::SetConfirmedTargetAPZC(uint64_t aInputBlockId,
- const nsTArray<ScrollableLayerGuid>& aTargets) const
- {
- if (mTabChild) {
- mTabChild->SetTargetAPZC(aInputBlockId, aTargets);
- }
- }
- void
- PuppetWidget::UpdateZoomConstraints(const uint32_t& aPresShellId,
- const FrameMetrics::ViewID& aViewId,
- const Maybe<ZoomConstraints>& aConstraints)
- {
- if (mTabChild) {
- mTabChild->DoUpdateZoomConstraints(aPresShellId, aViewId, aConstraints);
- }
- }
- bool
- PuppetWidget::AsyncPanZoomEnabled() const
- {
- return mTabChild && mTabChild->AsyncPanZoomEnabled();
- }
- NS_IMETHODIMP_(bool)
- PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
- const mozilla::WidgetKeyboardEvent& aEvent,
- DoCommandCallback aCallback,
- void* aCallbackData)
- {
- AutoCacheNativeKeyCommands autoCache(this);
- if (!aEvent.mWidget && !mNativeKeyCommandsValid) {
- MOZ_ASSERT(!aEvent.mFlags.mIsSynthesizedForTests);
- // Abort if untrusted to avoid leaking system settings
- if (NS_WARN_IF(!aEvent.IsTrusted())) {
- return false;
- }
- mTabChild->RequestNativeKeyBindings(&autoCache, &aEvent);
- }
- MOZ_ASSERT(mNativeKeyCommandsValid);
- const nsTArray<mozilla::CommandInt>* commands = nullptr;
- switch (aType) {
- case nsIWidget::NativeKeyBindingsForSingleLineEditor:
- commands = &mSingleLineCommands;
- break;
- case nsIWidget::NativeKeyBindingsForMultiLineEditor:
- commands = &mMultiLineCommands;
- break;
- case nsIWidget::NativeKeyBindingsForRichTextEditor:
- commands = &mRichTextCommands;
- break;
- default:
- MOZ_CRASH("Invalid type");
- break;
- }
- if (commands->IsEmpty()) {
- return false;
- }
- for (uint32_t i = 0; i < commands->Length(); i++) {
- aCallback(static_cast<mozilla::Command>((*commands)[i]), aCallbackData);
- }
- return true;
- }
- LayerManager*
- PuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
- LayersBackend aBackendHint,
- LayerManagerPersistence aPersistence)
- {
- if (!mLayerManager) {
- mLayerManager = new ClientLayerManager(this);
- }
- ShadowLayerForwarder* lf = mLayerManager->AsShadowForwarder();
- if (lf && !lf->HasShadowManager() && aShadowManager) {
- lf->SetShadowManager(aShadowManager);
- }
- return mLayerManager;
- }
- LayerManager*
- PuppetWidget::RecreateLayerManager(PLayerTransactionChild* aShadowManager)
- {
- mLayerManager = new ClientLayerManager(this);
- if (ShadowLayerForwarder* lf = mLayerManager->AsShadowForwarder()) {
- lf->SetShadowManager(aShadowManager);
- }
- return mLayerManager;
- }
- nsresult
- PuppetWidget::RequestIMEToCommitComposition(bool aCancel)
- {
- #ifdef MOZ_CROSS_PROCESS_IME
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- MOZ_ASSERT(!Destroyed());
- // There must not be composition which is caused by the PuppetWidget instance.
- if (NS_WARN_IF(!mNativeIMEContext.IsValid())) {
- return NS_OK;
- }
- RefPtr<TextComposition> composition =
- IMEStateManager::GetTextCompositionFor(this);
- // This method shouldn't be called when there is no text composition instance.
- if (NS_WARN_IF(!composition)) {
- return NS_OK;
- }
- bool isCommitted = false;
- nsAutoString committedString;
- if (NS_WARN_IF(!mTabChild->SendRequestIMEToCommitComposition(
- aCancel, &isCommitted, &committedString))) {
- return NS_ERROR_FAILURE;
- }
- // If the composition wasn't committed synchronously, we need to wait async
- // composition events for destroying the TextComposition instance.
- if (!isCommitted) {
- return NS_OK;
- }
- // Dispatch eCompositionCommit event.
- WidgetCompositionEvent compositionCommitEvent(true, eCompositionCommit, this);
- InitEvent(compositionCommitEvent, nullptr);
- compositionCommitEvent.mData = committedString;
- nsEventStatus status = nsEventStatus_eIgnore;
- DispatchEvent(&compositionCommitEvent, status);
- // NOTE: PuppetWidget might be destroyed already.
- #endif // #ifdef MOZ_CROSS_PROCESS_IME
- return NS_OK;
- }
- nsresult
- PuppetWidget::NotifyIMEInternal(const IMENotification& aIMENotification)
- {
- switch (aIMENotification.mMessage) {
- case REQUEST_TO_COMMIT_COMPOSITION:
- return RequestIMEToCommitComposition(false);
- case REQUEST_TO_CANCEL_COMPOSITION:
- return RequestIMEToCommitComposition(true);
- case NOTIFY_IME_OF_FOCUS:
- case NOTIFY_IME_OF_BLUR:
- return NotifyIMEOfFocusChange(aIMENotification);
- case NOTIFY_IME_OF_SELECTION_CHANGE:
- return NotifyIMEOfSelectionChange(aIMENotification);
- case NOTIFY_IME_OF_TEXT_CHANGE:
- return NotifyIMEOfTextChange(aIMENotification);
- case NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED:
- return NotifyIMEOfCompositionUpdate(aIMENotification);
- case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT:
- return NotifyIMEOfMouseButtonEvent(aIMENotification);
- case NOTIFY_IME_OF_POSITION_CHANGE:
- return NotifyIMEOfPositionChange(aIMENotification);
- default:
- return NS_ERROR_NOT_IMPLEMENTED;
- }
- }
- NS_IMETHODIMP
- PuppetWidget::StartPluginIME(const mozilla::WidgetKeyboardEvent& aKeyboardEvent,
- int32_t aPanelX, int32_t aPanelY,
- nsString& aCommitted)
- {
- if (!mTabChild ||
- !mTabChild->SendStartPluginIME(aKeyboardEvent, aPanelX,
- aPanelY, &aCommitted)) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
- }
- void
- PuppetWidget::SetPluginFocused(bool& aFocused)
- {
- if (mTabChild) {
- mTabChild->SendSetPluginFocused(aFocused);
- }
- }
- void
- PuppetWidget::DefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent)
- {
- if (!mTabChild) {
- return;
- }
- mTabChild->SendDefaultProcOfPluginEvent(aEvent);
- }
- NS_IMETHODIMP_(void)
- PuppetWidget::SetInputContext(const InputContext& aContext,
- const InputContextAction& aAction)
- {
- mInputContext = aContext;
- // Any widget instances cannot cache IME open state because IME open state
- // can be changed by user but native IME may not notify us of changing the
- // open state on some platforms.
- mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
- #ifndef MOZ_CROSS_PROCESS_IME
- return;
- #endif
- if (!mTabChild) {
- return;
- }
- mTabChild->SendSetInputContext(
- static_cast<int32_t>(aContext.mIMEState.mEnabled),
- static_cast<int32_t>(aContext.mIMEState.mOpen),
- aContext.mHTMLInputType,
- aContext.mHTMLInputInputmode,
- aContext.mActionHint,
- static_cast<int32_t>(aAction.mCause),
- static_cast<int32_t>(aAction.mFocusChange));
- }
- NS_IMETHODIMP_(InputContext)
- PuppetWidget::GetInputContext()
- {
- #ifndef MOZ_CROSS_PROCESS_IME
- return InputContext();
- #endif
- // XXX Currently, we don't support retrieving IME open state from child
- // process.
- // When this widget caches input context and currently managed by
- // IMEStateManager, the cache is valid. Only in this case, we can
- // avoid to use synchronous IPC.
- if (mInputContext.mIMEState.mEnabled != IMEState::UNKNOWN &&
- IMEStateManager::GetWidgetForActiveInputContext() == this) {
- return mInputContext;
- }
- NS_WARNING("PuppetWidget::GetInputContext() needs to retrieve it with IPC");
- // Don't cache InputContext here because this process isn't managing IME
- // state of the chrome widget. So, we cannot modify mInputContext when
- // chrome widget is set to new context.
- InputContext context;
- if (mTabChild) {
- int32_t enabled, open;
- mTabChild->SendGetInputContext(&enabled, &open);
- context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(enabled);
- context.mIMEState.mOpen = static_cast<IMEState::Open>(open);
- }
- return context;
- }
- NS_IMETHODIMP_(NativeIMEContext)
- PuppetWidget::GetNativeIMEContext()
- {
- return mNativeIMEContext;
- }
- nsresult
- PuppetWidget::NotifyIMEOfFocusChange(const IMENotification& aIMENotification)
- {
- #ifndef MOZ_CROSS_PROCESS_IME
- return NS_OK;
- #endif
- if (!mTabChild)
- return NS_ERROR_FAILURE;
- bool gotFocus = aIMENotification.mMessage == NOTIFY_IME_OF_FOCUS;
- if (gotFocus) {
- if (mInputContext.mIMEState.mEnabled != IMEState::PLUGIN) {
- // When IME gets focus, we should initalize all information of the
- // content.
- if (NS_WARN_IF(!mContentCache.CacheAll(this, &aIMENotification))) {
- return NS_ERROR_FAILURE;
- }
- } else {
- // However, if a plugin has focus, only the editor rect information is
- // available.
- if (NS_WARN_IF(!mContentCache.CacheEditorRect(this, &aIMENotification))) {
- return NS_ERROR_FAILURE;
- }
- }
- } else {
- // When IME loses focus, we don't need to store anything.
- mContentCache.Clear();
- }
- mIMEPreferenceOfParent = nsIMEUpdatePreference();
- if (!mTabChild->SendNotifyIMEFocus(mContentCache, aIMENotification,
- &mIMEPreferenceOfParent)) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
- }
- nsresult
- PuppetWidget::NotifyIMEOfCompositionUpdate(
- const IMENotification& aIMENotification)
- {
- #ifndef MOZ_CROSS_PROCESS_IME
- return NS_OK;
- #endif
- NS_ENSURE_TRUE(mTabChild, NS_ERROR_FAILURE);
- if (mInputContext.mIMEState.mEnabled != IMEState::PLUGIN &&
- NS_WARN_IF(!mContentCache.CacheSelection(this, &aIMENotification))) {
- return NS_ERROR_FAILURE;
- }
- mTabChild->SendNotifyIMECompositionUpdate(mContentCache, aIMENotification);
- return NS_OK;
- }
- nsIMEUpdatePreference
- PuppetWidget::GetIMEUpdatePreference()
- {
- #ifdef MOZ_CROSS_PROCESS_IME
- // e10s requires IME content cache in in the TabParent for handling query
- // content event only with the parent process. Therefore, this process
- // needs to receive a lot of information from the focused editor to sent
- // the latest content to the parent process.
- if (mInputContext.mIMEState.mEnabled == IMEState::PLUGIN) {
- // But if a plugin has focus, we cannot receive text nor selection change
- // in the plugin. Therefore, PuppetWidget needs to receive only position
- // change event for updating the editor rect cache.
- return nsIMEUpdatePreference(mIMEPreferenceOfParent.mWantUpdates |
- nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE);
- }
- return nsIMEUpdatePreference(mIMEPreferenceOfParent.mWantUpdates |
- nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE |
- nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE );
- #else
- // B2G doesn't handle IME as widget-level.
- return nsIMEUpdatePreference();
- #endif
- }
- nsresult
- PuppetWidget::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
- {
- MOZ_ASSERT(aIMENotification.mMessage == NOTIFY_IME_OF_TEXT_CHANGE,
- "Passed wrong notification");
- #ifndef MOZ_CROSS_PROCESS_IME
- return NS_OK;
- #endif
- if (!mTabChild)
- return NS_ERROR_FAILURE;
- // While a plugin has focus, text change notification shouldn't be available.
- if (NS_WARN_IF(mInputContext.mIMEState.mEnabled == IMEState::PLUGIN)) {
- return NS_ERROR_FAILURE;
- }
- // FYI: text change notification is the first notification after
- // a user operation changes the content. So, we need to modify
- // the cache as far as possible here.
- if (NS_WARN_IF(!mContentCache.CacheText(this, &aIMENotification))) {
- return NS_ERROR_FAILURE;
- }
- // TabParent doesn't this this to cache. we don't send the notification
- // if parent process doesn't request NOTIFY_TEXT_CHANGE.
- if (mIMEPreferenceOfParent.WantTextChange()) {
- mTabChild->SendNotifyIMETextChange(mContentCache, aIMENotification);
- } else {
- mTabChild->SendUpdateContentCache(mContentCache);
- }
- return NS_OK;
- }
- nsresult
- PuppetWidget::NotifyIMEOfSelectionChange(
- const IMENotification& aIMENotification)
- {
- MOZ_ASSERT(aIMENotification.mMessage == NOTIFY_IME_OF_SELECTION_CHANGE,
- "Passed wrong notification");
- #ifndef MOZ_CROSS_PROCESS_IME
- return NS_OK;
- #endif
- if (!mTabChild)
- return NS_ERROR_FAILURE;
- // While a plugin has focus, selection change notification shouldn't be
- // available.
- if (NS_WARN_IF(mInputContext.mIMEState.mEnabled == IMEState::PLUGIN)) {
- return NS_ERROR_FAILURE;
- }
- // Note that selection change must be notified after text change if it occurs.
- // Therefore, we don't need to query text content again here.
- mContentCache.SetSelection(
- this,
- aIMENotification.mSelectionChangeData.mOffset,
- aIMENotification.mSelectionChangeData.Length(),
- aIMENotification.mSelectionChangeData.mReversed,
- aIMENotification.mSelectionChangeData.GetWritingMode());
- mTabChild->SendNotifyIMESelection(mContentCache, aIMENotification);
- return NS_OK;
- }
- nsresult
- PuppetWidget::NotifyIMEOfMouseButtonEvent(
- const IMENotification& aIMENotification)
- {
- if (!mTabChild) {
- return NS_ERROR_FAILURE;
- }
- // While a plugin has focus, mouse button event notification shouldn't be
- // available.
- if (NS_WARN_IF(mInputContext.mIMEState.mEnabled == IMEState::PLUGIN)) {
- return NS_ERROR_FAILURE;
- }
- bool consumedByIME = false;
- if (!mTabChild->SendNotifyIMEMouseButtonEvent(aIMENotification,
- &consumedByIME)) {
- return NS_ERROR_FAILURE;
- }
- return consumedByIME ? NS_SUCCESS_EVENT_CONSUMED : NS_OK;
- }
- nsresult
- PuppetWidget::NotifyIMEOfPositionChange(const IMENotification& aIMENotification)
- {
- #ifndef MOZ_CROSS_PROCESS_IME
- return NS_OK;
- #endif
- if (NS_WARN_IF(!mTabChild)) {
- return NS_ERROR_FAILURE;
- }
- if (NS_WARN_IF(!mContentCache.CacheEditorRect(this, &aIMENotification))) {
- return NS_ERROR_FAILURE;
- }
- // While a plugin has focus, selection range isn't available. So, we don't
- // need to cache it at that time.
- if (mInputContext.mIMEState.mEnabled != IMEState::PLUGIN &&
- NS_WARN_IF(!mContentCache.CacheSelection(this, &aIMENotification))) {
- return NS_ERROR_FAILURE;
- }
- if (mIMEPreferenceOfParent.WantPositionChanged()) {
- mTabChild->SendNotifyIMEPositionChange(mContentCache, aIMENotification);
- } else {
- mTabChild->SendUpdateContentCache(mContentCache);
- }
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetWidget::SetCursor(nsCursor aCursor)
- {
- // Don't cache on windows, Windowless flash breaks this via async cursor updates.
- #if !defined(XP_WIN)
- if (mCursor == aCursor && !mCustomCursor && !mUpdateCursor) {
- return NS_OK;
- }
- #endif
- mCustomCursor = nullptr;
- if (mTabChild &&
- !mTabChild->SendSetCursor(aCursor, mUpdateCursor)) {
- return NS_ERROR_FAILURE;
- }
- mCursor = aCursor;
- mUpdateCursor = false;
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetWidget::SetCursor(imgIContainer* aCursor,
- uint32_t aHotspotX, uint32_t aHotspotY)
- {
- if (!aCursor || !mTabChild) {
- return NS_OK;
- }
- #if !defined(XP_WIN)
- if (mCustomCursor == aCursor &&
- mCursorHotspotX == aHotspotX &&
- mCursorHotspotY == aHotspotY &&
- !mUpdateCursor) {
- return NS_OK;
- }
- #endif
- RefPtr<mozilla::gfx::SourceSurface> surface =
- aCursor->GetFrame(imgIContainer::FRAME_CURRENT,
- imgIContainer::FLAG_SYNC_DECODE);
- if (!surface) {
- return NS_ERROR_FAILURE;
- }
- RefPtr<mozilla::gfx::DataSourceSurface> dataSurface =
- surface->GetDataSurface();
- if (!dataSurface) {
- return NS_ERROR_FAILURE;
- }
- size_t length;
- int32_t stride;
- mozilla::UniquePtr<char[]> surfaceData =
- nsContentUtils::GetSurfaceData(WrapNotNull(dataSurface), &length, &stride);
- nsDependentCString cursorData(surfaceData.get(), length);
- mozilla::gfx::IntSize size = dataSurface->GetSize();
- if (!mTabChild->SendSetCustomCursor(cursorData, size.width, size.height, stride,
- static_cast<uint8_t>(dataSurface->GetFormat()),
- aHotspotX, aHotspotY, mUpdateCursor)) {
- return NS_ERROR_FAILURE;
- }
- mCursor = nsCursor(-1);
- mCustomCursor = aCursor;
- mCursorHotspotX = aHotspotX;
- mCursorHotspotY = aHotspotY;
- mUpdateCursor = false;
- return NS_OK;
- }
- void
- PuppetWidget::ClearCachedCursor()
- {
- nsBaseWidget::ClearCachedCursor();
- mCustomCursor = nullptr;
- }
- nsresult
- PuppetWidget::Paint()
- {
- MOZ_ASSERT(!mDirtyRegion.IsEmpty(), "paint event logic messed up");
- if (!GetCurrentWidgetListener())
- return NS_OK;
- LayoutDeviceIntRegion region = mDirtyRegion;
- // reset repaint tracking
- mDirtyRegion.SetEmpty();
- mPaintTask.Revoke();
- RefPtr<PuppetWidget> strongThis(this);
- GetCurrentWidgetListener()->WillPaintWindow(this);
- if (GetCurrentWidgetListener()) {
- #ifdef DEBUG
- debug_DumpPaintEvent(stderr, this, region.ToUnknownRegion(),
- "PuppetWidget", 0);
- #endif
- if (mozilla::layers::LayersBackend::LAYERS_CLIENT == mLayerManager->GetBackendType()) {
- // Do nothing, the compositor will handle drawing
- if (mTabChild) {
- mTabChild->NotifyPainted();
- }
- } else if (mozilla::layers::LayersBackend::LAYERS_BASIC == mLayerManager->GetBackendType()) {
- RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(mDrawTarget);
- if (!ctx) {
- gfxDevCrash(LogReason::InvalidContext) << "PuppetWidget context problem " << gfx::hexa(mDrawTarget);
- return NS_ERROR_FAILURE;
- }
- ctx->Rectangle(gfxRect(0,0,0,0));
- ctx->Clip();
- AutoLayerManagerSetup setupLayerManager(this, ctx,
- BufferMode::BUFFER_NONE);
- GetCurrentWidgetListener()->PaintWindow(this, region);
- if (mTabChild) {
- mTabChild->NotifyPainted();
- }
- }
- }
- if (GetCurrentWidgetListener()) {
- GetCurrentWidgetListener()->DidPaintWindow();
- }
- return NS_OK;
- }
- void
- PuppetWidget::SetChild(PuppetWidget* aChild)
- {
- MOZ_ASSERT(this != aChild, "can't parent a widget to itself");
- MOZ_ASSERT(!aChild->mChild,
- "fake widget 'hierarchy' only expected to have one level");
- mChild = aChild;
- }
- NS_IMETHODIMP
- PuppetWidget::PaintTask::Run()
- {
- if (mWidget) {
- mWidget->Paint();
- }
- return NS_OK;
- }
- void
- PuppetWidget::PaintNowIfNeeded()
- {
- if (IsVisible() && mPaintTask.IsPending()) {
- Paint();
- }
- }
- NS_IMPL_ISUPPORTS(PuppetWidget::MemoryPressureObserver, nsIObserver)
- NS_IMETHODIMP
- PuppetWidget::MemoryPressureObserver::Observe(nsISupports* aSubject,
- const char* aTopic,
- const char16_t* aData)
- {
- if (!mWidget) {
- return NS_OK;
- }
- if (strcmp("memory-pressure", aTopic) == 0 &&
- !NS_LITERAL_STRING("lowering-priority").Equals(aData)) {
- if (!mWidget->mVisible && mWidget->mLayerManager &&
- XRE_IsContentProcess()) {
- mWidget->mLayerManager->ClearCachedResources();
- }
- }
- return NS_OK;
- }
- void
- PuppetWidget::MemoryPressureObserver::Remove()
- {
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- obs->RemoveObserver(this, "memory-pressure");
- }
- mWidget = nullptr;
- }
- bool
- PuppetWidget::NeedsPaint()
- {
- // e10s popups are handled by the parent process, so never should be painted here
- if (XRE_IsContentProcess() &&
- Preferences::GetBool("browser.tabs.remote.desktopbehavior", false) &&
- mWindowType == eWindowType_popup) {
- NS_WARNING("Trying to paint an e10s popup in the child process!");
- return false;
- }
- return mVisible;
- }
- float
- PuppetWidget::GetDPI()
- {
- if (mDPI < 0) {
- if (mTabChild) {
- mTabChild->GetDPI(&mDPI);
- } else {
- mDPI = 96.0;
- }
- }
- return mDPI;
- }
- double
- PuppetWidget::GetDefaultScaleInternal()
- {
- if (mDefaultScale < 0) {
- if (mTabChild) {
- mTabChild->GetDefaultScale(&mDefaultScale);
- } else {
- mDefaultScale = 1;
- }
- }
- return mDefaultScale;
- }
- int32_t
- PuppetWidget::RoundsWidgetCoordinatesTo()
- {
- if (mRounding < 0) {
- if (mTabChild) {
- mTabChild->GetWidgetRounding(&mRounding);
- } else {
- mRounding = 1;
- }
- }
- return mRounding;
- }
- void*
- PuppetWidget::GetNativeData(uint32_t aDataType)
- {
- switch (aDataType) {
- case NS_NATIVE_SHAREABLE_WINDOW: {
- MOZ_ASSERT(mTabChild, "Need TabChild to get the nativeWindow from!");
- mozilla::WindowsHandle nativeData = 0;
- if (mTabChild) {
- mTabChild->SendGetWidgetNativeData(&nativeData);
- }
- return (void*)nativeData;
- }
- case NS_NATIVE_WINDOW:
- case NS_NATIVE_WIDGET:
- case NS_NATIVE_DISPLAY:
- // These types are ignored (see bug 1183828, bug 1240891).
- break;
- case NS_RAW_NATIVE_IME_CONTEXT:
- MOZ_CRASH("You need to call GetNativeIMEContext() instead");
- case NS_NATIVE_PLUGIN_PORT:
- case NS_NATIVE_GRAPHIC:
- case NS_NATIVE_SHELLWIDGET:
- default:
- NS_WARNING("nsWindow::GetNativeData called with bad value");
- break;
- }
- return nullptr;
- }
- #if defined(XP_WIN)
- void
- PuppetWidget::SetNativeData(uint32_t aDataType, uintptr_t aVal)
- {
- switch (aDataType) {
- case NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW:
- MOZ_ASSERT(mTabChild, "Need TabChild to send the message.");
- if (mTabChild) {
- mTabChild->SendSetNativeChildOfShareableWindow(aVal);
- }
- break;
- default:
- NS_WARNING("SetNativeData called with unsupported data type.");
- }
- }
- #endif
- nsIntPoint
- PuppetWidget::GetChromeDimensions()
- {
- if (!GetOwningTabChild()) {
- NS_WARNING("PuppetWidget without Tab does not have chrome information.");
- return nsIntPoint();
- }
- return GetOwningTabChild()->GetChromeDisplacement().ToUnknownPoint();
- }
- nsIntPoint
- PuppetWidget::GetWindowPosition()
- {
- if (!GetOwningTabChild()) {
- return nsIntPoint();
- }
- int32_t winX, winY, winW, winH;
- NS_ENSURE_SUCCESS(GetOwningTabChild()->GetDimensions(0, &winX, &winY, &winW, &winH), nsIntPoint());
- return nsIntPoint(winX, winY) + GetOwningTabChild()->GetClientOffset().ToUnknownPoint();
- }
- LayoutDeviceIntRect
- PuppetWidget::GetScreenBounds()
- {
- return LayoutDeviceIntRect(WidgetToScreenOffset(), mBounds.Size());
- }
- uint32_t PuppetWidget::GetMaxTouchPoints() const
- {
- static uint32_t sTouchPoints = 0;
- static bool sIsInitialized = false;
- if (sIsInitialized) {
- return sTouchPoints;
- }
- if (mTabChild) {
- mTabChild->GetMaxTouchPoints(&sTouchPoints);
- sIsInitialized = true;
- }
- return sTouchPoints;
- }
- void
- PuppetWidget::StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics)
- {
- mTabChild->StartScrollbarDrag(aDragMetrics);
- }
- PuppetScreen::PuppetScreen(void *nativeScreen)
- {
- }
- PuppetScreen::~PuppetScreen()
- {
- }
- static ScreenConfiguration
- ScreenConfig()
- {
- ScreenConfiguration config;
- hal::GetCurrentScreenConfiguration(&config);
- return config;
- }
- nsIntSize
- PuppetWidget::GetScreenDimensions()
- {
- nsIntRect r = ScreenConfig().rect();
- return nsIntSize(r.width, r.height);
- }
- NS_IMETHODIMP
- PuppetScreen::GetId(uint32_t *outId)
- {
- *outId = 1;
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetScreen::GetRect(int32_t *outLeft, int32_t *outTop,
- int32_t *outWidth, int32_t *outHeight)
- {
- nsIntRect r = ScreenConfig().rect();
- *outLeft = r.x;
- *outTop = r.y;
- *outWidth = r.width;
- *outHeight = r.height;
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetScreen::GetAvailRect(int32_t *outLeft, int32_t *outTop,
- int32_t *outWidth, int32_t *outHeight)
- {
- return GetRect(outLeft, outTop, outWidth, outHeight);
- }
- NS_IMETHODIMP
- PuppetScreen::GetPixelDepth(int32_t *aPixelDepth)
- {
- *aPixelDepth = ScreenConfig().pixelDepth();
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetScreen::GetColorDepth(int32_t *aColorDepth)
- {
- *aColorDepth = ScreenConfig().colorDepth();
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetScreen::GetRotation(uint32_t* aRotation)
- {
- NS_WARNING("Attempt to get screen rotation through nsIScreen::GetRotation(). Nothing should know or care this in sandboxed contexts. If you want *orientation*, use hal.");
- return NS_ERROR_NOT_AVAILABLE;
- }
- NS_IMETHODIMP
- PuppetScreen::SetRotation(uint32_t aRotation)
- {
- NS_WARNING("Attempt to set screen rotation through nsIScreen::GetRotation(). Nothing should know or care this in sandboxed contexts. If you want *orientation*, use hal.");
- return NS_ERROR_NOT_AVAILABLE;
- }
- NS_IMPL_ISUPPORTS(PuppetScreenManager, nsIScreenManager)
- PuppetScreenManager::PuppetScreenManager()
- {
- mOneScreen = new PuppetScreen(nullptr);
- }
- PuppetScreenManager::~PuppetScreenManager()
- {
- }
- NS_IMETHODIMP
- PuppetScreenManager::ScreenForId(uint32_t aId,
- nsIScreen** outScreen)
- {
- NS_IF_ADDREF(*outScreen = mOneScreen.get());
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetScreenManager::GetPrimaryScreen(nsIScreen** outScreen)
- {
- NS_IF_ADDREF(*outScreen = mOneScreen.get());
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetScreenManager::ScreenForRect(int32_t inLeft,
- int32_t inTop,
- int32_t inWidth,
- int32_t inHeight,
- nsIScreen** outScreen)
- {
- return GetPrimaryScreen(outScreen);
- }
- NS_IMETHODIMP
- PuppetScreenManager::ScreenForNativeWidget(void* aWidget,
- nsIScreen** outScreen)
- {
- return GetPrimaryScreen(outScreen);
- }
- NS_IMETHODIMP
- PuppetScreenManager::GetNumberOfScreens(uint32_t* aNumberOfScreens)
- {
- *aNumberOfScreens = 1;
- return NS_OK;
- }
- NS_IMETHODIMP
- PuppetScreenManager::GetSystemDefaultScale(float *aDefaultScale)
- {
- *aDefaultScale = 1.0f;
- return NS_OK;
- }
- nsIWidgetListener*
- PuppetWidget::GetCurrentWidgetListener()
- {
- if (!mPreviouslyAttachedWidgetListener ||
- !mAttachedWidgetListener) {
- return mAttachedWidgetListener;
- }
- if (mAttachedWidgetListener->GetView()->IsPrimaryFramePaintSuppressed()) {
- return mPreviouslyAttachedWidgetListener;
- }
- return mAttachedWidgetListener;
- }
- void
- PuppetWidget::SetCandidateWindowForPlugin(
- const CandidateWindowPosition& aPosition)
- {
- if (!mTabChild) {
- return;
- }
- mTabChild->SendSetCandidateWindowForPlugin(aPosition);
- }
- void
- PuppetWidget::ZoomToRect(const uint32_t& aPresShellId,
- const FrameMetrics::ViewID& aViewId,
- const CSSRect& aRect,
- const uint32_t& aFlags)
- {
- if (!mTabChild) {
- return;
- }
- mTabChild->ZoomToRect(aPresShellId, aViewId, aRect, aFlags);
- }
- void
- PuppetWidget::LookUpDictionary(
- const nsAString& aText,
- const nsTArray<mozilla::FontRange>& aFontRangeArray,
- const bool aIsVertical,
- const LayoutDeviceIntPoint& aPoint)
- {
- if (!mTabChild) {
- return;
- }
- mTabChild->SendLookUpDictionary(nsString(aText), aFontRangeArray, aIsVertical, aPoint);
- }
- bool
- PuppetWidget::HasPendingInputEvent()
- {
- if (!mTabChild) {
- return false;
- }
- bool ret = false;
- mTabChild->GetIPCChannel()->PeekMessages(
- [&ret](const IPC::Message& aMsg) -> bool {
- if ((aMsg.type() & mozilla::dom::PBrowser::PBrowserStart)
- == mozilla::dom::PBrowser::PBrowserStart) {
- switch (aMsg.type()) {
- case mozilla::dom::PBrowser::Msg_RealMouseMoveEvent__ID:
- case mozilla::dom::PBrowser::Msg_SynthMouseMoveEvent__ID:
- case mozilla::dom::PBrowser::Msg_RealMouseButtonEvent__ID:
- case mozilla::dom::PBrowser::Msg_RealKeyEvent__ID:
- case mozilla::dom::PBrowser::Msg_MouseWheelEvent__ID:
- case mozilla::dom::PBrowser::Msg_RealTouchEvent__ID:
- case mozilla::dom::PBrowser::Msg_RealTouchMoveEvent__ID:
- case mozilla::dom::PBrowser::Msg_RealDragEvent__ID:
- case mozilla::dom::PBrowser::Msg_UpdateDimensions__ID:
- case mozilla::dom::PBrowser::Msg_MouseEvent__ID:
- case mozilla::dom::PBrowser::Msg_KeyEvent__ID:
- ret = true;
- return false; // Stop peeking.
- }
- }
- return true;
- }
- );
- return ret;
- }
- void
- PuppetWidget::HandledWindowedPluginKeyEvent(
- const NativeEventData& aKeyEventData,
- bool aIsConsumed)
- {
- if (NS_WARN_IF(mKeyEventInPluginCallbacks.IsEmpty())) {
- return;
- }
- nsCOMPtr<nsIKeyEventInPluginCallback> callback =
- mKeyEventInPluginCallbacks[0];
- MOZ_ASSERT(callback);
- mKeyEventInPluginCallbacks.RemoveElementAt(0);
- callback->HandledWindowedPluginKeyEvent(aKeyEventData, aIsConsumed);
- }
- nsresult
- PuppetWidget::OnWindowedPluginKeyEvent(const NativeEventData& aKeyEventData,
- nsIKeyEventInPluginCallback* aCallback)
- {
- if (NS_WARN_IF(!mTabChild)) {
- return NS_ERROR_NOT_AVAILABLE;
- }
- if (NS_WARN_IF(!mTabChild->SendOnWindowedPluginKeyEvent(aKeyEventData))) {
- return NS_ERROR_FAILURE;
- }
- mKeyEventInPluginCallbacks.AppendElement(aCallback);
- return NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY;
- }
- } // namespace widget
- } // namespace mozilla
|