2010-08-21 03:24:40 +04:00
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim : sw = 2 ts = 8 et :
*/
2012-05-21 15:12:37 +04:00
/* 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/. */
2010-08-21 03:24:40 +04:00
2012-07-18 03:59:45 +04:00
# include "base/basictypes.h"
2013-05-01 09:03:25 +04:00
# include "ClientLayerManager.h"
2012-07-18 03:59:45 +04:00
# include "gfxPlatform.h"
# include "mozilla/dom/TabChild.h"
2012-05-09 01:36:07 +04:00
# include "mozilla/Hal.h"
2014-03-08 05:20:07 +04:00
# include "mozilla/IMEStateManager.h"
2012-07-18 03:59:45 +04:00
# include "mozilla/layers/CompositorChild.h"
2013-04-24 22:42:40 +04:00
# include "mozilla/layers/PLayerTransactionChild.h"
2014-11-20 20:28:58 +03:00
# include "mozilla/Preferences.h"
2014-04-03 08:18:37 +04:00
# include "mozilla/TextComposition.h"
2013-09-25 15:21:19 +04:00
# include "mozilla/TextEvents.h"
2015-03-25 01:00:52 +03:00
# include "mozilla/unused.h"
2010-08-21 03:24:40 +04:00
# include "PuppetWidget.h"
2015-10-26 19:14:47 +03:00
# include "nsContentUtils.h"
2012-08-15 22:52:42 +04:00
# include "nsIWidgetListener.h"
2010-08-21 03:24:40 +04:00
2014-06-10 10:02:21 +04:00
using namespace mozilla ;
2012-05-09 01:36:07 +04:00
using namespace mozilla : : dom ;
using namespace mozilla : : hal ;
2014-02-09 12:04:38 +04:00
using namespace mozilla : : gfx ;
2010-08-21 03:24:40 +04:00
using namespace mozilla : : layers ;
using namespace mozilla : : widget ;
static void
2015-11-23 07:32:29 +03:00
InvalidateRegion ( nsIWidget * aWidget , const LayoutDeviceIntRegion & aRegion )
2010-08-21 03:24:40 +04:00
{
2015-11-23 07:32:29 +03:00
LayoutDeviceIntRegion : : RectIterator it ( aRegion ) ;
while ( const LayoutDeviceIntRect * r = it . Next ( ) ) {
aWidget - > Invalidate ( * r ) ;
2010-08-21 03:24:40 +04:00
}
}
/*static*/ already_AddRefed < nsIWidget >
2012-07-18 03:59:45 +04:00
nsIWidget : : CreatePuppetWidget ( TabChild * aTabChild )
2010-08-21 03:24:40 +04:00
{
2015-02-10 01:34:50 +03:00
MOZ_ASSERT ( ! aTabChild | | nsIWidget : : UsePuppetWidgets ( ) ,
" PuppetWidgets not allowed in this configuration " ) ;
2010-08-21 03:24:40 +04:00
2010-09-24 07:28:15 +04:00
nsCOMPtr < nsIWidget > widget = new PuppetWidget ( aTabChild ) ;
2010-08-21 03:24:40 +04:00
return widget . forget ( ) ;
}
namespace mozilla {
namespace widget {
2011-02-23 20:45:09 +03:00
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.
2013-01-29 03:56:28 +04:00
# ifdef MOZ_CROSS_PROCESS_IME
2011-02-23 20:45:09 +03:00
return ! IsPopup ( aInitData ) ;
2013-01-29 03:56:28 +04:00
# else
return false ;
# endif
2011-02-23 20:45:09 +03:00
}
2010-08-21 03:24:40 +04:00
// Arbitrary, fungible.
const size_t PuppetWidget : : kMaxDimension = 4000 ;
2015-02-18 09:27:53 +03:00
NS_IMPL_ISUPPORTS_INHERITED0 ( PuppetWidget , nsBaseWidget )
2010-08-21 03:24:40 +04:00
2012-07-18 03:59:45 +04:00
PuppetWidget : : PuppetWidget ( TabChild * aTabChild )
2010-09-24 07:28:15 +04:00
: mTabChild ( aTabChild )
2015-05-20 10:45:41 +03:00
, mMemoryPressureObserver ( nullptr )
2010-12-03 04:24:04 +03:00
, mDPI ( - 1 )
2013-05-02 03:06:19 +04:00
, mDefaultScale ( - 1 )
2015-05-20 04:28:57 +03:00
, mCursorHotspotX ( 0 )
, mCursorHotspotY ( 0 )
2015-12-11 09:15:57 +03:00
, mNativeKeyCommandsValid ( false )
2010-08-21 03:24:40 +04:00
{
MOZ_COUNT_CTOR ( PuppetWidget ) ;
2014-03-20 19:46:29 +04:00
mSingleLineCommands . SetCapacity ( 4 ) ;
mMultiLineCommands . SetCapacity ( 4 ) ;
mRichTextCommands . SetCapacity ( 4 ) ;
2010-08-21 03:24:40 +04:00
}
PuppetWidget : : ~ PuppetWidget ( )
{
MOZ_COUNT_DTOR ( PuppetWidget ) ;
2015-05-21 11:08:43 +03:00
Destroy ( ) ;
2010-08-21 03:24:40 +04:00
}
NS_IMETHODIMP
2015-11-16 11:35:18 +03:00
PuppetWidget : : Create ( nsIWidget * aParent ,
nsNativeWidget aNativeParent ,
const LayoutDeviceIntRect & aRect ,
nsWidgetInitData * aInitData )
2010-08-21 03:24:40 +04:00
{
2015-02-10 01:34:50 +03:00
MOZ_ASSERT ( ! aNativeParent , " got a non-Puppet native parent " ) ;
2010-08-21 03:24:40 +04:00
2016-01-13 10:32:55 +03:00
BaseCreate ( nullptr , aInitData ) ;
2010-08-21 03:24:40 +04:00
2015-11-23 07:32:29 +03:00
mBounds = aRect ;
2011-10-17 18:59:28 +04:00
mEnabled = true ;
mVisible = true ;
2010-08-21 03:24:40 +04:00
2014-06-10 10:02:21 +04:00
mDrawTarget = gfxPlatform : : GetPlatform ( ) - >
CreateOffscreenContentDrawTarget ( IntSize ( 1 , 1 ) , SurfaceFormat : : B8G8R8A8 ) ;
2010-08-21 03:24:40 +04:00
2012-08-29 19:26:18 +04:00
mNeedIMEStateInit = MightNeedIMEFocus ( aInitData ) ;
2010-09-24 07:28:15 +04:00
2010-08-21 03:24:40 +04:00
PuppetWidget * parent = static_cast < PuppetWidget * > ( aParent ) ;
if ( parent ) {
parent - > SetChild ( this ) ;
2010-08-21 03:24:41 +04:00
mLayerManager = parent - > GetLayerManager ( ) ;
2010-08-21 03:24:40 +04:00
}
else {
2011-10-17 18:59:28 +04:00
Resize ( mBounds . x , mBounds . y , mBounds . width , mBounds . height , false ) ;
2010-08-21 03:24:40 +04:00
}
2015-05-20 10:45:41 +03:00
nsCOMPtr < nsIObserverService > obs = mozilla : : services : : GetObserverService ( ) ;
if ( obs ) {
mMemoryPressureObserver = new MemoryPressureObserver ( this ) ;
obs - > AddObserver ( mMemoryPressureObserver , " memory-pressure " , false ) ;
}
2010-08-21 03:24:40 +04:00
return NS_OK ;
}
2012-08-29 19:26:18 +04:00
void
PuppetWidget : : InitIMEState ( )
{
2013-06-17 09:42:20 +04:00
MOZ_ASSERT ( mTabChild ) ;
2012-08-29 19:26:18 +04:00
if ( mNeedIMEStateInit ) {
2015-06-05 12:28:20 +03:00
mContentCache . Clear ( ) ;
2015-07-17 07:30:01 +03:00
mTabChild - > SendUpdateContentCache ( mContentCache ) ;
mIMEPreferenceOfParent = nsIMEUpdatePreference ( ) ;
2012-08-29 19:26:18 +04:00
mNeedIMEStateInit = false ;
}
}
2010-08-21 03:24:40 +04:00
already_AddRefed < nsIWidget >
2015-11-16 11:35:18 +03:00
PuppetWidget : : CreateChild ( const LayoutDeviceIntRect & aRect ,
nsWidgetInitData * aInitData ,
bool aForceUseIWidgetParent )
2010-08-21 03:24:40 +04:00
{
2011-02-23 20:45:09 +03:00
bool isPopup = IsPopup ( aInitData ) ;
2010-09-24 07:28:15 +04:00
nsCOMPtr < nsIWidget > widget = nsIWidget : : CreatePuppetWidget ( mTabChild ) ;
2010-08-21 03:24:40 +04:00
return ( ( widget & &
2012-07-30 18:20:58 +04:00
NS_SUCCEEDED ( widget - > Create ( isPopup ? nullptr : this , nullptr , aRect ,
2015-02-05 10:35:25 +03:00
aInitData ) ) ) ?
2012-07-30 18:20:58 +04:00
widget . forget ( ) : nullptr ) ;
2010-08-21 03:24:40 +04:00
}
2010-08-21 03:24:40 +04:00
NS_IMETHODIMP
PuppetWidget : : Destroy ( )
{
2015-12-11 09:15:58 +03:00
if ( mOnDestroyCalled ) {
return NS_OK ;
}
mOnDestroyCalled = true ;
2011-03-30 00:14:44 +04:00
Base : : OnDestroy ( ) ;
2010-08-21 03:24:40 +04:00
Base : : Destroy ( ) ;
mPaintTask . Revoke ( ) ;
2015-05-20 10:45:41 +03:00
if ( mMemoryPressureObserver ) {
mMemoryPressureObserver - > Remove ( ) ;
}
mMemoryPressureObserver = nullptr ;
2012-07-30 18:20:58 +04:00
mChild = nullptr ;
2010-12-07 05:05:25 +03:00
if ( mLayerManager ) {
mLayerManager - > Destroy ( ) ;
}
2012-07-30 18:20:58 +04:00
mLayerManager = nullptr ;
mTabChild = nullptr ;
2010-08-21 03:24:40 +04:00
return NS_OK ;
}
2010-08-21 03:24:40 +04:00
NS_IMETHODIMP
2011-09-29 10:19:26 +04:00
PuppetWidget : : Show ( bool aState )
2010-08-21 03:24:40 +04:00
{
NS_ASSERTION ( mEnabled ,
" does it make sense to Show()/Hide() a disabled widget? " ) ;
2011-09-29 10:19:26 +04:00
bool wasVisible = mVisible ;
2010-08-21 03:24:40 +04:00
mVisible = aState ;
2012-11-08 07:51:55 +04:00
if ( mChild ) {
mChild - > mVisible = aState ;
}
2010-08-21 03:24:40 +04:00
if ( ! wasVisible & & mVisible ) {
2011-10-17 18:59:28 +04:00
Resize ( mBounds . width , mBounds . height , false ) ;
2015-11-23 07:32:29 +03:00
Invalidate ( mBounds ) ;
2010-08-21 03:24:40 +04:00
}
return NS_OK ;
}
NS_IMETHODIMP
2012-12-12 13:57:38 +04:00
PuppetWidget : : Resize ( double aWidth ,
double aHeight ,
bool aRepaint )
2010-08-21 03:24:40 +04:00
{
2015-11-23 07:32:29 +03:00
LayoutDeviceIntRect oldBounds = mBounds ;
mBounds . SizeTo ( LayoutDeviceIntSize ( NSToIntRound ( aWidth ) ,
NSToIntRound ( aHeight ) ) ) ;
2010-08-21 03:24:40 +04:00
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 ) {
2015-11-23 07:32:29 +03:00
LayoutDeviceIntRegion dirty ( mBounds ) ;
dirty . Sub ( dirty , oldBounds ) ;
2010-08-21 03:24:40 +04:00
InvalidateRegion ( this , dirty ) ;
}
2015-07-22 04:09:02 +03:00
// 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
2012-08-15 22:53:14 +04:00
if ( ! oldBounds . IsEqualEdges ( mBounds ) & & mAttachedWidgetListener ) {
2015-07-22 04:09:02 +03:00
if ( GetCurrentWidgetListener ( ) & &
GetCurrentWidgetListener ( ) ! = mAttachedWidgetListener ) {
GetCurrentWidgetListener ( ) - > WindowResized ( this , mBounds . width , mBounds . height ) ;
}
2012-08-15 22:53:14 +04:00
mAttachedWidgetListener - > WindowResized ( this , mBounds . width , mBounds . height ) ;
2010-08-21 03:24:40 +04:00
}
return NS_OK ;
}
2014-11-12 23:59:19 +03:00
nsresult
PuppetWidget : : ConfigureChildren ( const nsTArray < Configuration > & aConfigurations )
{
for ( uint32_t i = 0 ; i < aConfigurations . Length ( ) ; + + i ) {
const Configuration & configuration = aConfigurations [ i ] ;
2015-05-25 21:45:00 +03:00
PuppetWidget * w = static_cast < PuppetWidget * > ( configuration . mChild . get ( ) ) ;
2014-11-12 23:59:19 +03:00
NS_ASSERTION ( w - > GetParent ( ) = = this ,
" Configured widget is not a child " ) ;
w - > SetWindowClipRegion ( configuration . mClipRegion , true ) ;
2015-11-11 03:27:26 +03:00
LayoutDeviceIntRect bounds ;
w - > GetBounds ( bounds ) ;
2014-11-12 23:59:19 +03:00
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 ;
}
2010-08-21 03:24:40 +04:00
NS_IMETHODIMP
2011-09-29 10:19:26 +04:00
PuppetWidget : : SetFocus ( bool aRaise )
2010-08-21 03:24:40 +04:00
{
2015-10-06 16:14:49 +03:00
if ( aRaise & & mTabChild ) {
mTabChild - > SendRequestFocus ( true ) ;
}
2010-08-21 03:24:40 +04:00
return NS_OK ;
}
NS_IMETHODIMP
2015-11-17 08:18:31 +03:00
PuppetWidget : : Invalidate ( const LayoutDeviceIntRect & aRect )
2010-08-21 03:24:40 +04:00
{
# ifdef DEBUG
2011-12-24 07:52:21 +04:00
debug_DumpInvalidate ( stderr , this , & aRect ,
2012-09-02 06:35:17 +04:00
nsAutoCString ( " PuppetWidget " ) , 0 ) ;
2010-08-21 03:24:40 +04:00
# endif
if ( mChild ) {
2011-12-24 07:52:21 +04:00
return mChild - > Invalidate ( aRect ) ;
2010-08-21 03:24:40 +04:00
}
mDirtyRegion . Or ( mDirtyRegion , aRect ) ;
2011-12-24 07:52:21 +04:00
if ( ! mDirtyRegion . IsEmpty ( ) & & ! mPaintTask . IsPending ( ) ) {
2010-08-21 03:24:40 +04:00
mPaintTask = new PaintTask ( this ) ;
return NS_DispatchToCurrentThread ( mPaintTask . get ( ) ) ;
}
return NS_OK ;
}
2010-09-24 07:28:15 +04:00
void
2015-11-10 08:37:32 +03:00
PuppetWidget : : InitEvent ( WidgetGUIEvent & event , LayoutDeviceIntPoint * aPoint )
2010-09-24 07:28:15 +04:00
{
2012-07-30 18:20:58 +04:00
if ( nullptr = = aPoint ) {
2010-09-24 07:28:15 +04:00
event . refPoint . x = 0 ;
event . refPoint . y = 0 ;
2015-11-10 08:37:32 +03:00
} else {
2010-09-24 07:28:15 +04:00
// use the point override if provided
2015-11-10 08:37:32 +03:00
event . refPoint = * aPoint ;
2010-09-24 07:28:15 +04:00
}
event . time = PR_Now ( ) / 1000 ;
}
2010-08-21 03:24:40 +04:00
NS_IMETHODIMP
2013-10-02 07:46:03 +04:00
PuppetWidget : : DispatchEvent ( WidgetGUIEvent * event , nsEventStatus & aStatus )
2010-08-21 03:24:40 +04:00
{
# ifdef DEBUG
debug_DumpEvent ( stdout , event - > widget , event ,
2012-09-02 06:35:17 +04:00
nsAutoCString ( " PuppetWidget " ) , 0 ) ;
2010-08-21 03:24:40 +04:00
# endif
2015-02-10 01:34:50 +03:00
MOZ_ASSERT ( ! mChild | | mChild - > mWindowType = = eWindowType_popup ,
" Unexpected event dispatch! " ) ;
2011-02-09 23:13:18 +03:00
2014-04-22 00:40:09 +04:00
AutoCacheNativeKeyCommands autoCache ( this ) ;
if ( event - > mFlags . mIsSynthesizedForTests & & ! mNativeKeyCommandsValid ) {
WidgetKeyboardEvent * keyEvent = event - > AsKeyboardEvent ( ) ;
if ( keyEvent ) {
mTabChild - > RequestNativeKeyBindings ( & autoCache , keyEvent ) ;
}
}
2015-12-11 09:15:57 +03:00
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 ;
}
2010-08-21 03:24:40 +04:00
aStatus = nsEventStatus_eIgnore ;
2011-02-09 23:13:18 +03:00
2015-07-22 04:09:02 +03:00
if ( GetCurrentWidgetListener ( ) ) {
aStatus = GetCurrentWidgetListener ( ) - > HandleEvent ( event , mUseAttachedEvents ) ;
2013-01-25 23:51:16 +04:00
}
2011-02-09 23:13:18 +03:00
2010-08-21 03:24:40 +04:00
return NS_OK ;
}
2015-03-25 01:00:52 +03:00
nsEventStatus
PuppetWidget : : DispatchInputEvent ( WidgetInputEvent * aEvent )
{
if ( ! mTabChild ) {
return nsEventStatus_eIgnore ;
}
switch ( aEvent - > mClass ) {
case eMouseEventClass :
2015-11-02 08:53:26 +03:00
Unused < <
2015-03-25 01:00:52 +03:00
mTabChild - > SendDispatchMouseEvent ( * aEvent - > AsMouseEvent ( ) ) ;
break ;
case eKeyboardEventClass :
2015-11-02 08:53:26 +03:00
Unused < <
2015-03-25 01:00:52 +03:00
mTabChild - > SendDispatchKeyboardEvent ( * aEvent - > AsKeyboardEvent ( ) ) ;
break ;
default :
MOZ_ASSERT_UNREACHABLE ( " unsupported event type " ) ;
}
return nsEventStatus_eIgnore ;
}
2014-03-20 19:46:29 +04:00
2015-03-07 01:26:59 +03:00
nsEventStatus
PuppetWidget : : DispatchAPZAwareEvent ( WidgetInputEvent * aEvent )
{
2015-06-04 23:51:10 +03:00
if ( ! AsyncPanZoomEnabled ( ) ) {
2015-03-07 01:26:59 +03:00
nsEventStatus status = nsEventStatus_eIgnore ;
DispatchEvent ( aEvent , status ) ;
return status ;
}
if ( ! mTabChild ) {
return nsEventStatus_eIgnore ;
}
switch ( aEvent - > mClass ) {
case eWheelEventClass :
2015-11-02 08:53:26 +03:00
Unused < <
2015-03-25 01:00:52 +03:00
mTabChild - > SendDispatchWheelEvent ( * aEvent - > AsWheelEvent ( ) ) ;
2015-03-07 01:26:59 +03:00
break ;
default :
MOZ_ASSERT_UNREACHABLE ( " unsupported event type " ) ;
}
return nsEventStatus_eIgnore ;
}
2015-04-14 18:36:36 +03:00
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 ,
2015-12-03 08:45:38 +03:00
ScreenIntPoint aPointerScreenPoint ,
2015-04-14 18:36:36 +03:00
double aPointerPressure ,
uint32_t aPointerOrientation ,
nsIObserver * aObserver )
{
AutoObserverNotifier notifier ( aObserver , " touchpoint " ) ;
if ( ! mTabChild ) {
return NS_ERROR_FAILURE ;
}
mTabChild - > SendSynthesizeNativeTouchPoint ( aPointerId , aPointerState ,
aPointerScreenPoint , aPointerPressure , aPointerOrientation ,
notifier . SaveObserver ( ) ) ;
return NS_OK ;
}
nsresult
2015-12-03 08:45:38 +03:00
PuppetWidget : : SynthesizeNativeTouchTap ( ScreenIntPoint aPointerScreenPoint ,
2015-04-14 18:36:36 +03:00
bool aLongTap ,
nsIObserver * aObserver )
{
AutoObserverNotifier notifier ( aObserver , " touchtap " ) ;
if ( ! mTabChild ) {
return NS_ERROR_FAILURE ;
}
mTabChild - > SendSynthesizeNativeTouchTap ( aPointerScreenPoint , 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 ;
}
2015-04-14 19:24:32 +03:00
void
PuppetWidget : : SetConfirmedTargetAPZC ( uint64_t aInputBlockId ,
const nsTArray < ScrollableLayerGuid > & aTargets ) const
{
if ( mTabChild ) {
mTabChild - > SendSetTargetAPZC ( aInputBlockId , aTargets ) ;
}
}
2015-04-14 18:36:36 +03:00
2015-06-17 19:32:42 +03:00
void
PuppetWidget : : UpdateZoomConstraints ( const uint32_t & aPresShellId ,
const FrameMetrics : : ViewID & aViewId ,
const Maybe < ZoomConstraints > & aConstraints )
{
if ( mTabChild ) {
mTabChild - > DoUpdateZoomConstraints ( aPresShellId , aViewId , aConstraints ) ;
}
}
2015-06-04 23:51:10 +03:00
bool
PuppetWidget : : AsyncPanZoomEnabled ( ) const
{
return mTabChild & & mTabChild - > AsyncPanZoomEnabled ( ) ;
}
2014-03-20 19:46:29 +04:00
NS_IMETHODIMP_ ( bool )
PuppetWidget : : ExecuteNativeKeyBinding ( NativeKeyBindingsType aType ,
const mozilla : : WidgetKeyboardEvent & aEvent ,
DoCommandCallback aCallback ,
void * aCallbackData )
{
2014-04-22 00:40:09 +04:00
// B2G doesn't have native key bindings.
2015-04-15 22:17:00 +03:00
# ifdef MOZ_WIDGET_GONK
2014-04-22 00:40:09 +04:00
return false ;
2015-04-15 22:17:00 +03:00
# else // #ifdef MOZ_WIDGET_GONK
2014-04-22 00:40:09 +04:00
MOZ_ASSERT ( mNativeKeyCommandsValid ) ;
2015-07-21 20:21:05 +03:00
const nsTArray < mozilla : : CommandInt > * commands = nullptr ;
2014-03-20 19:46:29 +04:00
switch ( aType ) {
case nsIWidget : : NativeKeyBindingsForSingleLineEditor :
2015-07-21 20:21:05 +03:00
commands = & mSingleLineCommands ;
2014-03-20 19:46:29 +04:00
break ;
case nsIWidget : : NativeKeyBindingsForMultiLineEditor :
2015-07-21 20:21:05 +03:00
commands = & mMultiLineCommands ;
2014-03-20 19:46:29 +04:00
break ;
case nsIWidget : : NativeKeyBindingsForRichTextEditor :
2015-07-21 20:21:05 +03:00
commands = & mRichTextCommands ;
break ;
default :
MOZ_CRASH ( " Invalid type " ) ;
2014-03-20 19:46:29 +04:00
break ;
}
2015-07-21 20:21:05 +03:00
if ( commands - > IsEmpty ( ) ) {
2014-03-20 19:46:29 +04:00
return false ;
}
2015-07-21 20:21:05 +03:00
for ( uint32_t i = 0 ; i < commands - > Length ( ) ; i + + ) {
aCallback ( static_cast < mozilla : : Command > ( ( * commands ) [ i ] ) , aCallbackData ) ;
2014-03-20 19:46:29 +04:00
}
return true ;
2014-04-22 00:40:09 +04:00
# endif
2014-03-20 19:46:29 +04:00
}
2010-08-21 03:24:40 +04:00
LayerManager *
2013-04-24 22:42:40 +04:00
PuppetWidget : : GetLayerManager ( PLayerTransactionChild * aShadowManager ,
2011-08-09 23:38:26 +04:00
LayersBackend aBackendHint ,
LayerManagerPersistence aPersistence ,
bool * aAllowRetaining )
2010-08-21 03:24:40 +04:00
{
if ( ! mLayerManager ) {
2014-08-22 04:16:44 +04:00
mLayerManager = new ClientLayerManager ( this ) ;
2010-08-21 03:24:40 +04:00
}
2013-11-01 10:36:02 +04:00
ShadowLayerForwarder * lf = mLayerManager - > AsShadowForwarder ( ) ;
if ( ! lf - > HasShadowManager ( ) & & aShadowManager ) {
lf - > SetShadowManager ( aShadowManager ) ;
}
2010-10-15 14:34:29 +04:00
if ( aAllowRetaining ) {
* aAllowRetaining = true ;
}
2010-08-21 03:24:40 +04:00
return mLayerManager ;
}
2010-09-24 07:28:15 +04:00
nsresult
2015-12-11 09:15:58 +03:00
PuppetWidget : : RequestIMEToCommitComposition ( bool aCancel )
2010-09-24 07:28:15 +04:00
{
2015-12-11 09:15:58 +03:00
# ifdef MOZ_CROSS_PROCESS_IME
if ( ! mTabChild ) {
return NS_ERROR_FAILURE ;
}
MOZ_ASSERT ( ! Destroyed ( ) ) ;
2013-01-29 03:56:28 +04:00
2015-12-11 09:15:57 +03:00
// There must not be composition which is caused by the PuppetWidget instance.
if ( NS_WARN_IF ( ! mNativeIMEContext . IsValid ( ) ) ) {
return NS_OK ;
}
2015-12-11 09:15:58 +03:00
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 ) ) ) {
2010-09-24 07:28:15 +04:00
return NS_ERROR_FAILURE ;
}
2010-12-15 22:22:15 +03:00
2015-12-11 09:15:58 +03:00
// If the composition wasn't committed synchronously, we need to wait async
// composition events for destroying the TextComposition instance.
if ( ! isCommitted ) {
2010-12-15 22:22:15 +03:00
return NS_OK ;
2015-02-17 05:30:55 +03:00
}
2010-12-15 22:22:15 +03:00
2015-12-11 09:15:58 +03:00
// Dispatch eCompositionCommit event.
WidgetCompositionEvent compositionCommitEvent ( true , eCompositionCommit , this ) ;
InitEvent ( compositionCommitEvent , nullptr ) ;
compositionCommitEvent . mData = committedString ;
nsEventStatus status = nsEventStatus_eIgnore ;
2015-02-17 05:30:38 +03:00
DispatchEvent ( & compositionCommitEvent , status ) ;
2015-12-11 09:15:58 +03:00
// NOTE: PuppetWidget might be destroyed already.
# endif // #ifdef MOZ_CROSS_PROCESS_IME
2010-09-24 07:28:15 +04:00
return NS_OK ;
}
2015-01-28 09:27:31 +03:00
nsresult
PuppetWidget : : NotifyIMEInternal ( const IMENotification & aIMENotification )
2010-09-24 07:28:15 +04:00
{
2014-02-18 04:00:15 +04:00
switch ( aIMENotification . mMessage ) {
2013-03-06 10:14:31 +04:00
case REQUEST_TO_COMMIT_COMPOSITION :
2015-12-11 09:15:58 +03:00
return RequestIMEToCommitComposition ( false ) ;
2013-03-06 10:14:31 +04:00
case REQUEST_TO_CANCEL_COMPOSITION :
2015-12-11 09:15:58 +03:00
return RequestIMEToCommitComposition ( true ) ;
2013-03-06 10:14:31 +04:00
case NOTIFY_IME_OF_FOCUS :
case NOTIFY_IME_OF_BLUR :
2015-06-05 12:28:20 +03:00
return NotifyIMEOfFocusChange ( aIMENotification ) ;
2013-03-06 10:14:31 +04:00
case NOTIFY_IME_OF_SELECTION_CHANGE :
2014-02-26 04:48:02 +04:00
return NotifyIMEOfSelectionChange ( aIMENotification ) ;
2014-02-18 04:00:15 +04:00
case NOTIFY_IME_OF_TEXT_CHANGE :
return NotifyIMEOfTextChange ( aIMENotification ) ;
2013-11-07 04:11:11 +04:00
case NOTIFY_IME_OF_COMPOSITION_UPDATE :
2015-07-17 07:30:01 +03:00
return NotifyIMEOfCompositionUpdate ( aIMENotification ) ;
2014-09-11 17:46:17 +04:00
case NOTIFY_IME_OF_MOUSE_BUTTON_EVENT :
return NotifyIMEOfMouseButtonEvent ( aIMENotification ) ;
2014-12-15 12:37:00 +03:00
case NOTIFY_IME_OF_POSITION_CHANGE :
2015-06-05 12:28:20 +03:00
return NotifyIMEOfPositionChange ( aIMENotification ) ;
2013-03-06 10:14:31 +04:00
default :
return NS_ERROR_NOT_IMPLEMENTED ;
}
2010-09-24 07:28:15 +04:00
}
2015-02-20 19:37:02 +03:00
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 ;
}
NS_IMETHODIMP
PuppetWidget : : SetPluginFocused ( bool & aFocused )
{
if ( ! mTabChild | | ! mTabChild - > SendSetPluginFocused ( aFocused ) ) {
return NS_ERROR_FAILURE ;
}
return NS_OK ;
}
2015-12-29 16:57:38 +03:00
void
PuppetWidget : : DefaultProcOfPluginEvent ( const WidgetPluginEvent & aEvent )
{
if ( ! mTabChild ) {
return ;
}
mTabChild - > SendDefaultProcOfPluginEvent ( aEvent ) ;
}
2011-11-27 15:51:52 +04:00
NS_IMETHODIMP_ ( void )
PuppetWidget : : SetInputContext ( const InputContext & aContext ,
const InputContextAction & aAction )
2010-09-24 07:28:15 +04:00
{
2015-10-10 04:21:02 +03:00
mInputContext = aContext ;
2013-01-29 03:56:28 +04:00
# ifndef MOZ_CROSS_PROCESS_IME
return ;
# endif
2011-11-27 15:51:52 +04:00
if ( ! mTabChild ) {
return ;
}
2011-11-27 15:51:53 +04:00
mTabChild - > SendSetInputContext (
2012-08-22 19:56:38 +04:00
static_cast < int32_t > ( aContext . mIMEState . mEnabled ) ,
static_cast < int32_t > ( aContext . mIMEState . mOpen ) ,
2011-11-27 15:51:53 +04:00
aContext . mHTMLInputType ,
2012-08-27 06:16:22 +04:00
aContext . mHTMLInputInputmode ,
2011-11-27 15:51:53 +04:00
aContext . mActionHint ,
2012-08-22 19:56:38 +04:00
static_cast < int32_t > ( aAction . mCause ) ,
static_cast < int32_t > ( aAction . mFocusChange ) ) ;
2010-09-24 07:28:15 +04:00
}
2011-11-27 15:51:52 +04:00
NS_IMETHODIMP_ ( InputContext )
PuppetWidget : : GetInputContext ( )
2010-09-24 07:28:15 +04:00
{
2013-01-29 03:56:28 +04:00
# ifndef MOZ_CROSS_PROCESS_IME
return InputContext ( ) ;
# endif
2011-11-27 15:51:52 +04:00
InputContext context ;
if ( mTabChild ) {
2012-08-22 19:56:38 +04:00
int32_t enabled , open ;
2015-12-11 09:15:57 +03:00
// TODO: This is too expensive. PuppetWidget should cache IMEState.
mTabChild - > SendGetInputContext ( & enabled , & open ) ;
2011-11-27 15:51:53 +04:00
context . mIMEState . mEnabled = static_cast < IMEState : : Enabled > ( enabled ) ;
context . mIMEState . mOpen = static_cast < IMEState : : Open > ( open ) ;
2011-11-27 15:51:52 +04:00
}
return context ;
2010-09-24 07:28:15 +04:00
}
2015-12-11 09:15:57 +03:00
NS_IMETHODIMP_ ( NativeIMEContext )
PuppetWidget : : GetNativeIMEContext ( )
{
return mNativeIMEContext ;
}
2013-03-06 10:14:31 +04:00
nsresult
2015-06-05 12:28:20 +03:00
PuppetWidget : : NotifyIMEOfFocusChange ( const IMENotification & aIMENotification )
2010-09-24 07:28:15 +04:00
{
2013-01-29 03:56:28 +04:00
# ifndef MOZ_CROSS_PROCESS_IME
return NS_OK ;
# endif
2010-09-24 07:28:15 +04:00
if ( ! mTabChild )
return NS_ERROR_FAILURE ;
2015-06-05 12:28:20 +03:00
bool gotFocus = aIMENotification . mMessage = = NOTIFY_IME_OF_FOCUS ;
if ( gotFocus ) {
2015-10-10 04:21:02 +03:00
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 ;
}
2010-09-24 07:28:15 +04:00
}
2015-06-05 12:28:20 +03:00
} else {
2015-06-05 12:28:20 +03:00
// When IME loses focus, we don't need to store anything.
2015-06-05 12:28:20 +03:00
mContentCache . Clear ( ) ;
2010-09-24 07:28:15 +04:00
}
2014-02-26 04:48:02 +04:00
mIMEPreferenceOfParent = nsIMEUpdatePreference ( ) ;
2015-07-17 07:30:01 +03:00
if ( ! mTabChild - > SendNotifyIMEFocus ( mContentCache , aIMENotification ,
2015-06-05 12:28:20 +03:00
& mIMEPreferenceOfParent ) ) {
2010-09-24 07:28:15 +04:00
return NS_ERROR_FAILURE ;
2014-01-29 13:32:39 +04:00
}
2010-09-24 07:28:15 +04:00
return NS_OK ;
}
2013-11-07 04:11:11 +04:00
nsresult
2015-07-17 07:30:01 +03:00
PuppetWidget : : NotifyIMEOfCompositionUpdate (
2015-06-05 12:28:20 +03:00
const IMENotification & aIMENotification )
2013-11-07 04:11:11 +04:00
{
# ifndef MOZ_CROSS_PROCESS_IME
return NS_OK ;
# endif
NS_ENSURE_TRUE ( mTabChild , NS_ERROR_FAILURE ) ;
2015-10-10 04:21:02 +03:00
if ( mInputContext . mIMEState . mEnabled ! = IMEState : : PLUGIN & &
NS_WARN_IF ( ! mContentCache . CacheSelection ( this , & aIMENotification ) ) ) {
2014-12-15 12:37:00 +03:00
return NS_ERROR_FAILURE ;
}
2015-07-17 07:30:01 +03:00
mTabChild - > SendNotifyIMECompositionUpdate ( mContentCache , aIMENotification ) ;
2014-12-15 12:37:00 +03:00
return NS_OK ;
}
2012-11-13 17:04:44 +04:00
nsIMEUpdatePreference
PuppetWidget : : GetIMEUpdatePreference ( )
{
2014-02-25 09:51:01 +04:00
# ifdef MOZ_CROSS_PROCESS_IME
2015-10-10 04:21:01 +03:00
// 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.
2015-10-10 04:21:02 +03:00
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 ) ;
}
2014-01-29 13:32:39 +04:00
return nsIMEUpdatePreference ( mIMEPreferenceOfParent . mWantUpdates |
nsIMEUpdatePreference : : NOTIFY_SELECTION_CHANGE |
2014-12-15 12:37:00 +03:00
nsIMEUpdatePreference : : NOTIFY_TEXT_CHANGE |
nsIMEUpdatePreference : : NOTIFY_POSITION_CHANGE ) ;
2014-01-29 13:32:39 +04:00
# else
// B2G doesn't handle IME as widget-level.
return nsIMEUpdatePreference ( ) ;
# endif
2012-11-13 17:04:44 +04:00
}
2014-02-18 04:00:15 +04:00
nsresult
PuppetWidget : : NotifyIMEOfTextChange ( const IMENotification & aIMENotification )
2010-09-24 07:28:15 +04:00
{
2014-02-26 04:48:02 +04:00
MOZ_ASSERT ( aIMENotification . mMessage = = NOTIFY_IME_OF_TEXT_CHANGE ,
" Passed wrong notification " ) ;
2013-01-29 03:56:28 +04:00
# ifndef MOZ_CROSS_PROCESS_IME
return NS_OK ;
# endif
2010-09-24 07:28:15 +04:00
if ( ! mTabChild )
return NS_ERROR_FAILURE ;
2015-10-10 04:21:02 +03:00
// 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 ;
}
2015-06-05 12:28:20 +03:00
// 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.
2015-06-05 12:28:20 +03:00
if ( NS_WARN_IF ( ! mContentCache . CacheText ( this , & aIMENotification ) ) ) {
2015-06-05 12:28:20 +03:00
return NS_ERROR_FAILURE ;
2010-09-24 07:28:15 +04:00
}
2014-01-29 13:32:39 +04:00
// TabParent doesn't this this to cache. we don't send the notification
// if parent process doesn't request NOTIFY_TEXT_CHANGE.
2014-02-26 04:48:02 +04:00
if ( mIMEPreferenceOfParent . WantTextChange ( ) & &
( mIMEPreferenceOfParent . WantChangesCausedByComposition ( ) | |
! aIMENotification . mTextChangeData . mCausedByComposition ) ) {
2015-07-17 07:30:01 +03:00
mTabChild - > SendNotifyIMETextChange ( mContentCache , aIMENotification ) ;
2015-06-05 12:28:20 +03:00
} else {
mTabChild - > SendUpdateContentCache ( mContentCache ) ;
2010-09-24 07:28:15 +04:00
}
return NS_OK ;
}
2013-03-06 10:14:31 +04:00
nsresult
2014-02-26 04:48:02 +04:00
PuppetWidget : : NotifyIMEOfSelectionChange (
const IMENotification & aIMENotification )
2010-09-24 07:28:15 +04:00
{
2014-02-26 04:48:02 +04:00
MOZ_ASSERT ( aIMENotification . mMessage = = NOTIFY_IME_OF_SELECTION_CHANGE ,
" Passed wrong notification " ) ;
2013-01-29 03:56:28 +04:00
# ifndef MOZ_CROSS_PROCESS_IME
return NS_OK ;
# endif
2010-09-24 07:28:15 +04:00
if ( ! mTabChild )
return NS_ERROR_FAILURE ;
2015-10-10 04:21:02 +03:00
// 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 ;
}
2015-06-05 12:28:20 +03:00
// Note that selection change must be notified after text change if it occurs.
// Therefore, we don't need to query text content again here.
2015-06-05 12:28:20 +03:00
mContentCache . SetSelection (
2015-07-17 07:30:01 +03:00
this ,
2015-06-05 12:28:20 +03:00
aIMENotification . mSelectionChangeData . mOffset ,
2015-07-22 06:40:32 +03:00
aIMENotification . mSelectionChangeData . Length ( ) ,
2015-06-05 12:28:20 +03:00
aIMENotification . mSelectionChangeData . mReversed ,
aIMENotification . mSelectionChangeData . GetWritingMode ( ) ) ;
2015-10-10 04:21:01 +03:00
if ( mIMEPreferenceOfParent . WantSelectionChange ( ) & &
( mIMEPreferenceOfParent . WantChangesCausedByComposition ( ) | |
! aIMENotification . mSelectionChangeData . mCausedByComposition ) ) {
mTabChild - > SendNotifyIMESelection ( mContentCache , aIMENotification ) ;
} else {
mTabChild - > SendUpdateContentCache ( mContentCache ) ;
}
2010-09-24 07:28:15 +04:00
return NS_OK ;
2014-09-11 17:46:17 +04:00
}
nsresult
PuppetWidget : : NotifyIMEOfMouseButtonEvent (
const IMENotification & aIMENotification )
{
if ( ! mTabChild ) {
return NS_ERROR_FAILURE ;
}
2015-10-10 04:21:02 +03:00
// 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 ;
}
2014-09-11 17:46:17 +04:00
bool consumedByIME = false ;
if ( ! mTabChild - > SendNotifyIMEMouseButtonEvent ( aIMENotification ,
& consumedByIME ) ) {
return NS_ERROR_FAILURE ;
}
return consumedByIME ? NS_SUCCESS_EVENT_CONSUMED : NS_OK ;
2010-09-24 07:28:15 +04:00
}
2014-12-15 12:37:00 +03:00
nsresult
2015-06-05 12:28:20 +03:00
PuppetWidget : : NotifyIMEOfPositionChange ( const IMENotification & aIMENotification )
2014-12-15 12:37:00 +03:00
{
# ifndef MOZ_CROSS_PROCESS_IME
return NS_OK ;
# endif
if ( NS_WARN_IF ( ! mTabChild ) ) {
return NS_ERROR_FAILURE ;
}
2015-10-10 04:21:02 +03:00
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 & &
2015-06-05 12:28:20 +03:00
NS_WARN_IF ( ! mContentCache . CacheSelection ( this , & aIMENotification ) ) ) {
2014-12-15 12:37:00 +03:00
return NS_ERROR_FAILURE ;
}
2015-10-10 04:21:01 +03:00
if ( mIMEPreferenceOfParent . WantPositionChanged ( ) ) {
mTabChild - > SendNotifyIMEPositionChange ( mContentCache , aIMENotification ) ;
} else {
mTabChild - > SendUpdateContentCache ( mContentCache ) ;
2014-12-15 12:37:00 +03:00
}
return NS_OK ;
}
2011-06-22 04:32:43 +04:00
NS_IMETHODIMP
PuppetWidget : : SetCursor ( nsCursor aCursor )
{
2015-12-22 01:19:15 +03:00
// Don't cache on windows, Windowless flash breaks this via async cursor updates.
# if !defined(XP_WIN)
2015-05-20 04:28:57 +03:00
if ( mCursor = = aCursor & & ! mCustomCursor & & ! mUpdateCursor ) {
2012-09-12 08:48:13 +04:00
return NS_OK ;
}
2015-12-22 01:19:15 +03:00
# endif
2012-09-12 08:48:13 +04:00
2015-05-20 04:28:57 +03:00
mCustomCursor = nullptr ;
2014-05-28 05:12:29 +04:00
if ( mTabChild & &
! mTabChild - > SendSetCursor ( aCursor , mUpdateCursor ) ) {
2011-06-22 04:32:43 +04:00
return NS_ERROR_FAILURE ;
}
2012-09-12 08:48:13 +04:00
mCursor = aCursor ;
2014-05-28 05:12:29 +04:00
mUpdateCursor = false ;
2012-09-12 08:48:13 +04:00
2011-06-22 04:32:43 +04:00
return NS_OK ;
2015-05-20 04:28:57 +03:00
}
NS_IMETHODIMP
PuppetWidget : : SetCursor ( imgIContainer * aCursor ,
uint32_t aHotspotX , uint32_t aHotspotY )
{
if ( ! aCursor | | ! mTabChild ) {
return NS_OK ;
}
2015-12-22 01:19:15 +03:00
# if !defined(XP_WIN)
2015-05-20 04:28:57 +03:00
if ( mCustomCursor = = aCursor & &
mCursorHotspotX = = aHotspotX & &
mCursorHotspotY = = aHotspotY & &
! mUpdateCursor ) {
return NS_OK ;
}
2015-12-22 01:19:15 +03:00
# endif
2015-05-20 04:28:57 +03:00
2015-10-18 08:24:48 +03:00
RefPtr < mozilla : : gfx : : SourceSurface > surface =
2015-05-20 04:28:57 +03:00
aCursor - > GetFrame ( imgIContainer : : FRAME_CURRENT ,
imgIContainer : : FLAG_SYNC_DECODE ) ;
if ( ! surface ) {
return NS_ERROR_FAILURE ;
}
2015-10-18 08:24:48 +03:00
RefPtr < mozilla : : gfx : : DataSourceSurface > dataSurface =
2015-05-20 04:28:57 +03:00
surface - > GetDataSurface ( ) ;
size_t length ;
int32_t stride ;
mozilla : : UniquePtr < char [ ] > surfaceData =
nsContentUtils : : GetSurfaceData ( dataSurface , & length , & stride ) ;
nsCString cursorData = nsCString ( 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 ;
2011-06-22 04:32:43 +04:00
}
2010-08-21 03:24:40 +04:00
nsresult
2012-08-15 22:52:42 +04:00
PuppetWidget : : Paint ( )
2010-08-21 03:24:40 +04:00
{
2015-02-10 01:34:50 +03:00
MOZ_ASSERT ( ! mDirtyRegion . IsEmpty ( ) , " paint event logic messed up " ) ;
2010-08-21 03:24:40 +04:00
2015-07-22 04:09:02 +03:00
if ( ! GetCurrentWidgetListener ( ) )
2012-08-15 22:52:42 +04:00
return NS_OK ;
2015-11-17 08:18:31 +03:00
LayoutDeviceIntRegion region = mDirtyRegion ;
2010-08-21 03:24:40 +04:00
// reset repaint tracking
mDirtyRegion . SetEmpty ( ) ;
mPaintTask . Revoke ( ) ;
2015-07-22 04:09:02 +03:00
GetCurrentWidgetListener ( ) - > WillPaintWindow ( this ) ;
2013-01-28 23:34:03 +04:00
2015-07-22 04:09:02 +03:00
if ( GetCurrentWidgetListener ( ) ) {
2010-08-21 03:24:40 +04:00
# ifdef DEBUG
2015-11-17 08:18:31 +03:00
debug_DumpPaintEvent ( stderr , this , region . ToUnknownRegion ( ) ,
2012-09-02 06:35:17 +04:00
nsAutoCString ( " PuppetWidget " ) , 0 ) ;
2010-08-21 03:24:40 +04:00
# endif
2015-05-11 07:22:51 +03:00
if ( mozilla : : layers : : LayersBackend : : LAYERS_CLIENT = = mLayerManager - > GetBackendType ( ) ) {
2013-05-01 09:03:25 +04:00
// Do nothing, the compositor will handle drawing
if ( mTabChild ) {
mTabChild - > NotifyPainted ( ) ;
}
2011-08-09 23:38:27 +04:00
} else {
2015-10-18 08:24:48 +03:00
RefPtr < gfxContext > ctx = new gfxContext ( mDrawTarget ) ;
2012-02-10 23:22:21 +04:00
ctx - > Rectangle ( gfxRect ( 0 , 0 , 0 , 0 ) ) ;
ctx - > Clip ( ) ;
2011-08-09 23:38:27 +04:00
AutoLayerManagerSetup setupLayerManager ( this , ctx ,
2014-01-23 22:26:41 +04:00
BufferMode : : BUFFER_NONE ) ;
2015-12-03 08:45:41 +03:00
GetCurrentWidgetListener ( ) - > PaintWindow ( this , region ) ;
2013-04-02 22:32:59 +04:00
if ( mTabChild ) {
mTabChild - > NotifyPainted ( ) ;
}
2011-08-09 23:38:27 +04:00
}
2010-08-21 03:24:40 +04:00
}
2015-07-22 04:09:02 +03:00
if ( GetCurrentWidgetListener ( ) ) {
GetCurrentWidgetListener ( ) - > DidPaintWindow ( ) ;
2012-12-13 01:57:08 +04:00
}
2010-08-21 03:24:40 +04:00
return NS_OK ;
}
void
PuppetWidget : : SetChild ( PuppetWidget * aChild )
{
2015-02-10 01:34:50 +03:00
MOZ_ASSERT ( this ! = aChild , " can't parent a widget to itself " ) ;
MOZ_ASSERT ( ! aChild - > mChild ,
" fake widget 'hierarchy' only expected to have one level " ) ;
2010-08-21 03:24:40 +04:00
mChild = aChild ;
}
NS_IMETHODIMP
PuppetWidget : : PaintTask : : Run ( )
{
if ( mWidget ) {
2012-08-15 22:52:42 +04:00
mWidget - > Paint ( ) ;
2010-08-21 03:24:40 +04:00
}
return NS_OK ;
}
2015-05-20 10:45:41 +03:00
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 ;
}
2015-07-14 11:32:05 +03:00
if ( strcmp ( " memory-pressure " , aTopic ) = = 0 & &
! NS_LITERAL_STRING ( " lowering-priority " ) . Equals ( aData ) ) {
2015-05-20 10:45:41 +03:00
if ( ! mWidget - > mVisible & & mWidget - > mLayerManager & &
2015-07-04 04:29:00 +03:00
XRE_IsContentProcess ( ) ) {
2015-05-20 10:45:41 +03:00
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 ;
}
2012-11-08 07:51:55 +04:00
bool
PuppetWidget : : NeedsPaint ( )
{
2014-11-20 20:28:58 +03:00
// e10s popups are handled by the parent process, so never should be painted here
2015-07-04 04:29:00 +03:00
if ( XRE_IsContentProcess ( ) & &
2014-11-20 20:28:58 +03:00
Preferences : : GetBool ( " browser.tabs.remote.desktopbehavior " , false ) & &
mWindowType = = eWindowType_popup ) {
NS_WARNING ( " Trying to paint an e10s popup in the child process! " ) ;
return false ;
}
2012-11-08 07:51:55 +04:00
return mVisible ;
}
2010-12-03 04:24:04 +03:00
float
PuppetWidget : : GetDPI ( )
{
if ( mDPI < 0 ) {
2013-04-02 22:32:59 +04:00
if ( mTabChild ) {
mTabChild - > GetDPI ( & mDPI ) ;
} else {
mDPI = 96.0 ;
}
2010-12-03 04:24:04 +03:00
}
return mDPI ;
}
2013-05-02 03:06:19 +04:00
double
PuppetWidget : : GetDefaultScaleInternal ( )
{
if ( mDefaultScale < 0 ) {
if ( mTabChild ) {
mTabChild - > GetDefaultScale ( & mDefaultScale ) ;
} else {
mDefaultScale = 1 ;
}
}
return mDefaultScale ;
}
2011-08-31 23:01:38 +04:00
void *
2012-08-22 19:56:38 +04:00
PuppetWidget : : GetNativeData ( uint32_t aDataType )
2011-08-31 23:01:38 +04:00
{
2012-05-09 01:36:07 +04:00
switch ( aDataType ) {
case NS_NATIVE_SHAREABLE_WINDOW : {
2015-02-10 01:34:50 +03:00
MOZ_ASSERT ( mTabChild , " Need TabChild to get the nativeWindow from! " ) ;
2012-07-20 15:16:17 +04:00
mozilla : : WindowsHandle nativeData = 0 ;
2013-04-02 22:32:59 +04:00
if ( mTabChild ) {
mTabChild - > SendGetWidgetNativeData ( & nativeData ) ;
}
2012-05-09 01:36:07 +04:00
return ( void * ) nativeData ;
}
2015-07-25 20:43:27 +03:00
case NS_NATIVE_WIDGET :
2012-05-09 01:36:07 +04:00
case NS_NATIVE_DISPLAY :
2015-07-25 20:43:27 +03:00
// These types are ignored (see bug 1183828).
break ;
2015-12-11 09:15:57 +03:00
case NS_RAW_NATIVE_IME_CONTEXT :
MOZ_CRASH ( " You need to call GetNativeIMEContext() instead " ) ;
2015-07-25 20:43:27 +03:00
case NS_NATIVE_WINDOW :
2012-05-09 01:36:07 +04:00
case NS_NATIVE_PLUGIN_PORT :
case NS_NATIVE_GRAPHIC :
case NS_NATIVE_SHELLWIDGET :
default :
NS_WARNING ( " nsWindow::GetNativeData called with bad value " ) ;
break ;
}
2012-07-30 18:20:58 +04:00
return nullptr ;
2012-05-09 01:36:07 +04:00
}
2015-08-12 18:00:26 +03:00
# 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
2014-12-11 17:44:07 +03:00
nsIntPoint
PuppetWidget : : GetChromeDimensions ( )
{
if ( ! GetOwningTabChild ( ) ) {
NS_WARNING ( " PuppetWidget without Tab does not have chrome information. " ) ;
return nsIntPoint ( ) ;
}
2015-11-07 06:13:40 +03:00
return GetOwningTabChild ( ) - > GetChromeDisplacement ( ) . ToUnknownPoint ( ) ;
2014-12-11 17:44:07 +03:00
}
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 ) ;
}
2015-03-31 23:39:02 +03:00
NS_METHOD
2015-11-13 03:04:52 +03:00
PuppetWidget : : GetScreenBounds ( LayoutDeviceIntRect & aRect ) {
aRect . MoveTo ( WidgetToScreenOffset ( ) ) ;
2015-11-23 07:32:29 +03:00
aRect . SizeTo ( mBounds . Size ( ) ) ;
2015-03-31 23:39:02 +03:00
return NS_OK ;
}
2015-05-08 04:29:00 +03:00
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 ;
}
2015-09-29 00:00:25 +03:00
void
PuppetWidget : : StartAsyncScrollbarDrag ( const AsyncDragMetrics & aDragMetrics )
{
mTabChild - > SendStartScrollbarDrag ( aDragMetrics ) ;
}
2012-05-09 01:36:07 +04:00
PuppetScreen : : PuppetScreen ( void * nativeScreen )
{
}
PuppetScreen : : ~ PuppetScreen ( )
{
}
static ScreenConfiguration
ScreenConfig ( )
{
ScreenConfiguration config ;
hal : : GetCurrentScreenConfiguration ( & config ) ;
return config ;
}
2014-12-11 17:44:07 +03:00
nsIntSize
PuppetWidget : : GetScreenDimensions ( )
{
nsIntRect r = ScreenConfig ( ) . rect ( ) ;
return nsIntSize ( r . width , r . height ) ;
}
2014-07-14 21:22:26 +04:00
NS_IMETHODIMP
PuppetScreen : : GetId ( uint32_t * outId )
{
* outId = 1 ;
return NS_OK ;
}
2012-05-09 01:36:07 +04:00
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
PuppetScreen : : GetRect ( int32_t * outLeft , int32_t * outTop ,
int32_t * outWidth , int32_t * outHeight )
2012-05-09 01:36:07 +04:00
{
nsIntRect r = ScreenConfig ( ) . rect ( ) ;
* outLeft = r . x ;
* outTop = r . y ;
* outWidth = r . width ;
* outHeight = r . height ;
return NS_OK ;
}
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
PuppetScreen : : GetAvailRect ( int32_t * outLeft , int32_t * outTop ,
int32_t * outWidth , int32_t * outHeight )
2012-05-09 01:36:07 +04:00
{
return GetRect ( outLeft , outTop , outWidth , outHeight ) ;
}
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
PuppetScreen : : GetPixelDepth ( int32_t * aPixelDepth )
2012-05-09 01:36:07 +04:00
{
* aPixelDepth = ScreenConfig ( ) . pixelDepth ( ) ;
return NS_OK ;
}
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
PuppetScreen : : GetColorDepth ( int32_t * aColorDepth )
2012-05-09 01:36:07 +04:00
{
* aColorDepth = ScreenConfig ( ) . colorDepth ( ) ;
return NS_OK ;
}
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
PuppetScreen : : GetRotation ( uint32_t * aRotation )
2012-05-09 01:36:07 +04:00
{
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
2012-08-22 19:56:38 +04:00
PuppetScreen : : SetRotation ( uint32_t aRotation )
2012-05-09 01:36:07 +04:00
{
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 ;
}
2014-04-27 11:06:00 +04:00
NS_IMPL_ISUPPORTS ( PuppetScreenManager , nsIScreenManager )
2012-05-09 01:36:07 +04:00
PuppetScreenManager : : PuppetScreenManager ( )
{
2012-07-30 18:20:58 +04:00
mOneScreen = new PuppetScreen ( nullptr ) ;
2012-05-09 01:36:07 +04:00
}
PuppetScreenManager : : ~ PuppetScreenManager ( )
{
}
2014-07-14 21:22:26 +04:00
NS_IMETHODIMP
PuppetScreenManager : : ScreenForId ( uint32_t aId ,
nsIScreen * * outScreen )
{
NS_IF_ADDREF ( * outScreen = mOneScreen . get ( ) ) ;
return NS_OK ;
}
2012-05-09 01:36:07 +04:00
NS_IMETHODIMP
PuppetScreenManager : : GetPrimaryScreen ( nsIScreen * * outScreen )
{
NS_IF_ADDREF ( * outScreen = mOneScreen . get ( ) ) ;
return NS_OK ;
}
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
PuppetScreenManager : : ScreenForRect ( int32_t inLeft ,
int32_t inTop ,
int32_t inWidth ,
int32_t inHeight ,
2012-05-09 01:36:07 +04:00
nsIScreen * * outScreen )
{
return GetPrimaryScreen ( outScreen ) ;
}
NS_IMETHODIMP
PuppetScreenManager : : ScreenForNativeWidget ( void * aWidget ,
nsIScreen * * outScreen )
{
return GetPrimaryScreen ( outScreen ) ;
}
NS_IMETHODIMP
2012-08-22 19:56:38 +04:00
PuppetScreenManager : : GetNumberOfScreens ( uint32_t * aNumberOfScreens )
2012-05-09 01:36:07 +04:00
{
* aNumberOfScreens = 1 ;
return NS_OK ;
2011-08-31 23:01:38 +04:00
}
2013-04-10 01:07:02 +04:00
NS_IMETHODIMP
PuppetScreenManager : : GetSystemDefaultScale ( float * aDefaultScale )
{
* aDefaultScale = 1.0f ;
return NS_OK ;
}
2015-07-22 04:09:02 +03:00
nsIWidgetListener *
PuppetWidget : : GetCurrentWidgetListener ( )
{
if ( ! mPreviouslyAttachedWidgetListener | |
! mAttachedWidgetListener ) {
return mAttachedWidgetListener ;
}
if ( mAttachedWidgetListener - > GetView ( ) - > IsPrimaryFramePaintSuppressed ( ) ) {
return mPreviouslyAttachedWidgetListener ;
}
return mAttachedWidgetListener ;
}
2015-12-29 16:57:38 +03:00
void
PuppetWidget : : SetCandidateWindowForPlugin ( int32_t aX , int32_t aY )
{
if ( ! mTabChild ) {
return ;
}
mTabChild - > SendSetCandidateWindowForPlugin ( aX , aY ) ;
}
2015-07-13 18:25:42 +03:00
} // namespace widget
} // namespace mozilla