2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-10-02 10:53:05 -04:00
# include "WebBrowserPrivatePCH.h"
# include "WebBrowserWindow.h"
2015-06-09 16:41:53 -04:00
# include "WebBrowserByteResource.h"
2015-07-06 15:27:08 -04:00
# include "WebBrowserPopupFeatures.h"
2015-07-30 10:49:18 -04:00
# include "WebBrowserDialog.h"
2015-06-25 16:56:38 -04:00
# include "WebJSScripting.h"
2015-01-05 08:54:59 -05:00
# include "RHI.h"
2014-10-02 10:53:05 -04:00
# if WITH_CEF3
2015-06-09 16:41:53 -04:00
# if PLATFORM_MAC
// Needed for character code definitions
# include <Carbon/Carbon.h>
# include <AppKit/NSEvent.h>
# endif
2015-06-30 11:54:52 -04:00
# if PLATFORM_WINDOWS
# include "WindowsCursor.h"
typedef FWindowsCursor FPlatformCursor ;
# elif PLATFORM_MAC
# include "MacCursor.h"
typedef FMacCursor FPlatformCursor ;
# else
# endif
2015-07-28 18:59:27 -04:00
FWebBrowserWindow : : FWebBrowserWindow ( CefRefPtr < CefBrowser > InBrowser , FString InUrl , TOptional < FString > InContentsToLoad , bool InShowErrorMessage , bool InThumbMouseButtonNavigation , bool InUseTransparency )
2015-03-13 08:26:18 -04:00
: DocumentState ( EWebBrowserDocumentState : : NoDocument )
2015-07-28 18:59:27 -04:00
, InternalCefBrowser ( InBrowser )
2015-04-09 15:23:52 -04:00
, CurrentUrl ( InUrl )
2015-07-28 18:59:27 -04:00
, ViewportSize ( FIntPoint : : ZeroValue )
2014-10-02 10:53:05 -04:00
, bIsClosing ( false )
2015-06-09 16:41:53 -04:00
, bIsInitialized ( false )
2015-04-09 15:23:52 -04:00
, ContentsToLoad ( InContentsToLoad )
2015-06-09 16:41:53 -04:00
, ShowErrorMessage ( InShowErrorMessage )
, bThumbMouseButtonNavigation ( InThumbMouseButtonNavigation )
2015-06-12 14:55:16 -04:00
, bUseTransparency ( InUseTransparency )
2015-06-09 16:41:53 -04:00
, Cursor ( EMouseCursor : : Default )
, bIsHidden ( false )
, bTickedLastFrame ( true )
, PreviousKeyDownEvent ( )
, PreviousKeyUpEvent ( )
, PreviousCharacterEvent ( )
, bIgnoreKeyDownEvent ( false )
, bIgnoreKeyUpEvent ( false )
, bIgnoreCharacterEvent ( false )
2015-07-13 11:46:44 -04:00
, bMainHasFocus ( false )
, bPopupHasFocus ( false )
2015-07-28 18:59:27 -04:00
, Scripting ( new FWebJSScripting ( InBrowser ) )
2014-10-02 10:53:05 -04:00
{
2015-07-28 18:59:27 -04:00
check ( InBrowser . get ( ) ! = nullptr ) ;
2015-07-13 11:46:44 -04:00
UpdatableTextures [ 0 ] = nullptr ;
UpdatableTextures [ 1 ] = nullptr ;
2014-10-02 10:53:05 -04:00
}
FWebBrowserWindow : : ~ FWebBrowserWindow ( )
{
2015-07-06 15:27:08 -04:00
CloseBrowser ( true ) ;
2015-07-13 11:46:44 -04:00
if ( FSlateApplication : : IsInitialized ( ) & & FSlateApplication : : Get ( ) . GetRenderer ( ) . IsValid ( ) )
2014-10-02 10:53:05 -04:00
{
2015-07-13 11:46:44 -04:00
for ( int I = 0 ; I < 1 ; + + I )
{
if ( UpdatableTextures [ I ] ! = nullptr )
{
FSlateApplication : : Get ( ) . GetRenderer ( ) - > ReleaseUpdatableTexture ( UpdatableTextures [ I ] ) ;
}
}
2014-10-02 10:53:05 -04:00
}
2015-07-13 11:46:44 -04:00
UpdatableTextures [ 0 ] = nullptr ;
UpdatableTextures [ 1 ] = nullptr ;
2014-10-02 10:53:05 -04:00
}
2014-12-17 09:20:23 -05:00
void FWebBrowserWindow : : LoadURL ( FString NewURL )
{
if ( IsValid ( ) )
{
CefRefPtr < CefFrame > MainFrame = InternalCefBrowser - > GetMainFrame ( ) ;
if ( MainFrame . get ( ) ! = nullptr )
{
2015-06-09 16:41:53 -04:00
ContentsToLoad = TOptional < FString > ( ) ;
2014-12-17 09:20:23 -05:00
CefString URL = * NewURL ;
MainFrame - > LoadURL ( URL ) ;
}
}
}
2015-01-20 16:49:52 -05:00
void FWebBrowserWindow : : LoadString ( FString Contents , FString DummyURL )
{
if ( IsValid ( ) )
{
CefRefPtr < CefFrame > MainFrame = InternalCefBrowser - > GetMainFrame ( ) ;
if ( MainFrame . get ( ) ! = nullptr )
{
2015-06-09 16:41:53 -04:00
ContentsToLoad = Contents ;
2015-01-20 16:49:52 -05:00
CefString URL = * DummyURL ;
2015-06-09 16:41:53 -04:00
MainFrame - > LoadURL ( URL ) ;
2015-01-20 16:49:52 -05:00
}
}
}
2015-01-05 08:54:59 -05:00
void FWebBrowserWindow : : SetViewportSize ( FIntPoint WindowSize )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
// SetViewportSize is called from the browser viewport tick method, which means that since we are receiving ticks, we can mark the browser as visible.
SetIsHidden ( false ) ;
bTickedLastFrame = true ;
2014-11-06 15:23:27 -05:00
// Ignore sizes that can't be seen as it forces CEF to re-render whole image
2015-01-05 08:54:59 -05:00
if ( WindowSize . X > 0 & & WindowSize . Y > 0 & & ViewportSize ! = WindowSize )
2014-10-02 10:53:05 -04:00
{
2015-01-05 08:54:59 -05:00
ViewportSize = MoveTemp ( WindowSize ) ;
2015-06-09 16:41:53 -04:00
2014-10-02 10:53:05 -04:00
if ( IsValid ( ) )
{
InternalCefBrowser - > GetHost ( ) - > WasResized ( ) ;
}
}
}
2015-07-13 11:46:44 -04:00
FSlateShaderResource * FWebBrowserWindow : : GetTexture ( bool bIsPopup )
2014-10-02 10:53:05 -04:00
{
2015-07-13 11:46:44 -04:00
if ( UpdatableTextures [ bIsPopup ? 1 : 0 ] ! = nullptr & & IsInitialized ( ) )
2014-10-02 10:53:05 -04:00
{
2015-07-13 11:46:44 -04:00
return UpdatableTextures [ bIsPopup ? 1 : 0 ] - > GetSlateResource ( ) ;
2014-10-02 10:53:05 -04:00
}
return nullptr ;
}
bool FWebBrowserWindow : : IsValid ( ) const
{
return InternalCefBrowser . get ( ) ! = nullptr ;
}
2015-06-09 16:41:53 -04:00
bool FWebBrowserWindow : : IsInitialized ( ) const
2014-11-06 15:23:27 -05:00
{
2015-06-09 16:41:53 -04:00
return bIsInitialized ;
2014-11-06 15:23:27 -05:00
}
2014-10-02 10:53:05 -04:00
bool FWebBrowserWindow : : IsClosing ( ) const
{
return bIsClosing ;
}
2015-03-13 08:26:18 -04:00
EWebBrowserDocumentState FWebBrowserWindow : : GetDocumentLoadingState ( ) const
{
return DocumentState ;
}
2014-10-02 10:53:05 -04:00
FString FWebBrowserWindow : : GetTitle ( ) const
{
return Title ;
}
2015-03-13 08:26:18 -04:00
FString FWebBrowserWindow : : GetUrl ( ) const
{
if ( InternalCefBrowser ! = nullptr )
{
CefRefPtr < CefFrame > MainFrame = InternalCefBrowser - > GetMainFrame ( ) ;
if ( MainFrame ! = nullptr )
{
2015-04-02 09:42:37 -04:00
return CurrentUrl ;
2015-03-13 08:26:18 -04:00
}
}
return FString ( ) ;
}
2015-06-09 16:41:53 -04:00
void FWebBrowserWindow : : PopulateCefKeyEvent ( const FKeyEvent & InKeyEvent , CefKeyEvent & OutKeyEvent )
2014-10-02 10:53:05 -04:00
{
2014-12-18 05:27:03 -05:00
# if PLATFORM_MAC
2015-06-09 16:41:53 -04:00
OutKeyEvent . native_key_code = InKeyEvent . GetKeyCode ( ) ;
FKey Key = InKeyEvent . GetKey ( ) ;
if ( Key = = EKeys : : BackSpace )
{
OutKeyEvent . unmodified_character = kBackspaceCharCode ;
}
else if ( Key = = EKeys : : Tab )
{
OutKeyEvent . unmodified_character = kTabCharCode ;
}
else if ( Key = = EKeys : : Enter )
{
OutKeyEvent . unmodified_character = kReturnCharCode ;
}
else if ( Key = = EKeys : : Pause )
{
OutKeyEvent . unmodified_character = NSPauseFunctionKey ;
}
else if ( Key = = EKeys : : Escape )
{
OutKeyEvent . unmodified_character = kEscapeCharCode ;
}
else if ( Key = = EKeys : : PageUp )
{
OutKeyEvent . unmodified_character = NSPageUpFunctionKey ;
}
else if ( Key = = EKeys : : PageDown )
{
OutKeyEvent . unmodified_character = NSPageDownFunctionKey ;
}
else if ( Key = = EKeys : : End )
{
OutKeyEvent . unmodified_character = NSEndFunctionKey ;
}
else if ( Key = = EKeys : : Home )
{
OutKeyEvent . unmodified_character = NSHomeFunctionKey ;
}
else if ( Key = = EKeys : : Left )
{
OutKeyEvent . unmodified_character = NSLeftArrowFunctionKey ;
}
else if ( Key = = EKeys : : Up )
{
OutKeyEvent . unmodified_character = NSUpArrowFunctionKey ;
}
else if ( Key = = EKeys : : Right )
{
OutKeyEvent . unmodified_character = NSRightArrowFunctionKey ;
}
else if ( Key = = EKeys : : Down )
{
OutKeyEvent . unmodified_character = NSDownArrowFunctionKey ;
}
else if ( Key = = EKeys : : Insert )
{
OutKeyEvent . unmodified_character = NSInsertFunctionKey ;
}
else if ( Key = = EKeys : : Delete )
{
OutKeyEvent . unmodified_character = kDeleteCharCode ;
}
else if ( Key = = EKeys : : F1 )
{
OutKeyEvent . unmodified_character = NSF1FunctionKey ;
}
else if ( Key = = EKeys : : F2 )
{
OutKeyEvent . unmodified_character = NSF2FunctionKey ;
}
else if ( Key = = EKeys : : F3 )
{
OutKeyEvent . unmodified_character = NSF3FunctionKey ;
}
else if ( Key = = EKeys : : F4 )
{
OutKeyEvent . unmodified_character = NSF4FunctionKey ;
}
else if ( Key = = EKeys : : F5 )
{
OutKeyEvent . unmodified_character = NSF5FunctionKey ;
}
else if ( Key = = EKeys : : F6 )
{
OutKeyEvent . unmodified_character = NSF6FunctionKey ;
}
else if ( Key = = EKeys : : F7 )
{
OutKeyEvent . unmodified_character = NSF7FunctionKey ;
}
else if ( Key = = EKeys : : F8 )
{
OutKeyEvent . unmodified_character = NSF8FunctionKey ;
}
else if ( Key = = EKeys : : F9 )
{
OutKeyEvent . unmodified_character = NSF9FunctionKey ;
}
else if ( Key = = EKeys : : F10 )
{
OutKeyEvent . unmodified_character = NSF10FunctionKey ;
}
else if ( Key = = EKeys : : F11 )
{
OutKeyEvent . unmodified_character = NSF11FunctionKey ;
}
else if ( Key = = EKeys : : F12 )
{
OutKeyEvent . unmodified_character = NSF12FunctionKey ;
}
else if ( Key = = EKeys : : CapsLock )
{
OutKeyEvent . unmodified_character = 0 ;
OutKeyEvent . native_key_code = kVK_CapsLock ;
}
else if ( Key . IsModifierKey ( ) )
{
// Setting both unmodified_character and character to 0 tells CEF that it needs to generate a NSFlagsChanged event instead of NSKeyDown/Up
OutKeyEvent . unmodified_character = 0 ;
// CEF expects modifier key codes as one of the Carbon kVK_* key codes.
if ( Key = = EKeys : : LeftCommand )
{
OutKeyEvent . native_key_code = kVK_Command ;
}
else if ( Key = = EKeys : : LeftShift )
{
OutKeyEvent . native_key_code = kVK_Shift ;
}
else if ( Key = = EKeys : : LeftAlt )
{
OutKeyEvent . native_key_code = kVK_Option ;
}
else if ( Key = = EKeys : : LeftControl )
{
OutKeyEvent . native_key_code = kVK_Control ;
}
else if ( Key = = EKeys : : RightCommand )
{
// There isn't a separate code for the right hand command key defined, but CEF seems to use the unused value before the left command keycode
OutKeyEvent . native_key_code = kVK_Command - 1 ;
}
else if ( Key = = EKeys : : RightShift )
{
OutKeyEvent . native_key_code = kVK_RightShift ;
}
else if ( Key = = EKeys : : RightAlt )
{
OutKeyEvent . native_key_code = kVK_RightOption ;
}
else if ( Key = = EKeys : : RightControl )
{
OutKeyEvent . native_key_code = kVK_RightControl ;
}
}
else
{
OutKeyEvent . unmodified_character = InKeyEvent . GetCharacter ( ) ;
}
OutKeyEvent . character = OutKeyEvent . unmodified_character ;
2014-12-18 05:27:03 -05:00
# else
2015-06-09 16:41:53 -04:00
OutKeyEvent . windows_key_code = InKeyEvent . GetKeyCode ( ) ;
2014-10-02 10:53:05 -04:00
// TODO: Figure out whether this is a system key if we come across problems
/*KeyEvent.is_system_key = message == WM_SYSCHAR ||
message = = WM_SYSKEYDOWN | |
message = = WM_SYSKEYUP ; */
2015-06-09 16:41:53 -04:00
# endif
2014-10-02 10:53:05 -04:00
2015-06-09 16:41:53 -04:00
OutKeyEvent . modifiers = GetCefKeyboardModifiers ( InKeyEvent ) ;
}
bool FWebBrowserWindow : : OnKeyDown ( const FKeyEvent & InKeyEvent )
{
if ( IsValid ( ) & & ! bIgnoreKeyDownEvent )
{
PreviousKeyDownEvent = InKeyEvent ;
CefKeyEvent KeyEvent ;
PopulateCefKeyEvent ( InKeyEvent , KeyEvent ) ;
2014-10-02 10:53:05 -04:00
KeyEvent . type = KEYEVENT_RAWKEYDOWN ;
InternalCefBrowser - > GetHost ( ) - > SendKeyEvent ( KeyEvent ) ;
2015-06-09 16:41:53 -04:00
return true ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
return false ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
bool FWebBrowserWindow : : OnKeyUp ( const FKeyEvent & InKeyEvent )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
if ( IsValid ( ) & & ! bIgnoreKeyUpEvent )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
PreviousKeyUpEvent = InKeyEvent ;
2014-10-02 10:53:05 -04:00
CefKeyEvent KeyEvent ;
2015-06-09 16:41:53 -04:00
PopulateCefKeyEvent ( InKeyEvent , KeyEvent ) ;
2014-10-02 10:53:05 -04:00
KeyEvent . type = KEYEVENT_KEYUP ;
InternalCefBrowser - > GetHost ( ) - > SendKeyEvent ( KeyEvent ) ;
2015-06-09 16:41:53 -04:00
return true ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
return false ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
bool FWebBrowserWindow : : OnKeyChar ( const FCharacterEvent & InCharacterEvent )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
if ( IsValid ( ) & & ! bIgnoreCharacterEvent )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
PreviousCharacterEvent = InCharacterEvent ;
2014-10-02 10:53:05 -04:00
CefKeyEvent KeyEvent ;
2014-12-18 05:27:03 -05:00
# if PLATFORM_MAC
KeyEvent . character = InCharacterEvent . GetCharacter ( ) ;
# else
2014-10-02 10:53:05 -04:00
KeyEvent . windows_key_code = InCharacterEvent . GetCharacter ( ) ;
2014-12-18 05:27:03 -05:00
# endif
2014-10-02 10:53:05 -04:00
// TODO: Figure out whether this is a system key if we come across problems
/*KeyEvent.is_system_key = message == WM_SYSCHAR ||
message = = WM_SYSKEYDOWN | |
message = = WM_SYSKEYUP ; */
KeyEvent . type = KEYEVENT_CHAR ;
KeyEvent . modifiers = GetCefInputModifiers ( InCharacterEvent ) ;
InternalCefBrowser - > GetHost ( ) - > SendKeyEvent ( KeyEvent ) ;
2015-06-09 16:41:53 -04:00
return true ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
return false ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
/* This is an ugly hack to inject unhandled key events back into Slate.
During processing of the initial keyboard event , we don ' t know whether it is handled by the Web browser or not .
Not until after CEF calls OnKeyEvent in our CefKeyboardHandler implementation , which is after our own keyboard event handler
has returned .
The solution is to save a copy of the event and re - inject it into Slate while ensuring that we ' ll ignore it and bubble it up
the widget hierarchy this time around . */
bool FWebBrowserWindow : : OnUnhandledKeyEvent ( const CefKeyEvent & CefEvent )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
bool bWasHandled = false ;
if ( IsValid ( ) )
{
switch ( CefEvent . type ) {
case KEYEVENT_RAWKEYDOWN :
case KEYEVENT_KEYDOWN :
if ( PreviousKeyDownEvent . IsSet ( ) )
{
bIgnoreKeyDownEvent = true ;
bWasHandled = FSlateApplication : : Get ( ) . ProcessKeyDownEvent ( PreviousKeyDownEvent . GetValue ( ) ) ;
PreviousKeyDownEvent . Reset ( ) ;
bIgnoreKeyDownEvent = false ;
}
break ;
case KEYEVENT_KEYUP :
if ( PreviousKeyUpEvent . IsSet ( ) )
{
bIgnoreKeyUpEvent = true ;
bWasHandled = FSlateApplication : : Get ( ) . ProcessKeyUpEvent ( PreviousKeyUpEvent . GetValue ( ) ) ;
PreviousKeyUpEvent . Reset ( ) ;
bIgnoreKeyUpEvent = false ;
}
break ;
case KEYEVENT_CHAR :
if ( PreviousCharacterEvent . IsSet ( ) )
{
bIgnoreCharacterEvent = true ;
bWasHandled = FSlateApplication : : Get ( ) . ProcessKeyCharEvent ( PreviousCharacterEvent . GetValue ( ) ) ;
PreviousCharacterEvent . Reset ( ) ;
bIgnoreCharacterEvent = false ;
}
break ;
default :
break ;
}
}
return bWasHandled ;
}
2015-06-12 14:55:16 -04:00
bool FWebBrowserWindow : : SupportsNewWindows ( )
{
return OnCreateWindow ( ) . IsBound ( ) ? true : false ;
}
2015-07-06 15:27:08 -04:00
bool FWebBrowserWindow : : RequestCreateWindow ( const TSharedRef < IWebBrowserWindow > & NewBrowserWindow , const TSharedPtr < IWebBrowserPopupFeatures > & BrowserPopupFeatures )
2015-06-12 14:55:16 -04:00
{
if ( OnCreateWindow ( ) . IsBound ( ) )
{
2015-07-06 15:27:08 -04:00
return OnCreateWindow ( ) . Execute ( TWeakPtr < IWebBrowserWindow > ( NewBrowserWindow ) , TWeakPtr < IWebBrowserPopupFeatures > ( BrowserPopupFeatures ) ) ;
2015-06-12 14:55:16 -04:00
}
return false ;
}
2015-07-30 10:49:18 -04:00
bool FWebBrowserWindow : : OnJSDialog ( CefJSDialogHandler : : JSDialogType DialogType , const CefString & MessageText , const CefString & DefaultPromptText , CefRefPtr < CefJSDialogCallback > Callback , bool & OutSuppressMessage )
{
bool Retval = false ;
if ( OnShowDialog ( ) . IsBound ( ) )
{
TSharedPtr < IWebBrowserDialog > Dialog ( new FWebBrowserDialog ( DialogType , MessageText , DefaultPromptText , Callback ) ) ;
EWebBrowserDialogEventResponse EventResponse = OnShowDialog ( ) . Execute ( TWeakPtr < IWebBrowserDialog > ( Dialog ) ) ;
switch ( EventResponse )
{
case EWebBrowserDialogEventResponse : : Handled :
Retval = true ;
break ;
case EWebBrowserDialogEventResponse : : Continue :
if ( DialogType = = JSDIALOGTYPE_ALERT )
{
// Alert dialogs don't return a value, so treat Continue the same way as Ingore
OutSuppressMessage = true ;
Retval = false ;
}
else
{
Callback - > Continue ( true , DefaultPromptText ) ;
Retval = true ;
}
break ;
case EWebBrowserDialogEventResponse : : Ignore :
OutSuppressMessage = true ;
Retval = false ;
break ;
case EWebBrowserDialogEventResponse : : Unhandled :
default :
Retval = false ;
break ;
}
}
return Retval ;
}
bool FWebBrowserWindow : : OnBeforeUnloadDialog ( const CefString & MessageText , bool IsReload , CefRefPtr < CefJSDialogCallback > Callback )
{
bool Retval = false ;
if ( OnShowDialog ( ) . IsBound ( ) )
{
TSharedPtr < IWebBrowserDialog > Dialog ( new FWebBrowserDialog ( MessageText , IsReload , Callback ) ) ;
EWebBrowserDialogEventResponse EventResponse = OnShowDialog ( ) . Execute ( TWeakPtr < IWebBrowserDialog > ( Dialog ) ) ;
switch ( EventResponse )
{
case EWebBrowserDialogEventResponse : : Handled :
Retval = true ;
break ;
case EWebBrowserDialogEventResponse : : Continue :
Callback - > Continue ( true , CefString ( ) ) ;
Retval = true ;
break ;
case EWebBrowserDialogEventResponse : : Ignore :
Callback - > Continue ( false , CefString ( ) ) ;
Retval = true ;
break ;
case EWebBrowserDialogEventResponse : : Unhandled :
default :
Retval = false ;
break ;
}
}
return Retval ;
}
void FWebBrowserWindow : : OnResetDialogState ( )
{
OnDismissAllDialogs ( ) . ExecuteIfBound ( ) ;
}
2015-07-13 11:46:44 -04:00
FReply FWebBrowserWindow : : OnMouseButtonDown ( const FGeometry & MyGeometry , const FPointerEvent & MouseEvent , bool bIsPopup )
2015-06-09 16:41:53 -04:00
{
FReply Reply = FReply : : Unhandled ( ) ;
2014-10-02 10:53:05 -04:00
if ( IsValid ( ) )
{
FKey Button = MouseEvent . GetEffectingButton ( ) ;
2015-06-09 16:41:53 -04:00
// CEF only supports left, right, and middle mouse buttons
bool bIsCefSupportedButton = ( Button = = EKeys : : LeftMouseButton | | Button = = EKeys : : RightMouseButton | | Button = = EKeys : : MiddleMouseButton ) ;
if ( bIsCefSupportedButton )
{
2014-10-02 10:53:05 -04:00
CefBrowserHost : : MouseButtonType Type =
( Button = = EKeys : : LeftMouseButton ? MBT_LEFT : (
Button = = EKeys : : RightMouseButton ? MBT_RIGHT : MBT_MIDDLE ) ) ;
2015-07-13 11:46:44 -04:00
CefMouseEvent Event = GetCefMouseEvent ( MyGeometry , MouseEvent , bIsPopup ) ;
2014-10-02 10:53:05 -04:00
InternalCefBrowser - > GetHost ( ) - > SendMouseClickEvent ( Event , Type , false , 1 ) ;
2015-06-09 16:41:53 -04:00
Reply = FReply : : Handled ( ) ;
}
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
return Reply ;
2014-10-02 10:53:05 -04:00
}
2015-07-13 11:46:44 -04:00
FReply FWebBrowserWindow : : OnMouseButtonUp ( const FGeometry & MyGeometry , const FPointerEvent & MouseEvent , bool bIsPopup )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
FReply Reply = FReply : : Unhandled ( ) ;
2014-10-02 10:53:05 -04:00
if ( IsValid ( ) )
{
FKey Button = MouseEvent . GetEffectingButton ( ) ;
2015-06-09 16:41:53 -04:00
// CEF only supports left, right, and middle mouse buttons
bool bIsCefSupportedButton = ( Button = = EKeys : : LeftMouseButton | | Button = = EKeys : : RightMouseButton | | Button = = EKeys : : MiddleMouseButton ) ;
if ( bIsCefSupportedButton )
{
2014-10-02 10:53:05 -04:00
CefBrowserHost : : MouseButtonType Type =
( Button = = EKeys : : LeftMouseButton ? MBT_LEFT : (
Button = = EKeys : : RightMouseButton ? MBT_RIGHT : MBT_MIDDLE ) ) ;
2015-07-13 11:46:44 -04:00
CefMouseEvent Event = GetCefMouseEvent ( MyGeometry , MouseEvent , bIsPopup ) ;
2014-10-02 10:53:05 -04:00
InternalCefBrowser - > GetHost ( ) - > SendMouseClickEvent ( Event , Type , true , 1 ) ;
2015-06-09 16:41:53 -04:00
Reply = FReply : : Handled ( ) ;
}
else if ( Button = = EKeys : : ThumbMouseButton & & bThumbMouseButtonNavigation )
{
if ( CanGoBack ( ) )
{
GoBack ( ) ;
Reply = FReply : : Handled ( ) ;
}
}
else if ( Button = = EKeys : : ThumbMouseButton2 & & bThumbMouseButtonNavigation )
{
if ( CanGoForward ( ) )
{
GoForward ( ) ;
Reply = FReply : : Handled ( ) ;
}
}
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
return Reply ;
2014-10-02 10:53:05 -04:00
}
2015-07-13 11:46:44 -04:00
FReply FWebBrowserWindow : : OnMouseButtonDoubleClick ( const FGeometry & MyGeometry , const FPointerEvent & MouseEvent , bool bIsPopup )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
FReply Reply = FReply : : Unhandled ( ) ;
2014-10-02 10:53:05 -04:00
if ( IsValid ( ) )
{
FKey Button = MouseEvent . GetEffectingButton ( ) ;
2015-06-09 16:41:53 -04:00
// CEF only supports left, right, and middle mouse buttons
bool bIsCefSupportedButton = ( Button = = EKeys : : LeftMouseButton | | Button = = EKeys : : RightMouseButton | | Button = = EKeys : : MiddleMouseButton ) ;
if ( bIsCefSupportedButton )
{
2014-10-02 10:53:05 -04:00
CefBrowserHost : : MouseButtonType Type =
( Button = = EKeys : : LeftMouseButton ? MBT_LEFT : (
Button = = EKeys : : RightMouseButton ? MBT_RIGHT : MBT_MIDDLE ) ) ;
2015-07-13 11:46:44 -04:00
CefMouseEvent Event = GetCefMouseEvent ( MyGeometry , MouseEvent , bIsPopup ) ;
2014-10-02 10:53:05 -04:00
InternalCefBrowser - > GetHost ( ) - > SendMouseClickEvent ( Event , Type , false , 2 ) ;
2015-06-09 16:41:53 -04:00
Reply = FReply : : Handled ( ) ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
}
return Reply ;
2014-10-02 10:53:05 -04:00
}
2015-07-13 11:46:44 -04:00
FReply FWebBrowserWindow : : OnMouseMove ( const FGeometry & MyGeometry , const FPointerEvent & MouseEvent , bool bIsPopup )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
FReply Reply = FReply : : Unhandled ( ) ;
2014-10-02 10:53:05 -04:00
if ( IsValid ( ) )
{
2015-07-13 11:46:44 -04:00
CefMouseEvent Event = GetCefMouseEvent ( MyGeometry , MouseEvent , bIsPopup ) ;
2014-10-02 10:53:05 -04:00
InternalCefBrowser - > GetHost ( ) - > SendMouseMoveEvent ( Event , false ) ;
2015-06-09 16:41:53 -04:00
Reply = FReply : : Handled ( ) ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
return Reply ;
2014-10-02 10:53:05 -04:00
}
2015-07-13 11:46:44 -04:00
FReply FWebBrowserWindow : : OnMouseWheel ( const FGeometry & MyGeometry , const FPointerEvent & MouseEvent , bool bIsPopup )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
FReply Reply = FReply : : Unhandled ( ) ;
2014-10-02 10:53:05 -04:00
if ( IsValid ( ) )
{
// The original delta is reduced so this should bring it back to what CEF expects
2015-06-09 16:41:53 -04:00
const float SpinFactor = 50.0f ;
2014-10-02 10:53:05 -04:00
const float TrueDelta = MouseEvent . GetWheelDelta ( ) * SpinFactor ;
2015-07-13 11:46:44 -04:00
CefMouseEvent Event = GetCefMouseEvent ( MyGeometry , MouseEvent , bIsPopup ) ;
2014-10-02 10:53:05 -04:00
InternalCefBrowser - > GetHost ( ) - > SendMouseWheelEvent ( Event ,
MouseEvent . IsShiftDown ( ) ? TrueDelta : 0 ,
! MouseEvent . IsShiftDown ( ) ? TrueDelta : 0 ) ;
2015-06-09 16:41:53 -04:00
Reply = FReply : : Handled ( ) ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
return Reply ;
2014-10-02 10:53:05 -04:00
}
2015-07-13 11:46:44 -04:00
void FWebBrowserWindow : : OnFocus ( bool SetFocus , bool bIsPopup )
2014-10-02 10:53:05 -04:00
{
2015-07-13 11:46:44 -04:00
if ( bIsPopup )
2014-10-02 10:53:05 -04:00
{
2015-07-13 11:46:44 -04:00
bPopupHasFocus = SetFocus ;
}
else
{
bMainHasFocus = SetFocus ;
}
// Only notify focus if there is no popup menu with focus, as SendFocusEvent will dismiss any popup menus.
if ( IsValid ( ) & & ! bPopupHasFocus )
{
InternalCefBrowser - > GetHost ( ) - > SendFocusEvent ( bMainHasFocus ) ;
2014-10-02 10:53:05 -04:00
}
}
void FWebBrowserWindow : : OnCaptureLost ( )
{
if ( IsValid ( ) )
{
InternalCefBrowser - > GetHost ( ) - > SendCaptureLostEvent ( ) ;
}
}
bool FWebBrowserWindow : : CanGoBack ( ) const
{
if ( IsValid ( ) )
{
return InternalCefBrowser - > CanGoBack ( ) ;
}
return false ;
}
void FWebBrowserWindow : : GoBack ( )
{
if ( IsValid ( ) )
{
InternalCefBrowser - > GoBack ( ) ;
}
}
bool FWebBrowserWindow : : CanGoForward ( ) const
{
if ( IsValid ( ) )
{
return InternalCefBrowser - > CanGoForward ( ) ;
}
return false ;
}
void FWebBrowserWindow : : GoForward ( )
{
if ( IsValid ( ) )
{
InternalCefBrowser - > GoForward ( ) ;
}
}
bool FWebBrowserWindow : : IsLoading ( ) const
{
if ( IsValid ( ) )
{
return InternalCefBrowser - > IsLoading ( ) ;
}
return false ;
}
void FWebBrowserWindow : : Reload ( )
{
if ( IsValid ( ) )
{
InternalCefBrowser - > Reload ( ) ;
}
}
void FWebBrowserWindow : : StopLoad ( )
{
if ( IsValid ( ) )
{
InternalCefBrowser - > StopLoad ( ) ;
}
}
2015-05-22 15:17:48 -04:00
void FWebBrowserWindow : : ExecuteJavascript ( const FString & Script )
{
if ( IsValid ( ) )
{
CefRefPtr < CefFrame > frame = InternalCefBrowser - > GetMainFrame ( ) ;
frame - > ExecuteJavaScript ( TCHAR_TO_ANSI ( * Script ) , frame - > GetURL ( ) , 0 ) ;
}
}
2014-10-02 10:53:05 -04:00
2015-07-06 15:27:08 -04:00
void FWebBrowserWindow : : CloseBrowser ( bool bForce )
2014-10-02 10:53:05 -04:00
{
if ( IsValid ( ) )
{
2015-07-06 15:27:08 -04:00
InternalCefBrowser - > GetHost ( ) - > CloseBrowser ( bForce ) ;
2014-10-02 10:53:05 -04:00
}
}
2015-06-09 16:41:53 -04:00
CefRefPtr < CefBrowser > FWebBrowserWindow : : GetCefBrowser ( )
{
return InternalCefBrowser ;
}
2014-10-02 10:53:05 -04:00
void FWebBrowserWindow : : SetTitle ( const CefString & InTitle )
{
2014-11-21 13:41:17 -05:00
Title = InTitle . ToWString ( ) . c_str ( ) ;
2015-02-13 15:52:26 -05:00
TitleChangedEvent . Broadcast ( Title ) ;
2014-10-02 10:53:05 -04:00
}
2015-04-02 09:42:37 -04:00
void FWebBrowserWindow : : SetUrl ( const CefString & Url )
{
CurrentUrl = Url . ToWString ( ) . c_str ( ) ;
OnUrlChanged ( ) . Broadcast ( CurrentUrl ) ;
}
2015-06-09 16:41:53 -04:00
void FWebBrowserWindow : : SetToolTip ( const CefString & CefToolTip )
{
FString NewToolTipText = CefToolTip . ToWString ( ) . c_str ( ) ;
if ( ToolTipText ! = NewToolTipText )
{
ToolTipText = NewToolTipText ;
OnToolTip ( ) . Broadcast ( ToolTipText ) ;
}
}
2014-10-02 10:53:05 -04:00
bool FWebBrowserWindow : : GetViewRect ( CefRect & Rect )
{
Rect . x = 0 ;
Rect . y = 0 ;
2015-07-27 11:06:35 -04:00
if ( ViewportSize = = FIntPoint : : ZeroValue )
{
// We need to return a dummy size until we know the final size of the viewport. Otherwise, popup menus may not work.
Rect . width = 1024 ;
Rect . height = 1024 ;
}
else
{
Rect . width = ViewportSize . X ;
Rect . height = ViewportSize . Y ;
}
2014-10-02 10:53:05 -04:00
return true ;
}
2015-03-13 08:26:18 -04:00
void FWebBrowserWindow : : NotifyDocumentError ( )
{
DocumentState = EWebBrowserDocumentState : : Error ;
DocumentStateChangedEvent . Broadcast ( DocumentState ) ;
}
void FWebBrowserWindow : : NotifyDocumentLoadingStateChange ( bool IsLoading )
{
2015-06-09 16:41:53 -04:00
if ( ! IsLoading )
{
bIsInitialized = true ;
}
2015-03-13 08:26:18 -04:00
EWebBrowserDocumentState NewState = IsLoading
? EWebBrowserDocumentState : : Loading
: EWebBrowserDocumentState : : Completed ;
if ( DocumentState ! = EWebBrowserDocumentState : : Error )
{
DocumentState = NewState ;
}
DocumentStateChangedEvent . Broadcast ( NewState ) ;
}
2014-10-02 10:53:05 -04:00
void FWebBrowserWindow : : OnPaint ( CefRenderHandler : : PaintElementType Type , const CefRenderHandler : : RectList & DirtyRects , const void * Buffer , int Width , int Height )
{
2015-07-13 11:46:44 -04:00
if ( UpdatableTextures [ Type ] = = nullptr & & FSlateApplication : : IsInitialized ( ) & & FSlateApplication : : Get ( ) . GetRenderer ( ) . IsValid ( ) )
2015-06-12 14:55:16 -04:00
{
2015-07-13 11:46:44 -04:00
UpdatableTextures [ Type ] = FSlateApplication : : Get ( ) . GetRenderer ( ) - > CreateUpdatableTexture ( Width , Height ) ;
2015-06-12 14:55:16 -04:00
}
2015-07-13 11:46:44 -04:00
if ( UpdatableTextures [ Type ] ! = nullptr )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
// Note that with more recent versions of CEF, the DirtyRects will always contain a single element, as it merges all dirty areas into a single rectangle before calling OnPaint
// In case that should change in the future, we'll simply update the entire area if DirtyRects is not a single element.
FIntRect Dirty = ( DirtyRects . size ( ) = = 1 ) ? FIntRect ( DirtyRects [ 0 ] . x , DirtyRects [ 0 ] . y , DirtyRects [ 0 ] . x + DirtyRects [ 0 ] . width , DirtyRects [ 0 ] . y + DirtyRects [ 0 ] . height ) : FIntRect ( ) ;
2015-07-13 11:46:44 -04:00
UpdatableTextures [ Type ] - > UpdateTextureThreadSafeRaw ( Width , Height , Buffer , Dirty ) ;
2014-10-02 10:53:05 -04:00
}
2014-10-07 09:58:47 -04:00
2015-07-27 11:06:35 -04:00
if ( Type = = PET_POPUP & & bShowPopupRequested )
{
bShowPopupRequested = false ;
bPopupHasFocus = true ;
FIntPoint PopupSize = FIntPoint ( Width , Height ) ;
FIntRect PopupRect = FIntRect ( PopupPosition , PopupPosition + PopupSize ) ;
OnShowPopup ( ) . Broadcast ( PopupRect ) ;
}
2015-06-09 16:41:53 -04:00
bIsInitialized = true ;
NeedsRedrawEvent . Broadcast ( ) ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
void FWebBrowserWindow : : OnCursorChange ( CefCursorHandle CefCursor , CefRenderHandler : : CursorType Type , const CefCursorInfo & CustomCursorInfo )
2014-10-02 10:53:05 -04:00
{
2015-06-09 16:41:53 -04:00
switch ( Type ) {
2015-06-30 11:54:52 -04:00
// Map the basic 3 cursor types directly to Slate types on all platforms
2015-06-09 16:41:53 -04:00
case CT_NONE :
Cursor = EMouseCursor : : None ;
break ;
2015-06-30 11:54:52 -04:00
case CT_POINTER :
Cursor = EMouseCursor : : Default ;
break ;
2015-06-09 16:41:53 -04:00
case CT_IBEAM :
2015-06-30 11:54:52 -04:00
Cursor = EMouseCursor : : TextEditBeam ;
break ;
# if PLATFORM_WINDOWS || PLATFORM_MAC
// Platform specific support for native cursor types
default :
{
FPlatformCursor * PlatformCursor = ( FPlatformCursor * ) FSlateApplication : : Get ( ) . GetPlatformCursor ( ) . Get ( ) ;
PlatformCursor - > SetCustomShape ( CefCursor ) ;
Cursor = EMouseCursor : : Custom ;
}
break ;
# else
// Map to closest Slate equivalent on platforms where native cursors are not available.
2015-06-09 16:41:53 -04:00
case CT_VERTICALTEXT :
Cursor = EMouseCursor : : TextEditBeam ;
break ;
case CT_EASTRESIZE :
case CT_WESTRESIZE :
case CT_EASTWESTRESIZE :
case CT_COLUMNRESIZE :
Cursor = EMouseCursor : : ResizeLeftRight ;
break ;
case CT_NORTHRESIZE :
case CT_SOUTHRESIZE :
case CT_NORTHSOUTHRESIZE :
case CT_ROWRESIZE :
Cursor = EMouseCursor : : ResizeUpDown ;
break ;
case CT_NORTHWESTRESIZE :
case CT_SOUTHEASTRESIZE :
case CT_NORTHWESTSOUTHEASTRESIZE :
Cursor = EMouseCursor : : ResizeSouthEast ;
break ;
case CT_NORTHEASTRESIZE :
case CT_SOUTHWESTRESIZE :
case CT_NORTHEASTSOUTHWESTRESIZE :
Cursor = EMouseCursor : : ResizeSouthWest ;
break ;
case CT_MOVE :
case CT_MIDDLEPANNING :
case CT_EASTPANNING :
case CT_NORTHPANNING :
case CT_NORTHEASTPANNING :
case CT_NORTHWESTPANNING :
case CT_SOUTHPANNING :
case CT_SOUTHEASTPANNING :
case CT_SOUTHWESTPANNING :
case CT_WESTPANNING :
Cursor = EMouseCursor : : CardinalCross ;
break ;
case CT_CROSS :
Cursor = EMouseCursor : : Crosshairs ;
break ;
case CT_HAND :
Cursor = EMouseCursor : : Hand ;
break ;
case CT_GRAB :
Cursor = EMouseCursor : : GrabHand ;
break ;
case CT_GRABBING :
Cursor = EMouseCursor : : GrabHandClosed ;
break ;
case CT_NOTALLOWED :
case CT_NODROP :
Cursor = EMouseCursor : : SlashedCircle ;
break ;
default :
Cursor = EMouseCursor : : Default ;
break ;
2015-06-30 11:54:52 -04:00
# endif
2015-06-09 16:41:53 -04:00
}
// Tell Slate to update the cursor now
FSlateApplication : : Get ( ) . QueryCursor ( ) ;
2014-10-02 10:53:05 -04:00
}
2015-06-09 16:41:53 -04:00
bool FWebBrowserWindow : : OnBeforeBrowse ( CefRefPtr < CefBrowser > Browser , CefRefPtr < CefFrame > Frame , CefRefPtr < CefRequest > Request , bool bIsRedirect )
{
if ( InternalCefBrowser ! = nullptr & & InternalCefBrowser - > IsSame ( Browser ) )
{
CefRefPtr < CefFrame > MainFrame = InternalCefBrowser - > GetMainFrame ( ) ;
if ( MainFrame . get ( ) ! = nullptr )
{
if ( OnBeforeBrowse ( ) . IsBound ( ) )
{
FString Url = Request - > GetURL ( ) . ToWString ( ) . c_str ( ) ;
return OnBeforeBrowse ( ) . Execute ( Url , bIsRedirect ) ;
}
}
}
return false ;
}
CefRefPtr < CefResourceHandler > FWebBrowserWindow : : GetResourceHandler ( CefRefPtr < CefFrame > Frame , CefRefPtr < CefRequest > Request )
{
if ( ContentsToLoad . IsSet ( ) )
{
FTCHARToUTF8 Convert ( * ContentsToLoad . GetValue ( ) ) ;
CefRefPtr < CefResourceHandler > Resource = new FWebBrowserByteResource ( Convert . Get ( ) , Convert . Length ( ) ) ;
ContentsToLoad = TOptional < FString > ( ) ;
return Resource ;
}
if ( OnLoadUrl ( ) . IsBound ( ) )
{
FString Method = Request - > GetMethod ( ) . ToWString ( ) . c_str ( ) ;
FString Url = Request - > GetURL ( ) . ToWString ( ) . c_str ( ) ;
FString Response ;
if ( OnLoadUrl ( ) . Execute ( Method , Url , Response ) )
{
FTCHARToUTF8 Convert ( * Response ) ;
CefRefPtr < CefResourceHandler > Resource = new FWebBrowserByteResource ( Convert . Get ( ) , Convert . Length ( ) ) ;
return Resource ;
}
}
return NULL ;
}
2014-10-30 12:29:36 -04:00
int32 FWebBrowserWindow : : GetCefKeyboardModifiers ( const FKeyEvent & KeyEvent )
2014-10-02 10:53:05 -04:00
{
2014-10-30 12:29:36 -04:00
int32 Modifiers = GetCefInputModifiers ( KeyEvent ) ;
2014-10-02 10:53:05 -04:00
2014-10-30 12:29:36 -04:00
const FKey Key = KeyEvent . GetKey ( ) ;
2014-10-02 10:53:05 -04:00
if ( Key = = EKeys : : LeftAlt | |
Key = = EKeys : : LeftCommand | |
Key = = EKeys : : LeftControl | |
Key = = EKeys : : LeftShift )
{
Modifiers | = EVENTFLAG_IS_LEFT ;
}
if ( Key = = EKeys : : RightAlt | |
Key = = EKeys : : RightCommand | |
Key = = EKeys : : RightControl | |
Key = = EKeys : : RightShift )
{
Modifiers | = EVENTFLAG_IS_RIGHT ;
}
if ( Key = = EKeys : : NumPadZero | |
Key = = EKeys : : NumPadOne | |
Key = = EKeys : : NumPadTwo | |
Key = = EKeys : : NumPadThree | |
Key = = EKeys : : NumPadFour | |
Key = = EKeys : : NumPadFive | |
Key = = EKeys : : NumPadSix | |
Key = = EKeys : : NumPadSeven | |
Key = = EKeys : : NumPadEight | |
Key = = EKeys : : NumPadNine )
{
Modifiers | = EVENTFLAG_IS_KEY_PAD ;
}
return Modifiers ;
}
int32 FWebBrowserWindow : : GetCefMouseModifiers ( const FPointerEvent & InMouseEvent )
{
int32 Modifiers = GetCefInputModifiers ( InMouseEvent ) ;
if ( InMouseEvent . IsMouseButtonDown ( EKeys : : LeftMouseButton ) )
{
Modifiers | = EVENTFLAG_LEFT_MOUSE_BUTTON ;
}
if ( InMouseEvent . IsMouseButtonDown ( EKeys : : MiddleMouseButton ) )
{
Modifiers | = EVENTFLAG_MIDDLE_MOUSE_BUTTON ;
}
if ( InMouseEvent . IsMouseButtonDown ( EKeys : : RightMouseButton ) )
{
Modifiers | = EVENTFLAG_RIGHT_MOUSE_BUTTON ;
}
return Modifiers ;
}
2015-07-13 11:46:44 -04:00
CefMouseEvent FWebBrowserWindow : : GetCefMouseEvent ( const FGeometry & MyGeometry , const FPointerEvent & MouseEvent , bool bIsPopup )
{
CefMouseEvent Event ;
FVector2D LocalPos = MyGeometry . AbsoluteToLocal ( MouseEvent . GetScreenSpacePosition ( ) ) ;
if ( bIsPopup )
{
2015-07-27 11:06:35 -04:00
LocalPos + = PopupPosition ;
2015-07-13 11:46:44 -04:00
}
2015-07-27 11:06:35 -04:00
Event . x = LocalPos . X ;
Event . y = LocalPos . Y ;
2015-07-13 11:46:44 -04:00
Event . modifiers = GetCefMouseModifiers ( MouseEvent ) ;
return Event ;
}
2014-10-02 10:53:05 -04:00
int32 FWebBrowserWindow : : GetCefInputModifiers ( const FInputEvent & InputEvent )
{
int32 Modifiers = 0 ;
if ( InputEvent . IsShiftDown ( ) )
{
Modifiers | = EVENTFLAG_SHIFT_DOWN ;
}
if ( InputEvent . IsControlDown ( ) )
{
2015-06-09 16:41:53 -04:00
# if PLATFORM_MAC
// Slate swaps the flags for Command and Control on OSX, so we need to swap them back for CEF
Modifiers | = EVENTFLAG_COMMAND_DOWN ;
# else
2014-10-02 10:53:05 -04:00
Modifiers | = EVENTFLAG_CONTROL_DOWN ;
2015-06-09 16:41:53 -04:00
# endif
2014-10-02 10:53:05 -04:00
}
if ( InputEvent . IsAltDown ( ) )
{
Modifiers | = EVENTFLAG_ALT_DOWN ;
}
if ( InputEvent . IsCommandDown ( ) )
{
2015-06-09 16:41:53 -04:00
# if PLATFORM_MAC
// Slate swaps the flags for Command and Control on OSX, so we need to swap them back for CEF
Modifiers | = EVENTFLAG_CONTROL_DOWN ;
# else
2014-10-02 10:53:05 -04:00
Modifiers | = EVENTFLAG_COMMAND_DOWN ;
2015-06-09 16:41:53 -04:00
# endif
2014-10-02 10:53:05 -04:00
}
if ( InputEvent . AreCapsLocked ( ) )
{
Modifiers | = EVENTFLAG_CAPS_LOCK_ON ;
}
// TODO: Add function for this if necessary
/*if (InputEvent.AreNumsLocked())
{
Modifiers | = EVENTFLAG_NUM_LOCK_ON ;
} */
return Modifiers ;
}
2015-06-09 16:41:53 -04:00
void FWebBrowserWindow : : CheckTickActivity ( )
{
// Early out if we're currently hidden, not initialized or currently loading.
if ( bIsHidden | | ! IsValid ( ) | | IsLoading ( ) | | ViewportSize = = FIntPoint : : ZeroValue )
{
return ;
}
// We clear the bTickedLastFrame flag here and set it on every Slate tick.
// If it's still clear when we come back it means we're not getting ticks from slate.
// Note: The BrowserSingleton object will not invoke this method if Slate itself is sleeping.
// Therefore we can safely assume the widget is hidden in that case.
if ( ! bTickedLastFrame )
{
SetIsHidden ( true ) ;
}
bTickedLastFrame = false ;
}
void FWebBrowserWindow : : SetIsHidden ( bool bValue )
{
if ( bIsHidden = = bValue )
{
return ;
}
bIsHidden = bValue ;
if ( IsValid ( ) )
{
InternalCefBrowser - > GetHost ( ) - > WasHidden ( bIsHidden ) ;
}
}
2015-06-25 16:56:38 -04:00
CefRefPtr < CefDictionaryValue > FWebBrowserWindow : : GetProcessInfo ( )
{
CefRefPtr < CefDictionaryValue > Retval = nullptr ;
if ( IsValid ( ) )
{
Retval = CefDictionaryValue : : Create ( ) ;
Retval - > SetInt ( " browser " , InternalCefBrowser - > GetIdentifier ( ) ) ;
Retval - > SetDictionary ( " bindings " , Scripting - > GetPermanentBindings ( ) ) ;
}
return Retval ;
}
bool FWebBrowserWindow : : OnProcessMessageReceived ( CefRefPtr < CefBrowser > Browser , CefProcessId SourceProcess , CefRefPtr < CefProcessMessage > Message )
{
return Scripting - > OnProcessMessageReceived ( Browser , SourceProcess , Message ) ;
}
void FWebBrowserWindow : : BindUObject ( const FString & Name , UObject * Object , bool bIsPermanent )
{
Scripting - > BindUObject ( Name , Object , bIsPermanent ) ;
}
void FWebBrowserWindow : : UnbindUObject ( const FString & Name , UObject * Object , bool bIsPermanent )
{
Scripting - > UnbindUObject ( Name , Object , bIsPermanent ) ;
}
2015-05-22 15:17:48 -04:00
bool FWebBrowserWindow : : OnCefBeforePopup ( const CefString & Target_Url , const CefString & Target_Frame_Name )
{
if ( OnBeforePopup ( ) . IsBound ( ) )
{
FString URL = Target_Url . ToWString ( ) . c_str ( ) ;
FString FrameName = Target_Frame_Name . ToWString ( ) . c_str ( ) ;
return OnBeforePopup ( ) . Execute ( URL , FrameName ) ;
}
return false ;
}
2015-07-06 15:27:08 -04:00
void FWebBrowserWindow : : OnBrowserClosing ( )
{
bIsClosing = true ;
}
void FWebBrowserWindow : : OnBrowserClosed ( )
{
if ( OnCloseWindow ( ) . IsBound ( ) )
{
OnCloseWindow ( ) . Execute ( TWeakPtr < IWebBrowserWindow > ( SharedThis ( this ) ) ) ;
}
Scripting - > UnbindCefBrowser ( ) ;
InternalCefBrowser = nullptr ;
}
2015-07-27 11:06:35 -04:00
void FWebBrowserWindow : : SetPopupMenuPosition ( CefRect CefPopupSize )
2015-07-13 11:46:44 -04:00
{
2015-07-27 11:06:35 -04:00
// We only store the position, as the size will be provided ib the OnPaint call.
PopupPosition = FIntPoint ( CefPopupSize . x , CefPopupSize . y ) ;
2015-07-13 11:46:44 -04:00
}
2015-07-27 11:06:35 -04:00
void FWebBrowserWindow : : ShowPopupMenu ( bool bShow )
2015-07-13 11:46:44 -04:00
{
2015-07-27 11:06:35 -04:00
if ( bShow )
{
bShowPopupRequested = true ; // We have to delay showing the popup until we get the first OnPaint on it.
}
else
{
bPopupHasFocus = false ;
bShowPopupRequested = false ;
OnDismissPopup ( ) . Broadcast ( ) ;
}
2015-07-13 11:46:44 -04:00
}
2014-10-02 10:53:05 -04:00
# endif