unit uCEFWindowInfoWrapper; {$IFDEF FPC} {$MODE OBJFPC}{$H+} {$ENDIF} {$I cef.inc} {$IFNDEF TARGET_64BITS}{$ALIGN ON}{$ENDIF} {$MINENUMSIZE 4} interface uses {$IFDEF DELPHI16_UP} {$IFDEF MSWINDOWS}WinApi.Windows,{$ENDIF}System.Classes, System.Types, {$ELSE} {$IFDEF MSWINDOWS}Windows,{$ENDIF}Classes, Types, {$ENDIF} uCEFTypes; type /// /// Wrapper class used to initialize a TCEFWindowInfo record. /// /// /// CEF source file: /include/internal/cef_win.h (CefWindowInfo) /// CEF source file: /include/internal/cef_mac.h (CefWindowInfo) /// CEF source file: /include/internal/cef_linux.h (CefWindowInfo) /// TCEFWindowInfoWrapper = class protected FWindowInfo : TCEFWindowInfo; function GetWindowName : ustring; function GetBounds : TCefRect; function GetParentWindow : TCefWindowHandle; function GetWindowlessRenderingEnabled : boolean; function GetSharedTextureEnabled : boolean; function GetExternalBeginFrameEnabled : boolean; function GetWindow : TCefWindowHandle; function GetRuntimeStyle : TCefRuntimeStyle; {$IFDEF MSWINDOWS} function GetExStyle : DWORD; function GetStyle : DWORD; function GetMenu : HMENU; {$ENDIF} {$IFDEF MACOSX} function GetHidden : boolean; function GetParentView : TCefWindowHandle; function GetView : TCefWindowHandle; {$ENDIF} procedure SetWindowName(const aValue : ustring); procedure SetBounds(const aValue : TCefRect); procedure SetParentWindow(aValue : TCefWindowHandle); procedure SetWindowlessRenderingEnabled(aValue : boolean); procedure SetSharedTextureEnabled(aValue : boolean); procedure SetExternalBeginFrameEnabled(aValue : boolean); procedure SetWindow(aValue : TCefWindowHandle); procedure SetRuntimeStyle(aValue : TCefRuntimeStyle); {$IFDEF MSWINDOWS} procedure SetExStyle(aValue : DWORD); procedure SetStyle(aValue : DWORD); procedure SetMenu(aValue : HMENU); {$ENDIF} {$IFDEF MACOSX} procedure SetHidden(aValue : boolean); procedure SetParentView(aValue : TCefWindowHandle); procedure SetView(aValue : TCefWindowHandle); {$ENDIF} public constructor Create; /// /// Copy the information from an external TCEFWindowInfo instance /// procedure CopyFromWindowInfo(const aSrcWindowInfo: TCEFWindowInfo); /// /// Create the browser as a child window. /// class procedure AsChild(var aWindowInfo: TCEFWindowInfo; aParent : TCefWindowHandle; aWindowBounds : TRect); /// /// Create the browser as a child window. /// procedure SetAsChild(aParent : TCefWindowHandle; aWindowBounds : TRect); {$IFDEF MSWINDOWS} /// /// Create the browser as a popup window. /// class procedure AsPopup(var aWindowInfo: TCEFWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring); /// /// Create the browser as a popup window. /// procedure SetAsPopup(aParent : TCefWindowHandle; const aWindowName : ustring); {$ENDIF} /// /// Create the browser using windowless (off-screen) rendering. No window /// will be created for the browser and all rendering will occur via the /// ICefRenderHandler interface. The |parent| value will be used to identify /// monitor info and to act as the parent window for dialogs, context menus, /// etc. If |parent| is not provided then the main screen monitor will be used /// and some functionality that requires a parent window may not function /// correctly. In order to create windowless browsers the /// TCefSettings.windowless_rendering_enabled value must be set to true. /// Transparent painting is enabled by default but can be disabled by setting /// ICefBrowserSettings.background_color to an opaque value. /// class procedure AsWindowless(var aWindowInfo: TCEFWindowInfo; aParent : TCefWindowHandle); /// /// Create the browser using windowless (off-screen) rendering. No window /// will be created for the browser and all rendering will occur via the /// ICefRenderHandler interface. The |parent| value will be used to identify /// monitor info and to act as the parent window for dialogs, context menus, /// etc. If |parent| is not provided then the main screen monitor will be used /// and some functionality that requires a parent window may not function /// correctly. In order to create windowless browsers the /// TCefSettings.windowless_rendering_enabled value must be set to true. /// Transparent painting is enabled by default but can be disabled by setting /// ICefBrowserSettings.background_color to an opaque value. /// procedure SetAsWindowless(aParent : TCefWindowHandle); /// /// Internal TCEFWindowInfo instance /// property WindowInfoRecord : TCEFWindowInfo read FWindowInfo write FWindowInfo; /// /// The initial title of the window, to be set when the window is created. /// Some layout managers (e.g., Compiz) can look at the window title /// in order to decide where to place the window when it is /// created. When this attribute is not empty, the window title will /// be set before the window is mapped to the dispay. Otherwise the /// title will be initially empty. /// property WindowName : ustring read GetWindowName write SetWindowName; /// /// Initial window bounds. /// property Bounds : TCefRect read GetBounds write SetBounds; /// /// Set to true (1) to create the browser using windowless (off-screen) /// rendering. No window will be created for the browser and all rendering /// will occur via the ICefRenderHandler interface. The |parent_window| value /// will be used to identify monitor info and to act as the parent window for /// dialogs, context menus, etc. If |parent_window| is not provided then the /// main screen monitor will be used and some functionality that requires a /// parent window may not function correctly. In order to create windowless /// browsers the TCefSettings.windowless_rendering_enabled value must be set to /// true. Transparent painting is enabled by default but can be disabled by /// setting TCefBrowserSettings.background_color to an opaque value. /// property WindowlessRenderingEnabled : boolean read GetWindowlessRenderingEnabled write SetWindowlessRenderingEnabled; /// /// Set to true (1) to enable shared textures for windowless rendering. Only /// valid if windowless_rendering_enabled above is also set to true. Currently /// only supported on Windows (D3D11). /// property SharedTextureEnabled : boolean read GetSharedTextureEnabled write SetSharedTextureEnabled; /// /// Set to true (1) to enable the ability to issue BeginFrame requests from /// the client application by calling ICefBrowserHost.SendExternalBeginFrame. /// property ExternalBeginFrameEnabled : boolean read GetExternalBeginFrameEnabled write SetExternalBeginFrameEnabled; /// /// Optionally change the runtime style. Alloy style will always be used if /// |windowless_rendering_enabled| is true. See TCefRuntimeStyle /// documentation for details. /// property RuntimeStyle : TCefRuntimeStyle read GetRuntimeStyle write SetRuntimeStyle; {$IFDEF MSWINDOWS} /// /// Standard parameters required by CreateWindowEx(). /// Used as the dwExStyle parameter in CreateWindowEx. /// /// /// Read the CreateWindowExW article. /// property ExStyle : DWORD read GetExStyle write SetExStyle; /// /// Used as the dwStyle parameter in CreateWindowEx. /// /// /// Read the CreateWindowExW article. /// property Style : DWORD read GetStyle write SetStyle; /// /// Used as the hMenu parameter in CreateWindowEx. /// /// /// Read the CreateWindowExW article. /// property Menu : HMENU read GetMenu write SetMenu; /// /// Used as the hWndParent parameter in CreateWindowEx. /// /// /// Read the CreateWindowExW article. /// property ParentWindow : TCefWindowHandle read GetParentWindow write SetParentWindow; /// /// Handle for the new browser window. Only used with windowed rendering. /// property Window : TCefWindowHandle read GetWindow write SetWindow; {$ENDIF} {$IFDEF MACOSX} /// /// Set to true (1) to create the view initially hidden. /// property Hidden : boolean read GetHidden write SetHidden; /// /// NSView pointer for the parent view. /// property ParentView : TCefWindowHandle read GetParentView write SetParentView; /// /// NSView pointer for the new browser view. Only used with windowed /// rendering. /// property View : TCefWindowHandle read GetView write SetView; {$ENDIF} {$IFDEF LINUX} /// /// Pointer for the parent window. /// property ParentWindow : TCefWindowHandle read GetParentWindow write SetParentWindow; /// /// Pointer for the new browser window. Only used with windowed rendering. /// property Window : TCefWindowHandle read GetWindow write SetWindow; {$ENDIF} end; implementation uses {$IFDEF LINUX}{$IFDEF FPC} ctypes, keysym, xf86keysym, x, xlib, {$IFDEF LCLGTK2}gtk2, glib2, gdk2, gtk2proc, gtk2int, Gtk2Def, gdk2x, Gtk2Extra,{$ENDIF} {$IFDEF LCLGTK3}LazGdk3, LazGtk3, LazGLib2, gtk3widgets,{$ENDIF} uCEFLinuxFunctions, {$ENDIF}{$ENDIF} uCEFMiscFunctions; constructor TCEFWindowInfoWrapper.Create; begin inherited Create; FillChar(FWindowInfo, SizeOf(TCefWindowInfo), 0); end; {$IFDEF MSWINDOWS} function TCEFWindowInfoWrapper.GetExStyle : DWORD; begin Result := FWindowInfo.ex_style; end; function TCEFWindowInfoWrapper.GetStyle : DWORD; begin Result := FWindowInfo.style; end; function TCEFWindowInfoWrapper.GetMenu : HMENU; begin Result := FWindowInfo.menu; end; {$ENDIF} function TCEFWindowInfoWrapper.GetWindowName : ustring; begin Result := CefString(@FWindowInfo.window_name); end; function TCEFWindowInfoWrapper.GetBounds : TCefRect; begin Result := FWindowInfo.bounds; end; function TCEFWindowInfoWrapper.GetParentWindow : TCefWindowHandle; begin {$IFDEF MSWINDOWS} Result := FWindowInfo.parent_window; {$ENDIF} {$IFDEF LINUX} Result := FWindowInfo.parent_window; {$ENDIF} end; function TCEFWindowInfoWrapper.GetWindowlessRenderingEnabled : boolean; begin Result := FWindowInfo.windowless_rendering_enabled <> 0; end; function TCEFWindowInfoWrapper.GetSharedTextureEnabled : boolean; begin Result := FWindowInfo.shared_texture_enabled <> 0; end; function TCEFWindowInfoWrapper.GetExternalBeginFrameEnabled : boolean; begin Result := FWindowInfo.external_begin_frame_enabled <> 0; end; function TCEFWindowInfoWrapper.GetWindow : TCefWindowHandle; begin {$IFDEF MSWINDOWS} Result := FWindowInfo.window; {$ENDIF} {$IFDEF LINUX} Result := FWindowInfo.window; {$ENDIF} end; function TCEFWindowInfoWrapper.GetRuntimeStyle : TCefRuntimeStyle; begin {$IFDEF MSWINDOWS} Result := FWindowInfo.runtime_style; {$ENDIF} {$IFDEF MACOSX} Result := FWindowInfo.runtime_style; {$ENDIF} {$IFDEF LINUX} Result := FWindowInfo.runtime_style; {$ENDIF} end; {$IFDEF MACOSX} function TCEFWindowInfoWrapper.GetHidden : boolean; begin Result := FWindowInfo.hidden <> 0; end; function TCEFWindowInfoWrapper.GetParentView : TCefWindowHandle; begin Result := FWindowInfo.parent_view; end; function TCEFWindowInfoWrapper.GetView : TCefWindowHandle; begin Result := FWindowInfo.view; end; {$ENDIF} {$IFDEF MSWINDOWS} procedure TCEFWindowInfoWrapper.SetExStyle(aValue : DWORD); begin FWindowInfo.ex_style := aValue; end; procedure TCEFWindowInfoWrapper.SetStyle(aValue : DWORD); begin FWindowInfo.style := aValue; end; procedure TCEFWindowInfoWrapper.SetMenu(aValue : HMENU); begin FWindowInfo.menu := aValue; end; {$ENDIF} procedure TCEFWindowInfoWrapper.SetWindowName(const aValue : ustring); begin FWindowInfo.window_name := CefString(aValue); end; procedure TCEFWindowInfoWrapper.SetBounds(const aValue : TCefRect); begin FWindowInfo.bounds := aValue; end; procedure TCEFWindowInfoWrapper.SetParentWindow(aValue : TCefWindowHandle); begin {$IFDEF MSWINDOWS} FWindowInfo.parent_window := aValue; {$ENDIF} {$IFDEF LINUX} FWindowInfo.parent_window := aValue; {$ENDIF} end; procedure TCEFWindowInfoWrapper.SetWindowlessRenderingEnabled(aValue : boolean); begin FWindowInfo.windowless_rendering_enabled := ord(aValue); end; procedure TCEFWindowInfoWrapper.SetSharedTextureEnabled(aValue : boolean); begin FWindowInfo.shared_texture_enabled := ord(aValue); end; procedure TCEFWindowInfoWrapper.SetExternalBeginFrameEnabled(aValue : boolean); begin FWindowInfo.external_begin_frame_enabled := ord(aValue); end; procedure TCEFWindowInfoWrapper.SetWindow(aValue : TCefWindowHandle); begin {$IFDEF MSWINDOWS} FWindowInfo.window := aValue; {$ENDIF} {$IFDEF LINUX} FWindowInfo.window := aValue; {$ENDIF} end; procedure TCEFWindowInfoWrapper.SetRuntimeStyle(aValue : TCefRuntimeStyle); begin {$IFDEF MSWINDOWS} FWindowInfo.runtime_style := aValue; {$ENDIF} {$IFDEF MACOSX} FWindowInfo.runtime_style := aValue; {$ENDIF} {$IFDEF LINUX} FWindowInfo.runtime_style := aValue; {$ENDIF} end; {$IFDEF MACOSX} procedure TCEFWindowInfoWrapper.SetHidden(aValue : boolean); begin FWindowInfo.hidden := ord(aValue); end; procedure TCEFWindowInfoWrapper.SetParentView(aValue : TCefWindowHandle); begin FWindowInfo.parent_view := aValue; end; procedure TCEFWindowInfoWrapper.SetView(aValue : TCefWindowHandle); begin FWindowInfo.view := aValue; end; {$ENDIF} procedure TCEFWindowInfoWrapper.CopyFromWindowInfo(const aSrcWindowInfo: TCEFWindowInfo); begin {$IFDEF MSWINDOWS} FWindowInfo.ex_style := aSrcWindowInfo.ex_style; CefStringSet(FWindowInfo.window_name, aSrcWindowInfo.window_name); FWindowInfo.style := aSrcWindowInfo.style; FWindowInfo.bounds := aSrcWindowInfo.bounds; FWindowInfo.parent_window := aSrcWindowInfo.parent_window; FWindowInfo.menu := aSrcWindowInfo.menu; FWindowInfo.windowless_rendering_enabled := aSrcWindowInfo.windowless_rendering_enabled; FWindowInfo.shared_texture_enabled := aSrcWindowInfo.shared_texture_enabled; FWindowInfo.external_begin_frame_enabled := aSrcWindowInfo.external_begin_frame_enabled; FWindowInfo.window := aSrcWindowInfo.window; FWindowInfo.runtime_style := aSrcWindowInfo.runtime_style; {$ENDIF} {$IFDEF MACOSX} CefStringSet(FWindowInfo.window_name, aSrcWindowInfo.window_name); FWindowInfo.bounds := aSrcWindowInfo.bounds; FWindowInfo.hidden := aSrcWindowInfo.hidden; FWindowInfo.parent_view := aSrcWindowInfo.parent_view; FWindowInfo.windowless_rendering_enabled := aSrcWindowInfo.windowless_rendering_enabled; FWindowInfo.shared_texture_enabled := aSrcWindowInfo.shared_texture_enabled; FWindowInfo.external_begin_frame_enabled := aSrcWindowInfo.external_begin_frame_enabled; FWindowInfo.view := aSrcWindowInfo.view; FWindowInfo.runtime_style := aSrcWindowInfo.runtime_style; {$ENDIF} {$IFDEF LINUX} CefStringSet(FWindowInfo.window_name, aSrcWindowInfo.window_name); FWindowInfo.bounds := aSrcWindowInfo.bounds; FWindowInfo.parent_window := aSrcWindowInfo.parent_window; FWindowInfo.windowless_rendering_enabled := aSrcWindowInfo.windowless_rendering_enabled; FWindowInfo.shared_texture_enabled := aSrcWindowInfo.shared_texture_enabled; FWindowInfo.external_begin_frame_enabled := aSrcWindowInfo.external_begin_frame_enabled; FWindowInfo.window := aSrcWindowInfo.window; FWindowInfo.runtime_style := aSrcWindowInfo.runtime_style; {$ENDIF} end; class procedure TCEFWindowInfoWrapper.AsChild(var aWindowInfo: TCEFWindowInfo; aParent : TCefWindowHandle; aWindowBounds : TRect); {$IFDEF LINUX} var TempParent : TCefWindowHandle; {$ENDIF} begin {$IFDEF MSWINDOWS} aWindowInfo.style := WS_CHILD or WS_VISIBLE or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_TABSTOP; aWindowInfo.parent_window := aParent; aWindowInfo.bounds.x := aWindowBounds.left; aWindowInfo.bounds.y := aWindowBounds.top; aWindowInfo.bounds.width := aWindowBounds.right - aWindowBounds.left; aWindowInfo.bounds.height := aWindowBounds.bottom - aWindowBounds.top; {$ENDIF} {$IFDEF MACOSX} aWindowInfo.parent_view := aParent; aWindowInfo.bounds.x := aWindowBounds.left; aWindowInfo.bounds.y := aWindowBounds.top; aWindowInfo.bounds.width := aWindowBounds.right - aWindowBounds.left; aWindowInfo.bounds.height := aWindowBounds.bottom - aWindowBounds.top; aWindowInfo.hidden := ord(False); {$ENDIF} {$IFDEF LINUX} TempParent := aParent; {$IFDEF FPC} {$IFDEF LCLGTK2} if ValidCefWindowHandle(aParent) and (PGtkWidget(aParent)^.window <> nil) then TempParent := gdk_window_xwindow(PGtkWidget(aParent)^.window); {$ENDIF} {$IFDEF LCLGTK3} if ValidCefWindowHandle(aParent) and (TGtk3Widget(aParent).Widget <> nil) then begin // cefclient creates the main window with this code in root_window_gtk.cc // window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL); // Then if populates window_info with : // window_info.SetAsChild(GetXWindowForWidget(parent_handle), rect); // GetXWindowForWidget returns this : // GDK_WINDOW_XID(gtk_widget_get_window(widget)); // GDK_WINDOW_XID is a macro equivalent to gdk_x11_drawable_get_xid in gtk2 but // in gtk3 we use gdk_x11_window_get_xid instead. // LCL sets TGtk3Widget.Widget to gtk_window_new(GTK_WINDOW_TOPLEVEL) for the main form. // When we call TChromium.CreateBrowser with the main form as parent we get this error in the console (not in the log) : // [19140:19166:0604/174851.690766:ERROR:x11_software_bitmap_presenter.cc(144)] XGetWindowAttributes failed for window XXXXXXX TempParent := gdk_x11_window_get_xid(gtk_widget_get_window(TGtk3Widget(aParent).Widget)); end; {$ENDIF} {$ENDIF} aWindowInfo.parent_window := TempParent; aWindowInfo.bounds.x := aWindowBounds.left; aWindowInfo.bounds.y := aWindowBounds.top; aWindowInfo.bounds.width := aWindowBounds.right - aWindowBounds.left; aWindowInfo.bounds.height := aWindowBounds.bottom - aWindowBounds.top; {$ENDIF} end; procedure TCEFWindowInfoWrapper.SetAsChild(aParent : TCefWindowHandle; aWindowBounds : TRect); begin AsChild(FWindowInfo, aParent, aWindowBounds); end; {$IFDEF MSWINDOWS} class procedure TCEFWindowInfoWrapper.AsPopup(var aWindowInfo: TCEFWindowInfo; aParent : TCefWindowHandle; const aWindowName : ustring); begin aWindowInfo.window_name := CefString(aWindowName); aWindowInfo.style := WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN or WS_CLIPSIBLINGS or WS_VISIBLE; aWindowInfo.bounds.x := integer(CW_USEDEFAULT); aWindowInfo.bounds.y := integer(CW_USEDEFAULT); aWindowInfo.bounds.width := integer(CW_USEDEFAULT); aWindowInfo.bounds.height := integer(CW_USEDEFAULT); aWindowInfo.parent_window := aParent; end; procedure TCEFWindowInfoWrapper.SetAsPopup(aParent : TCefWindowHandle; const aWindowName : ustring); begin AsPopup(FWindowInfo, aParent, aWindowName); end; {$ENDIF} class procedure TCEFWindowInfoWrapper.AsWindowless(var aWindowInfo: TCEFWindowInfo; aParent : TCefWindowHandle); begin {$IFDEF MSWINDOWS} aWindowInfo.windowless_rendering_enabled := ord(True); aWindowInfo.parent_window := aParent; aWindowInfo.runtime_style := CEF_RUNTIME_STYLE_ALLOY; {$ENDIF} {$IFDEF MACOSX} aWindowInfo.windowless_rendering_enabled := ord(True); aWindowInfo.parent_view := aParent; aWindowInfo.runtime_style := CEF_RUNTIME_STYLE_ALLOY; {$ENDIF} {$IFDEF LINUX} aWindowInfo.windowless_rendering_enabled := ord(True); aWindowInfo.parent_window := aParent; aWindowInfo.runtime_style := CEF_RUNTIME_STYLE_ALLOY; {$ENDIF} end; procedure TCEFWindowInfoWrapper.SetAsWindowless(aParent : TCefWindowHandle); begin AsWindowless(FWindowInfo, aParent); end; end.