diff options
Diffstat (limited to 'libcef/browser/native/browser_platform_delegate_native_linux.cc')
-rw-r--r-- | libcef/browser/native/browser_platform_delegate_native_linux.cc | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.cc b/libcef/browser/native/browser_platform_delegate_native_linux.cc new file mode 100644 index 00000000..50e7a950 --- /dev/null +++ b/libcef/browser/native/browser_platform_delegate_native_linux.cc @@ -0,0 +1,299 @@ +// Copyright 2015 The Chromium Embedded Framework Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "libcef/browser/native/browser_platform_delegate_native_linux.h" + +#include "libcef/browser/browser_host_base.h" +#include "libcef/browser/context.h" +#include "libcef/browser/native/window_delegate_view.h" +#include "libcef/browser/thread_util.h" + +#include "base/no_destructor.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/public/browser/native_web_keyboard_event.h" +#include "content/public/browser/render_view_host.h" +#include "third_party/blink/public/mojom/renderer_preferences.mojom.h" +#include "ui/events/keycodes/dom/dom_key.h" +#include "ui/events/keycodes/dom/keycode_converter.h" +#include "ui/events/keycodes/keysym_to_unicode.h" +#include "ui/gfx/font_render_params.h" +#include "ui/views/widget/widget.h" + +#if BUILDFLAG(OZONE_PLATFORM_X11) +#include "libcef/browser/native/window_x11.h" +#include "ui/events/keycodes/keyboard_code_conversion_x.h" +#include "ui/events/keycodes/keyboard_code_conversion_xkb.h" +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h" +#endif + +CefBrowserPlatformDelegateNativeLinux::CefBrowserPlatformDelegateNativeLinux( + const CefWindowInfo& window_info, + SkColor background_color) + : CefBrowserPlatformDelegateNativeAura(window_info, background_color) {} + +void CefBrowserPlatformDelegateNativeLinux::BrowserDestroyed( + CefBrowserHostBase* browser) { + CefBrowserPlatformDelegateNativeAura::BrowserDestroyed(browser); + + if (host_window_created_) { + // Release the reference added in CreateHostWindow(). + browser->Release(); + } +} + +bool CefBrowserPlatformDelegateNativeLinux::CreateHostWindow() { + DCHECK(!window_widget_); + + if (window_info_.bounds.width == 0) { + window_info_.bounds.width = 800; + } + if (window_info_.bounds.height == 0) { + window_info_.bounds.height = 600; + } + + gfx::Rect rect(window_info_.bounds.x, window_info_.bounds.y, + window_info_.bounds.width, window_info_.bounds.height); + +#if BUILDFLAG(OZONE_PLATFORM_X11) + DCHECK(!window_x11_); + + x11::Window parent_window = x11::Window::None; + if (window_info_.parent_window != kNullWindowHandle) { + parent_window = static_cast<x11::Window>(window_info_.parent_window); + } + + // Create a new window object. It will delete itself when the associated X11 + // window is destroyed. + window_x11_ = + new CefWindowX11(browser_, parent_window, rect, + CefString(&window_info_.window_name).ToString()); + DCHECK_NE(window_x11_->xwindow(), x11::Window::None); + window_info_.window = + static_cast<cef_window_handle_t>(window_x11_->xwindow()); + + host_window_created_ = true; + + // Add a reference that will be released in BrowserDestroyed(). + browser_->AddRef(); + + CefWindowDelegateView* delegate_view = new CefWindowDelegateView( + GetBackgroundColor(), window_x11_->TopLevelAlwaysOnTop(), + GetBoundsChangedCallback(), GetWidgetDeleteCallback()); + delegate_view->Init(static_cast<gfx::AcceleratedWidget>(window_info_.window), + web_contents_, gfx::Rect(gfx::Point(), rect.size())); + + window_widget_ = delegate_view->GetWidget(); + window_widget_->Show(); + + window_x11_->Show(); +#endif // BUILDFLAG(OZONE_PLATFORM_X11) + + // As an additional requirement on Linux, we must set the colors for the + // render widgets in webkit. + auto prefs = web_contents_->GetMutableRendererPrefs(); + prefs->focus_ring_color = SkColorSetARGB(255, 229, 151, 0); + + prefs->active_selection_bg_color = SkColorSetRGB(30, 144, 255); + prefs->active_selection_fg_color = SK_ColorWHITE; + prefs->inactive_selection_bg_color = SkColorSetRGB(200, 200, 200); + prefs->inactive_selection_fg_color = SkColorSetRGB(50, 50, 50); + + // Set font-related attributes. + static const gfx::FontRenderParams params( + gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr)); + prefs->should_antialias_text = params.antialiasing; + prefs->use_subpixel_positioning = params.subpixel_positioning; + prefs->hinting = params.hinting; + prefs->use_autohinter = params.autohinter; + prefs->use_bitmaps = params.use_bitmaps; + prefs->subpixel_rendering = params.subpixel_rendering; + + web_contents_->SyncRendererPrefs(); + + return true; +} + +void CefBrowserPlatformDelegateNativeLinux::CloseHostWindow() { +#if BUILDFLAG(OZONE_PLATFORM_X11) + if (window_x11_) { + window_x11_->Close(); + } +#endif +} + +CefWindowHandle CefBrowserPlatformDelegateNativeLinux::GetHostWindowHandle() + const { + if (windowless_handler_) { + return windowless_handler_->GetParentWindowHandle(); + } + return window_info_.window; +} + +views::Widget* CefBrowserPlatformDelegateNativeLinux::GetWindowWidget() const { + return window_widget_; +} + +void CefBrowserPlatformDelegateNativeLinux::SetFocus(bool setFocus) { + if (!setFocus) { + return; + } + + if (web_contents_) { + // Give logical focus to the RenderWidgetHostViewAura in the views + // hierarchy. This does not change the native keyboard focus. + web_contents_->Focus(); + } + +#if BUILDFLAG(OZONE_PLATFORM_X11) + if (window_x11_) { + // Give native focus to the DesktopNativeWidgetAura for the root window. + // Needs to be done via the ::Window so that keyboard focus is assigned + // correctly. + window_x11_->Focus(); + } +#endif // BUILDFLAG(OZONE_PLATFORM_X11) +} + +void CefBrowserPlatformDelegateNativeLinux::NotifyMoveOrResizeStarted() { + // Call the parent method to dismiss any existing popups. + CefBrowserPlatformDelegateNativeAura::NotifyMoveOrResizeStarted(); + + if (!web_contents_) { + return; + } + +#if BUILDFLAG(OZONE_PLATFORM_X11) + if (!window_x11_) { + return; + } + + views::DesktopWindowTreeHostLinux* tree_host = window_x11_->GetHost(); + if (!tree_host) { + return; + } + + // Explicitly set the screen bounds so that WindowTreeHost::*Screen() + // methods return the correct results. + const gfx::Rect& bounds = window_x11_->GetBoundsInScreen(); + tree_host->set_screen_bounds(bounds); + + // Send updated screen rectangle information to the renderer process so that + // popups are displayed in the correct location. + content::RenderWidgetHostImpl::From( + web_contents_->GetRenderViewHost()->GetWidget()) + ->SendScreenRects(); +#endif // BUILDFLAG(OZONE_PLATFORM_X11) +} + +void CefBrowserPlatformDelegateNativeLinux::SizeTo(int width, int height) { +#if BUILDFLAG(OZONE_PLATFORM_X11) + if (window_x11_) { + window_x11_->SetBounds( + gfx::Rect(window_x11_->bounds().origin(), gfx::Size(width, height))); + } +#endif // BUILDFLAG(OZONE_PLATFORM_X11) +} + +void CefBrowserPlatformDelegateNativeLinux::ViewText(const std::string& text) { + char buff[] = "/tmp/CEFSourceXXXXXX"; + int fd = mkstemp(buff); + + if (fd == -1) { + return; + } + + FILE* srcOutput = fdopen(fd, "w+"); + if (!srcOutput) { + return; + } + + if (fputs(text.c_str(), srcOutput) < 0) { + fclose(srcOutput); + return; + } + + fclose(srcOutput); + + std::string newName(buff); + newName.append(".txt"); + if (rename(buff, newName.c_str()) != 0) { + return; + } + + std::string openCommand("xdg-open "); + openCommand += newName; + + [[maybe_unused]] int result = system(openCommand.c_str()); +} + +bool CefBrowserPlatformDelegateNativeLinux::HandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) { + // TODO(cef): Is something required here to handle shortcut keys? + return false; +} + +// static +void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) {} + +CefEventHandle CefBrowserPlatformDelegateNativeLinux::GetEventHandle( + const content::NativeWebKeyboardEvent& event) const { + // TODO(cef): We need to return an XEvent* from this method, but + // |event.os_event->native_event()| now returns a ui::Event* instead. + // See https://crbug.com/965991. + return nullptr; +} + +ui::KeyEvent CefBrowserPlatformDelegateNativeLinux::TranslateUiKeyEvent( + const CefKeyEvent& key_event) const { + int flags = TranslateUiEventModifiers(key_event.modifiers); + ui::KeyboardCode key_code = + static_cast<ui::KeyboardCode>(key_event.windows_key_code); + ui::DomCode dom_code = + ui::KeycodeConverter::NativeKeycodeToDomCode(key_event.native_key_code); + +#if BUILDFLAG(OZONE_PLATFORM_X11) + int keysym = ui::XKeysymForWindowsKeyCode( + key_code, !!(key_event.modifiers & EVENTFLAG_SHIFT_DOWN)); + char16_t character = ui::GetUnicodeCharacterFromXKeySym(keysym); +#else + char16_t character = key_event.character; +#endif + + base::TimeTicks time_stamp = GetEventTimeStamp(); + + if (key_event.type == KEYEVENT_CHAR) { + return ui::KeyEvent(character, key_code, dom_code, flags, time_stamp); + } + + ui::EventType type = ui::ET_UNKNOWN; + switch (key_event.type) { + case KEYEVENT_RAWKEYDOWN: + case KEYEVENT_KEYDOWN: + type = ui::ET_KEY_PRESSED; + break; + case KEYEVENT_KEYUP: + type = ui::ET_KEY_RELEASED; + break; + default: + NOTREACHED(); + } + +#if BUILDFLAG(OZONE_PLATFORM_X11) + ui::DomKey dom_key = ui::XKeySymToDomKey(keysym, character); +#else + ui::DomKey dom_key = ui::DomKey::NONE; +#endif + + return ui::KeyEvent(type, key_code, dom_code, flags, dom_key, time_stamp); +} + +content::NativeWebKeyboardEvent +CefBrowserPlatformDelegateNativeLinux::TranslateWebKeyEvent( + const CefKeyEvent& key_event) const { + ui::KeyEvent ui_event = TranslateUiKeyEvent(key_event); + if (key_event.type == KEYEVENT_CHAR) { + return content::NativeWebKeyboardEvent(ui_event, key_event.character); + } + return content::NativeWebKeyboardEvent(ui_event); +} |