Phase 0: browser X11-overlay inventory + mpv reference cell + tooling installs
Source-level verdict: no browser in the matrix has a code path to hand NV12 to the X server for plane scanout. Chromium ozone-x11 wires StubOverlayManager (ozone_platform_x11.cc:262); Brave 147 + chromium-fourier 149 inherit unchanged. Firefox WindowSurfaceX11 is RGB-only. The campaign's load-bearing hypothesis is structurally weakened — what the X11 cells will measure for browsers is KWin's per-frame RGB-recomposite cost, not the original "force-GL-composite of NV12" framing. mpv --vo=xv becomes the matrix's only direct test of the operator-supplied mechanism. Matrix updated: 12 cells -> 16 cells (+8 mpv VO sub-points). revert.log entries 1-5 capture all package + per-user state mutations from this turn (measurement tools, openbox, XFCE + xfwm4-no-comp pre-seed, firefox + AUR xtrace, XFCE rotation + touchscreen mapping); single SSH-driveable revert chain returns ohm to its pre-campaign 1169-package state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Source provenance
|
||||
Host: boltzmann
|
||||
Container: chromium-builder (LXD)
|
||||
Path inside CT: /build/chromium/src
|
||||
Tarball mtime: 2026-04-25 (chromium-147.0.7727.116.tar.xz)
|
||||
Fetched: 2026-05-03
|
||||
Reach recipe: ssh boltzmann "sudo lxc exec chromium-builder -- cat /build/chromium/src/<path>"
|
||||
|
||||
## Chromium VERSION + ui/ozone/platform/x11/ listing
|
||||
|
||||
MAJOR=147
|
||||
MINOR=0
|
||||
BUILD=7727
|
||||
PATCH=116
|
||||
---
|
||||
total 384
|
||||
drwxr-xr-x 1 builder builder 2298 Apr 21 17:50 .
|
||||
drwxr-xr-x 1 builder builder 78 Apr 21 17:50 ..
|
||||
-rw-r--r-- 1 builder builder 5298 Apr 21 17:50 BUILD.gn
|
||||
-rw-r--r-- 1 builder builder 360 Apr 21 17:50 DEPS
|
||||
-rw-r--r-- 1 builder builder 89 Apr 21 17:50 OWNERS
|
||||
-rw-r--r-- 1 builder builder 2841 Apr 21 17:50 atk_event_conversion.cc
|
||||
-rw-r--r-- 1 builder builder 1033 Apr 21 17:50 atk_event_conversion.h
|
||||
-rw-r--r-- 1 builder builder 440 Apr 21 17:50 client_native_pixmap_factory_x11.cc
|
||||
-rw-r--r-- 1 builder builder 556 Apr 21 17:50 client_native_pixmap_factory_x11.h
|
||||
-rw-r--r-- 1 builder builder 1255 Apr 21 17:50 gl_egl_utility_x11.cc
|
||||
-rw-r--r-- 1 builder builder 1133 Apr 21 17:50 gl_egl_utility_x11.h
|
||||
-rw-r--r-- 1 builder builder 2469 Apr 21 17:50 gl_surface_egl_readback_x11.cc
|
||||
-rw-r--r-- 1 builder builder 1280 Apr 21 17:50 gl_surface_egl_readback_x11.h
|
||||
-rw-r--r-- 1 builder builder 1218 Apr 21 17:50 hit_test_x11.cc
|
||||
-rw-r--r-- 1 builder builder 508 Apr 21 17:50 hit_test_x11.h
|
||||
-rw-r--r-- 1 builder builder 1198 Apr 21 17:50 linux_ui_delegate_x11.cc
|
||||
-rw-r--r-- 1 builder builder 894 Apr 21 17:50 linux_ui_delegate_x11.h
|
||||
-rw-r--r-- 1 builder builder 8235 Apr 21 17:50 native_pixmap_egl_x11_binding.cc
|
||||
-rw-r--r-- 1 builder builder 1553 Apr 21 17:50 native_pixmap_egl_x11_binding.h
|
||||
-rw-r--r-- 1 builder builder 1703 Apr 21 17:50 os_exchange_data_provider_x11.cc
|
||||
-rw-r--r-- 1 builder builder 1726 Apr 21 17:50 os_exchange_data_provider_x11.h
|
||||
-rw-r--r-- 1 builder builder 13470 Apr 21 17:50 ozone_platform_x11.cc
|
||||
-rw-r--r-- 1 builder builder 458 Apr 21 17:50 ozone_platform_x11.h
|
||||
drwxr-xr-x 1 builder builder 366 Apr 21 17:50 test
|
||||
-rw-r--r-- 1 builder builder 5791 Apr 21 17:50 vulkan_implementation_x11.cc
|
||||
-rw-r--r-- 1 builder builder 2126 Apr 21 17:50 vulkan_implementation_x11.h
|
||||
-rw-r--r-- 1 builder builder 4729 Apr 21 17:50 vulkan_surface_x11.cc
|
||||
-rw-r--r-- 1 builder builder 2797 Apr 21 17:50 vulkan_surface_x11.h
|
||||
-rw-r--r-- 1 builder builder 1686 Apr 21 17:50 x11_canvas_surface.cc
|
||||
-rw-r--r-- 1 builder builder 1962 Apr 21 17:50 x11_canvas_surface.h
|
||||
-rw-r--r-- 1 builder builder 3845 Apr 21 17:50 x11_clipboard_ozone.cc
|
||||
-rw-r--r-- 1 builder builder 2158 Apr 21 17:50 x11_clipboard_ozone.h
|
||||
-rw-r--r-- 1 builder builder 1885 Apr 21 17:50 x11_global_shortcut_listener_ozone.cc
|
||||
-rw-r--r-- 1 builder builder 1736 Apr 21 17:50 x11_global_shortcut_listener_ozone.h
|
||||
-rw-r--r-- 1 builder builder 4440 Apr 21 17:50 x11_keyboard_hook.cc
|
||||
-rw-r--r-- 1 builder builder 1600 Apr 21 17:50 x11_keyboard_hook.h
|
||||
-rw-r--r-- 1 builder builder 440 Apr 21 17:50 x11_menu_utils.cc
|
||||
-rw-r--r-- 1 builder builder 636 Apr 21 17:50 x11_menu_utils.h
|
||||
-rw-r--r-- 1 builder builder 2846 Apr 21 17:50 x11_ozone_ui_controls_test_helper.cc
|
||||
-rw-r--r-- 1 builder builder 2127 Apr 21 17:50 x11_ozone_ui_controls_test_helper.h
|
||||
-rw-r--r-- 1 builder builder 9385 Apr 21 17:50 x11_screen_ozone.cc
|
||||
-rw-r--r-- 1 builder builder 3750 Apr 21 17:50 x11_screen_ozone.h
|
||||
-rw-r--r-- 1 builder builder 18003 Apr 21 17:50 x11_screen_ozone_unittest.cc
|
||||
-rw-r--r-- 1 builder builder 8966 Apr 21 17:50 x11_surface_factory.cc
|
||||
-rw-r--r-- 1 builder builder 2267 Apr 21 17:50 x11_surface_factory.h
|
||||
-rw-r--r-- 1 builder builder 1191 Apr 21 17:50 x11_user_input_monitor.cc
|
||||
-rw-r--r-- 1 builder builder 1279 Apr 21 17:50 x11_user_input_monitor.h
|
||||
-rw-r--r-- 1 builder builder 876 Apr 21 17:50 x11_utils.cc
|
||||
-rw-r--r-- 1 builder builder 754 Apr 21 17:50 x11_utils.h
|
||||
-rw-r--r-- 1 builder builder 92805 Apr 21 17:50 x11_window.cc
|
||||
-rw-r--r-- 1 builder builder 19102 Apr 21 17:50 x11_window.h
|
||||
-rw-r--r-- 1 builder builder 3105 Apr 21 17:50 x11_window_manager.cc
|
||||
-rw-r--r-- 1 builder builder 1813 Apr 21 17:50 x11_window_manager.h
|
||||
-rw-r--r-- 1 builder builder 11141 Apr 21 17:50 x11_window_ozone_unittest.cc
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2015 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/common/stub_overlay_manager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ui/ozone/public/overlay_candidates_ozone.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
StubOverlayManager::StubOverlayManager() {
|
||||
}
|
||||
|
||||
StubOverlayManager::~StubOverlayManager() {
|
||||
}
|
||||
|
||||
std::unique_ptr<OverlayCandidatesOzone>
|
||||
StubOverlayManager::CreateOverlayCandidates(gfx::AcceleratedWidget w) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_
|
||||
#define UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ui/ozone/public/overlay_manager_ozone.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class StubOverlayManager : public OverlayManagerOzone {
|
||||
public:
|
||||
StubOverlayManager();
|
||||
|
||||
StubOverlayManager(const StubOverlayManager&) = delete;
|
||||
StubOverlayManager& operator=(const StubOverlayManager&) = delete;
|
||||
|
||||
~StubOverlayManager() override;
|
||||
|
||||
// OverlayManagerOzone:
|
||||
std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates(
|
||||
gfx::AcceleratedWidget w) override;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_COMMON_STUB_OVERLAY_MANAGER_H_
|
||||
@@ -0,0 +1,204 @@
|
||||
# Copyright 2016 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//build/config/chromeos/ui_mode.gni")
|
||||
import("//gpu/vulkan/features.gni")
|
||||
import("//ui/base/ui_features.gni")
|
||||
|
||||
visibility = [ "//ui/ozone/*" ]
|
||||
|
||||
assert(is_linux || is_chromeos)
|
||||
|
||||
source_set("x11") {
|
||||
sources = [
|
||||
"client_native_pixmap_factory_x11.cc",
|
||||
"client_native_pixmap_factory_x11.h",
|
||||
"gl_egl_utility_x11.cc",
|
||||
"gl_egl_utility_x11.h",
|
||||
"gl_surface_egl_readback_x11.cc",
|
||||
"gl_surface_egl_readback_x11.h",
|
||||
"hit_test_x11.cc",
|
||||
"hit_test_x11.h",
|
||||
"native_pixmap_egl_x11_binding.cc",
|
||||
"native_pixmap_egl_x11_binding.h",
|
||||
"os_exchange_data_provider_x11.cc",
|
||||
"os_exchange_data_provider_x11.h",
|
||||
"ozone_platform_x11.cc",
|
||||
"ozone_platform_x11.h",
|
||||
"x11_canvas_surface.cc",
|
||||
"x11_canvas_surface.h",
|
||||
"x11_clipboard_ozone.cc",
|
||||
"x11_clipboard_ozone.h",
|
||||
"x11_global_shortcut_listener_ozone.cc",
|
||||
"x11_global_shortcut_listener_ozone.h",
|
||||
"x11_keyboard_hook.cc",
|
||||
"x11_keyboard_hook.h",
|
||||
"x11_menu_utils.cc",
|
||||
"x11_menu_utils.h",
|
||||
"x11_screen_ozone.cc",
|
||||
"x11_screen_ozone.h",
|
||||
"x11_surface_factory.cc",
|
||||
"x11_surface_factory.h",
|
||||
"x11_user_input_monitor.cc",
|
||||
"x11_user_input_monitor.h",
|
||||
"x11_utils.cc",
|
||||
"x11_utils.h",
|
||||
"x11_window.cc",
|
||||
"x11_window.h",
|
||||
"x11_window_manager.cc",
|
||||
"x11_window_manager.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base",
|
||||
"//build:chromecast_buildflags",
|
||||
"//components/viz/common/resources:shared_image_format",
|
||||
"//gpu/vulkan:buildflags",
|
||||
"//net",
|
||||
"//skia",
|
||||
"//third_party/angle:includes",
|
||||
"//ui/base",
|
||||
"//ui/base:buildflags",
|
||||
"//ui/base:data_exchange",
|
||||
"//ui/base:hit_test",
|
||||
"//ui/base:wm_role_names",
|
||||
"//ui/base/clipboard:clipboard_types",
|
||||
"//ui/base/cursor",
|
||||
"//ui/base/data_transfer_policy",
|
||||
"//ui/base/dragdrop:types",
|
||||
"//ui/base/dragdrop/mojom",
|
||||
"//ui/base/ime",
|
||||
"//ui/base/x",
|
||||
"//ui/base/x:gl",
|
||||
"//ui/display/types",
|
||||
"//ui/events",
|
||||
"//ui/events:dom_keycode_converter",
|
||||
"//ui/events/devices",
|
||||
"//ui/events/devices/x11",
|
||||
"//ui/events/ozone",
|
||||
"//ui/events/ozone/layout",
|
||||
"//ui/events/platform",
|
||||
"//ui/events/platform/x11",
|
||||
"//ui/events/x",
|
||||
"//ui/gfx",
|
||||
"//ui/gfx/geometry",
|
||||
"//ui/gfx/linux:gbm",
|
||||
"//ui/gfx/linux:gbm_support_x11",
|
||||
"//ui/gfx/x",
|
||||
"//ui/gl",
|
||||
"//ui/ozone:ozone_base",
|
||||
"//ui/ozone/common",
|
||||
"//ui/platform_window",
|
||||
"//ui/platform_window/common",
|
||||
"//ui/platform_window/wm",
|
||||
]
|
||||
|
||||
if (is_linux) {
|
||||
sources += [
|
||||
"linux_ui_delegate_x11.cc",
|
||||
"linux_ui_delegate_x11.h",
|
||||
]
|
||||
deps += [
|
||||
"//components/dbus",
|
||||
"//ui/base/clipboard:clipboard_util_linux",
|
||||
"//ui/linux:linux_ui",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_chromeos) {
|
||||
deps += [ "//ui/base/ime/ash" ]
|
||||
} else {
|
||||
deps += [ "//ui/base/ime/linux" ]
|
||||
}
|
||||
|
||||
if (enable_vulkan) {
|
||||
sources += [
|
||||
"vulkan_implementation_x11.cc",
|
||||
"vulkan_implementation_x11.h",
|
||||
"vulkan_surface_x11.cc",
|
||||
"vulkan_surface_x11.h",
|
||||
]
|
||||
deps += [ "//gpu/vulkan" ]
|
||||
}
|
||||
|
||||
if (use_xkbcommon) {
|
||||
configs += [ "//ui/events/ozone/layout:xkbcommon" ]
|
||||
}
|
||||
|
||||
if (use_atk) {
|
||||
sources += [
|
||||
"atk_event_conversion.cc",
|
||||
"atk_event_conversion.h",
|
||||
]
|
||||
configs += [ "//build/config/linux/atk" ]
|
||||
deps += [ "//ui/events/x" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("x11_unittests") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"test/device_data_manager_x11_unittest.cc",
|
||||
"test/events_x_unittest.cc",
|
||||
"test/x11_event_translation_unittest.cc",
|
||||
"test/x11_window_unittest.cc",
|
||||
"x11_screen_ozone_unittest.cc",
|
||||
"x11_window_ozone_unittest.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":x11",
|
||||
"//base",
|
||||
"//base/test:test_support",
|
||||
"//skia",
|
||||
"//testing/gmock",
|
||||
"//testing/gtest",
|
||||
"//ui/base",
|
||||
"//ui/base:features",
|
||||
"//ui/base/dragdrop:types",
|
||||
"//ui/base/x",
|
||||
"//ui/base/x:test_support",
|
||||
"//ui/base/x:unittests",
|
||||
"//ui/display:test_support",
|
||||
"//ui/events:test_support",
|
||||
"//ui/events/devices/x11",
|
||||
"//ui/events/platform/x11",
|
||||
"//ui/events/x",
|
||||
"//ui/gfx:test_support",
|
||||
"//ui/gfx/x",
|
||||
"//ui/gfx/x:unit_test",
|
||||
"//ui/ozone:platform",
|
||||
"//ui/ozone:test_support",
|
||||
"//ui/ozone/common",
|
||||
]
|
||||
|
||||
if (!is_chromeos) {
|
||||
sources += [ "test/os_exchange_data_provider_x11_unittest.cc" ]
|
||||
deps += [ "//ui/base/clipboard:clipboard_types" ]
|
||||
|
||||
# ChromeOS uses a non-backed exchange data provider while the tests actually
|
||||
# expect to use a normal X11 provider. Running these tests with a non-backed
|
||||
# provided results in crashes when ownership selection call is made.
|
||||
# Moreover, X11 on ChromeOS is used only for dev purposes and it doesn't
|
||||
# support DnD between X11 windows. Instead, all the dnd operations are
|
||||
# performed within a single native windows, where ash spawns number of own
|
||||
# internal windows.
|
||||
sources += [ "test/x11_drag_drop_client_unittest.cc" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("test_support") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"x11_ozone_ui_controls_test_helper.cc",
|
||||
"x11_ozone_ui_controls_test_helper.h",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//ui/aura",
|
||||
"//ui/base/x",
|
||||
"//ui/base/x:test_support",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
include_rules = [
|
||||
"+components/dbus",
|
||||
"+components/viz/common/resources/shared_image_format.h",
|
||||
"+components/viz/common/resources/shared_image_format_utils.h",
|
||||
"+dbus/bus.h",
|
||||
"+net/base/network_interfaces.h",
|
||||
"+ui/base/x",
|
||||
"+ui/base",
|
||||
"+ui/linux",
|
||||
]
|
||||
|
||||
specific_include_rules = {
|
||||
"x11_ozone_ui_controls_test_helper.cc": [
|
||||
"+ui/aura",
|
||||
]
|
||||
}
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/x11/ozone_platform_x11.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/message_loop/message_pump_type.h"
|
||||
#include "base/metrics/histogram_functions.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "build/build_config.h"
|
||||
#include "ui/base/buildflags.h"
|
||||
#include "ui/base/cursor/cursor_factory.h"
|
||||
#include "ui/base/dragdrop/os_exchange_data_provider_factory_ozone.h"
|
||||
#include "ui/base/x/x11_cursor_factory.h"
|
||||
#include "ui/base/x/x11_util.h"
|
||||
#include "ui/display/types/native_display_delegate.h"
|
||||
#include "ui/events/devices/x11/touch_factory_x11.h"
|
||||
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
|
||||
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#include "ui/gfx/linux/gbm_support_x11.h"
|
||||
#include "ui/gfx/native_ui_types.h"
|
||||
#include "ui/gfx/switches.h"
|
||||
#include "ui/gfx/x/atom_cache.h"
|
||||
#include "ui/gfx/x/visual_manager.h"
|
||||
#include "ui/linux/linux_ui_delegate.h"
|
||||
#include "ui/ozone/common/stub_overlay_manager.h"
|
||||
#include "ui/ozone/platform/x11/gl_egl_utility_x11.h"
|
||||
#include "ui/ozone/platform/x11/linux_ui_delegate_x11.h"
|
||||
#include "ui/ozone/platform/x11/x11_clipboard_ozone.h"
|
||||
#include "ui/ozone/platform/x11/x11_global_shortcut_listener_ozone.h"
|
||||
#include "ui/ozone/platform/x11/x11_keyboard_hook.h"
|
||||
#include "ui/ozone/platform/x11/x11_menu_utils.h"
|
||||
#include "ui/ozone/platform/x11/x11_screen_ozone.h"
|
||||
#include "ui/ozone/platform/x11/x11_surface_factory.h"
|
||||
#include "ui/ozone/platform/x11/x11_user_input_monitor.h"
|
||||
#include "ui/ozone/platform/x11/x11_utils.h"
|
||||
#include "ui/ozone/platform/x11/x11_window.h"
|
||||
#include "ui/ozone/public/gpu_platform_support_host.h"
|
||||
#include "ui/ozone/public/input_controller.h"
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#include "ui/ozone/public/stub_input_controller.h"
|
||||
#include "ui/ozone/public/system_input_injector.h"
|
||||
#include "ui/platform_window/platform_window.h"
|
||||
#include "ui/platform_window/platform_window_init_properties.h"
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS)
|
||||
#include "ui/base/dragdrop/os_exchange_data_provider_non_backed.h"
|
||||
#include "ui/base/ime/ash/input_method_ash.h"
|
||||
#else
|
||||
#include "ui/base/ime/linux/input_method_auralinux.h"
|
||||
#include "ui/ozone/platform/x11/os_exchange_data_provider_x11.h"
|
||||
#endif
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace {
|
||||
|
||||
// Singleton OzonePlatform implementation for X11 platform.
|
||||
class OzonePlatformX11 : public OzonePlatform,
|
||||
public OSExchangeDataProviderFactoryOzone {
|
||||
public:
|
||||
OzonePlatformX11() { SetInstance(this); }
|
||||
|
||||
OzonePlatformX11(const OzonePlatformX11&) = delete;
|
||||
OzonePlatformX11& operator=(const OzonePlatformX11&) = delete;
|
||||
|
||||
~OzonePlatformX11() override = default;
|
||||
|
||||
// OzonePlatform:
|
||||
ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override {
|
||||
return surface_factory_ozone_.get();
|
||||
}
|
||||
|
||||
ui::OverlayManagerOzone* GetOverlayManager() override {
|
||||
return overlay_manager_.get();
|
||||
}
|
||||
|
||||
CursorFactory* GetCursorFactory() override { return cursor_factory_.get(); }
|
||||
|
||||
std::unique_ptr<SystemInputInjector> CreateSystemInputInjector() override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
InputController* GetInputController() override {
|
||||
return input_controller_.get();
|
||||
}
|
||||
|
||||
GpuPlatformSupportHost* GetGpuPlatformSupportHost() override {
|
||||
return gpu_platform_support_host_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformWindow> CreatePlatformWindow(
|
||||
PlatformWindowDelegate* delegate,
|
||||
PlatformWindowInitProperties properties) override {
|
||||
auto window = std::make_unique<X11Window>(delegate);
|
||||
window->Initialize(std::move(properties));
|
||||
return std::move(window);
|
||||
}
|
||||
|
||||
std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate()
|
||||
override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformScreen> CreateScreen() override {
|
||||
return std::make_unique<X11ScreenOzone>();
|
||||
}
|
||||
|
||||
void InitScreen(PlatformScreen* screen) override {
|
||||
// InitScreen is always called with the same screen that CreateScreen
|
||||
// hands back, so it is safe to cast here.
|
||||
static_cast<X11ScreenOzone*>(screen)->Init();
|
||||
}
|
||||
|
||||
PlatformClipboard* GetPlatformClipboard() override {
|
||||
return clipboard_.get();
|
||||
}
|
||||
|
||||
PlatformGLEGLUtility* GetPlatformGLEGLUtility() override {
|
||||
if (!gl_egl_utility_)
|
||||
gl_egl_utility_ = std::make_unique<GLEGLUtilityX11>();
|
||||
return gl_egl_utility_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<InputMethod> CreateInputMethod(
|
||||
ImeKeyEventDispatcher* ime_key_event_dispatcher,
|
||||
gfx::AcceleratedWidget widget) override {
|
||||
#if BUILDFLAG(IS_CHROMEOS)
|
||||
return std::make_unique<ash::InputMethodAsh>(ime_key_event_dispatcher);
|
||||
#else
|
||||
return std::make_unique<InputMethodAuraLinux>(ime_key_event_dispatcher,
|
||||
widget);
|
||||
#endif
|
||||
}
|
||||
|
||||
PlatformMenuUtils* GetPlatformMenuUtils() override {
|
||||
return menu_utils_.get();
|
||||
}
|
||||
|
||||
PlatformUtils* GetPlatformUtils() override { return x11_utils_.get(); }
|
||||
|
||||
PlatformGlobalShortcutListener* GetPlatformGlobalShortcutListener(
|
||||
PlatformGlobalShortcutListenerDelegate* delegate) override {
|
||||
if (!global_shortcut_listener_) {
|
||||
global_shortcut_listener_ =
|
||||
std::make_unique<X11GlobalShortcutListenerOzone>(delegate);
|
||||
}
|
||||
return global_shortcut_listener_.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformKeyboardHook> CreateKeyboardHook(
|
||||
PlatformKeyboardHookTypes type,
|
||||
base::RepeatingCallback<void(KeyEvent* event)> callback,
|
||||
std::optional<base::flat_set<DomCode>> dom_codes,
|
||||
gfx::AcceleratedWidget accelerated_widget) override {
|
||||
switch (type) {
|
||||
case PlatformKeyboardHookTypes::kModifier:
|
||||
return std::make_unique<X11KeyboardHook>(
|
||||
std::move(dom_codes), std::move(callback), accelerated_widget);
|
||||
case PlatformKeyboardHookTypes::kMedia:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<OSExchangeDataProvider> CreateProvider() override {
|
||||
#if BUILDFLAG(IS_CHROMEOS)
|
||||
return std::make_unique<OSExchangeDataProviderNonBacked>();
|
||||
#else
|
||||
return std::make_unique<OSExchangeDataProviderX11>();
|
||||
#endif
|
||||
}
|
||||
|
||||
const PlatformProperties& GetPlatformProperties() override {
|
||||
using SupportsForTest = OzonePlatform::PlatformProperties::SupportsForTest;
|
||||
const auto& override_set_parent_for_non_top_level_windows_for_test =
|
||||
OzonePlatform::PlatformProperties::
|
||||
override_set_parent_for_non_top_level_windows_for_test;
|
||||
|
||||
static base::NoDestructor<OzonePlatform::PlatformProperties> properties;
|
||||
static bool initialised = false;
|
||||
if (!initialised) {
|
||||
properties->custom_frame_pref_default = ui::GetCustomFramePrefDefault();
|
||||
|
||||
// When the Ozone X11 backend is running, use a UI loop to grab Expose
|
||||
// events. See GLSurfaceGLX and https://crbug.com/326995.
|
||||
properties->message_pump_type_for_gpu = base::MessagePumpType::UI;
|
||||
// When the Ozone X11 backend is running, use a UI loop to dispatch
|
||||
// SHM completion events.
|
||||
properties->message_pump_type_for_viz_compositor =
|
||||
base::MessagePumpType::UI;
|
||||
properties->supports_vulkan_swap_chain = true;
|
||||
properties->skia_can_fall_back_to_x11 = true;
|
||||
properties->platform_shows_drag_image = false;
|
||||
properties->app_modal_dialogs_use_event_blocker = true;
|
||||
|
||||
// Defaults to false unless explicitly enabled for testing.
|
||||
properties->set_parent_for_non_top_level_windows =
|
||||
override_set_parent_for_non_top_level_windows_for_test ==
|
||||
SupportsForTest::kYes;
|
||||
|
||||
initialised = true;
|
||||
}
|
||||
|
||||
return *properties;
|
||||
}
|
||||
|
||||
const PlatformRuntimeProperties& GetPlatformRuntimeProperties() override {
|
||||
static OzonePlatform::PlatformRuntimeProperties properties;
|
||||
|
||||
if (has_initialized_gpu() &&
|
||||
ui::GBMSupportX11::GetInstance()->has_gbm_device()) {
|
||||
// This property is set when the GetPlatformRuntimeProperties is
|
||||
// called on the gpu process side.
|
||||
properties.supports_native_pixmaps = true;
|
||||
}
|
||||
properties.supports_subwindows_as_accelerated_widgets = false;
|
||||
properties.supports_system_tray_windowing = true;
|
||||
properties.supports_server_window_menus =
|
||||
x11::Connection::Get()->WmSupportsHint(
|
||||
x11::GetAtom("_GTK_SHOW_WINDOW_MENU"));
|
||||
properties.supports_global_application_menus = true;
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
bool IsNativePixmapConfigSupported(viz::SharedImageFormat format,
|
||||
gfx::BufferUsage usage) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsWindowCompositingSupported() const override {
|
||||
return x11::Connection::Get()
|
||||
->GetOrCreateVisualManager()
|
||||
.ArgbVisualAvailable();
|
||||
}
|
||||
|
||||
bool InitializeUI(const InitParams& params) override {
|
||||
if (ShouldFailInitializeUIForTest()) {
|
||||
LOG(ERROR) << "Failing for test";
|
||||
return false;
|
||||
}
|
||||
// If opening the connection failed, we can not do anything. The platform
|
||||
// cannot initialise.
|
||||
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
|
||||
switches::kHeadless) &&
|
||||
!x11::Connection::Get()->Ready()) {
|
||||
LOG(ERROR) << "Missing X server or $DISPLAY";
|
||||
return false;
|
||||
}
|
||||
|
||||
InitializeCommon(params);
|
||||
CreatePlatformEventSource();
|
||||
overlay_manager_ = std::make_unique<StubOverlayManager>();
|
||||
input_controller_ = std::make_unique<StubInputController>();
|
||||
clipboard_ = std::make_unique<X11ClipboardOzone>();
|
||||
cursor_factory_ = std::make_unique<X11CursorFactory>();
|
||||
gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
|
||||
|
||||
// TODO(crbug.com/41472924): Support XKB.
|
||||
keyboard_layout_engine_ = std::make_unique<StubKeyboardLayoutEngine>();
|
||||
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
|
||||
keyboard_layout_engine_.get());
|
||||
|
||||
TouchFactory::SetTouchDeviceListFromCommandLine();
|
||||
|
||||
#if BUILDFLAG(USE_GTK)
|
||||
linux_ui_delegate_ = std::make_unique<LinuxUiDelegateX11>();
|
||||
#endif
|
||||
|
||||
menu_utils_ = std::make_unique<X11MenuUtils>();
|
||||
x11_utils_ = std::make_unique<X11Utils>();
|
||||
|
||||
base::UmaHistogramEnumeration("Linux.WindowManager", GetWindowManagerUMA());
|
||||
|
||||
base::UmaHistogramBoolean(
|
||||
"Linux.X11.XInput2",
|
||||
x11::Connection::Get()->xinput_version().first == 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InitializeGPU(const InitParams& params) override {
|
||||
InitializeCommon(params);
|
||||
if (params.enable_native_gpu_memory_buffers) {
|
||||
base::ThreadPool::PostTask(FROM_HERE, base::BindOnce([]() {
|
||||
ui::GBMSupportX11::GetInstance();
|
||||
}));
|
||||
}
|
||||
// In single process mode either the UI thread will create an event source
|
||||
// or it's a test and an event source isn't desired.
|
||||
if (!params.single_process)
|
||||
CreatePlatformEventSource();
|
||||
|
||||
// Set up the X11 connection before the sandbox gets set up. This cannot be
|
||||
// done later since opening the connection requires socket() and connect().
|
||||
auto connection = x11::Connection::Get()->Clone();
|
||||
connection->DetachFromSequence();
|
||||
surface_factory_ozone_ =
|
||||
std::make_unique<X11SurfaceFactory>(std::move(connection));
|
||||
}
|
||||
|
||||
void PostCreateMainMessageLoop(
|
||||
base::OnceCallback<void()> shutdown_cb,
|
||||
scoped_refptr<base::SingleThreadTaskRunner>) override {
|
||||
// Installs the X11 error handlers for the UI process after the
|
||||
// main message loop has started. This will allow us to exit cleanly
|
||||
// if X exits before we do.
|
||||
x11::Connection::Get()->SetIOErrorHandler(std::move(shutdown_cb));
|
||||
}
|
||||
|
||||
std::unique_ptr<PlatformUserInputMonitor> GetPlatformUserInputMonitor(
|
||||
const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
|
||||
override {
|
||||
return std::make_unique<X11UserInputMonitor>(std::move(io_task_runner));
|
||||
}
|
||||
|
||||
private:
|
||||
// Performs initialization steps need by both UI and GPU.
|
||||
void InitializeCommon(const InitParams& params) {
|
||||
if (common_initialized_)
|
||||
return;
|
||||
|
||||
common_initialized_ = true;
|
||||
}
|
||||
|
||||
// Creates |event_source_| if it doesn't already exist.
|
||||
void CreatePlatformEventSource() {
|
||||
if (event_source_)
|
||||
return;
|
||||
|
||||
auto* connection = x11::Connection::Get();
|
||||
event_source_ = std::make_unique<X11EventSource>(connection);
|
||||
}
|
||||
|
||||
bool common_initialized_ = false;
|
||||
|
||||
// Objects in the UI process.
|
||||
std::unique_ptr<KeyboardLayoutEngine> keyboard_layout_engine_;
|
||||
std::unique_ptr<OverlayManagerOzone> overlay_manager_;
|
||||
std::unique_ptr<InputController> input_controller_;
|
||||
std::unique_ptr<X11ClipboardOzone> clipboard_;
|
||||
std::unique_ptr<CursorFactory> cursor_factory_;
|
||||
std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
|
||||
std::unique_ptr<X11MenuUtils> menu_utils_;
|
||||
std::unique_ptr<X11Utils> x11_utils_;
|
||||
std::unique_ptr<PlatformGlobalShortcutListener> global_shortcut_listener_;
|
||||
|
||||
// Objects in the GPU process.
|
||||
std::unique_ptr<X11SurfaceFactory> surface_factory_ozone_;
|
||||
std::unique_ptr<GLEGLUtilityX11> gl_egl_utility_;
|
||||
|
||||
// Objects in both UI and GPU process.
|
||||
std::unique_ptr<X11EventSource> event_source_;
|
||||
|
||||
#if BUILDFLAG(USE_GTK)
|
||||
std::unique_ptr<LinuxUiDelegate> linux_ui_delegate_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
OzonePlatform* CreateOzonePlatformX11() {
|
||||
return new OzonePlatformX11;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_
|
||||
#define UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_
|
||||
|
||||
namespace ui {
|
||||
|
||||
class OzonePlatform;
|
||||
|
||||
// Constructor hook for use in ozone_platform_list.cc
|
||||
OzonePlatform* CreateOzonePlatformX11();
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_X11_OZONE_PLATFORM_X11_H_
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/x11/x11_surface_factory.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "components/viz/common/resources/shared_image_format_utils.h"
|
||||
#include "gpu/vulkan/buildflags.h"
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#include "ui/gfx/linux/gbm_buffer.h"
|
||||
#include "ui/gfx/linux/gbm_support_x11.h"
|
||||
#include "ui/gfx/linux/native_pixmap_dmabuf.h"
|
||||
#include "ui/gl/gl_bindings.h"
|
||||
#include "ui/gl/gl_surface_egl.h"
|
||||
#include "ui/gl/gl_surface_egl_x11_gles2.h"
|
||||
#include "ui/ozone/common/egl_util.h"
|
||||
#include "ui/ozone/common/gl_ozone_egl.h"
|
||||
#include "ui/ozone/common/native_pixmap_egl_binding.h"
|
||||
#include "ui/ozone/platform/x11/gl_surface_egl_readback_x11.h"
|
||||
#include "ui/ozone/platform/x11/native_pixmap_egl_x11_binding.h"
|
||||
#include "ui/ozone/platform/x11/x11_canvas_surface.h"
|
||||
|
||||
#if BUILDFLAG(ENABLE_VULKAN)
|
||||
#include "ui/ozone/platform/x11/vulkan_implementation_x11.h"
|
||||
#endif
|
||||
|
||||
namespace ui {
|
||||
namespace {
|
||||
|
||||
enum class NativePixmapSupportType {
|
||||
// Importing native pixmaps not supported.
|
||||
kNone,
|
||||
|
||||
// Native pixmaps are imported directly into EGL using the
|
||||
// EGL_EXT_image_dma_buf_import extension.
|
||||
kDMABuf,
|
||||
|
||||
// Native pixmaps are first imported as X11 pixmaps using DRI3 and then into
|
||||
// EGL.
|
||||
kX11Pixmap,
|
||||
};
|
||||
|
||||
NativePixmapSupportType GetNativePixmapSupportType() {
|
||||
if (gl::GLSurfaceEGL::GetGLDisplayEGL()
|
||||
->ext->b_EGL_EXT_image_dma_buf_import) {
|
||||
return NativePixmapSupportType::kDMABuf;
|
||||
} else if (NativePixmapEGLX11Binding::CanImportNativeGLXPixmap()) {
|
||||
return NativePixmapSupportType::kX11Pixmap;
|
||||
} else {
|
||||
return NativePixmapSupportType::kNone;
|
||||
}
|
||||
}
|
||||
|
||||
class GLOzoneEGLX11 : public GLOzoneEGL {
|
||||
public:
|
||||
GLOzoneEGLX11() = default;
|
||||
|
||||
GLOzoneEGLX11(const GLOzoneEGLX11&) = delete;
|
||||
GLOzoneEGLX11& operator=(const GLOzoneEGLX11&) = delete;
|
||||
|
||||
~GLOzoneEGLX11() override = default;
|
||||
|
||||
// GLOzone:
|
||||
bool InitializeStaticGLBindings(
|
||||
const gl::GLImplementationParts& implementation) override {
|
||||
is_swiftshader_ = gl::IsSoftwareGLImplementation(implementation);
|
||||
return GLOzoneEGL::InitializeStaticGLBindings(implementation);
|
||||
}
|
||||
|
||||
bool CanImportNativePixmap(viz::SharedImageFormat format) override {
|
||||
if (GetNativePixmapSupportType() == NativePixmapSupportType::kNone) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (GetNativePixmapSupportType()) {
|
||||
case NativePixmapSupportType::kDMABuf: {
|
||||
return NativePixmapEGLBinding::IsSharedImageFormatSupported(format);
|
||||
}
|
||||
case NativePixmapSupportType::kX11Pixmap: {
|
||||
return NativePixmapEGLX11Binding::IsSharedImageFormatSupported(format);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
scoped_refptr<gl::GLSurface> CreateViewGLSurface(
|
||||
gl::GLDisplay* display,
|
||||
gfx::AcceleratedWidget window) override {
|
||||
if (is_swiftshader_) {
|
||||
return gl::InitializeGLSurface(
|
||||
base::MakeRefCounted<GLSurfaceEglReadbackX11>(
|
||||
display->GetAs<gl::GLDisplayEGL>(), window));
|
||||
} else {
|
||||
switch (gl::GetGLImplementation()) {
|
||||
case gl::kGLImplementationEGLGLES2:
|
||||
DCHECK(window != gfx::kNullAcceleratedWidget);
|
||||
return gl::InitializeGLSurface(new gl::NativeViewGLSurfaceEGLX11GLES2(
|
||||
display->GetAs<gl::GLDisplayEGL>(),
|
||||
static_cast<x11::Window>(window)));
|
||||
case gl::kGLImplementationEGLANGLE:
|
||||
DCHECK(window != gfx::kNullAcceleratedWidget);
|
||||
return gl::InitializeGLSurface(new gl::NativeViewGLSurfaceEGLX11(
|
||||
display->GetAs<gl::GLDisplayEGL>(),
|
||||
static_cast<x11::Window>(window)));
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(
|
||||
gl::GLDisplay* display,
|
||||
const gfx::Size& size) override {
|
||||
gl::GLDisplayEGL* egl_display = display->GetAs<gl::GLDisplayEGL>();
|
||||
if (egl_display->IsEGLSurfacelessContextSupported() && size.width() == 0 &&
|
||||
size.height() == 0) {
|
||||
return InitializeGLSurface(new gl::SurfacelessEGL(egl_display, size));
|
||||
} else {
|
||||
return InitializeGLSurface(
|
||||
new gl::PbufferGLSurfaceEGL(egl_display, size));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// GLOzoneEGL:
|
||||
gl::EGLDisplayPlatform GetNativeDisplay() override {
|
||||
return gl::EGLDisplayPlatform(reinterpret_cast<EGLNativeDisplayType>(
|
||||
x11::Connection::Get()->GetXlibDisplay().display()));
|
||||
}
|
||||
|
||||
bool LoadGLES2Bindings(
|
||||
const gl::GLImplementationParts& implementation) override {
|
||||
return LoadDefaultEGLGLES2Bindings(implementation);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<NativePixmapGLBinding> ImportNativePixmap(
|
||||
scoped_refptr<gfx::NativePixmap> pixmap,
|
||||
viz::SharedImageFormat plane_format,
|
||||
std::optional<int> plane_index,
|
||||
gfx::Size plane_size,
|
||||
const gfx::ColorSpace& color_space,
|
||||
GLenum target,
|
||||
GLuint texture_id) override {
|
||||
switch (GetNativePixmapSupportType()) {
|
||||
case NativePixmapSupportType::kDMABuf: {
|
||||
return NativePixmapEGLBinding::Create(pixmap, plane_format, plane_index,
|
||||
plane_size, color_space, target,
|
||||
texture_id);
|
||||
}
|
||||
case NativePixmapSupportType::kX11Pixmap: {
|
||||
return NativePixmapEGLX11Binding::Create(
|
||||
pixmap, plane_format, plane_size, target, texture_id);
|
||||
}
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_swiftshader_ = false;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
X11SurfaceFactory::X11SurfaceFactory(
|
||||
std::unique_ptr<x11::Connection> connection)
|
||||
: egl_implementation_(std::make_unique<GLOzoneEGLX11>()),
|
||||
connection_(std::move(connection)) {}
|
||||
|
||||
X11SurfaceFactory::~X11SurfaceFactory() = default;
|
||||
|
||||
std::vector<gl::GLImplementationParts>
|
||||
X11SurfaceFactory::GetAllowedGLImplementations() {
|
||||
return std::vector<gl::GLImplementationParts>{
|
||||
gl::GLImplementationParts(gl::kGLImplementationEGLANGLE),
|
||||
};
|
||||
}
|
||||
|
||||
GLOzone* X11SurfaceFactory::GetGLOzone(
|
||||
const gl::GLImplementationParts& implementation) {
|
||||
switch (implementation.gl) {
|
||||
case gl::kGLImplementationEGLANGLE:
|
||||
return egl_implementation_.get();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#if BUILDFLAG(ENABLE_VULKAN)
|
||||
std::unique_ptr<gpu::VulkanImplementation>
|
||||
X11SurfaceFactory::CreateVulkanImplementation(bool use_swiftshader,
|
||||
bool allow_protected_memory) {
|
||||
return std::make_unique<VulkanImplementationX11>(use_swiftshader);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<SurfaceOzoneCanvas> X11SurfaceFactory::CreateCanvasForWidget(
|
||||
gfx::AcceleratedWidget widget) {
|
||||
// X11SoftwareBitmapPresenter (created via X11CanvasSurface) requres a
|
||||
// Connection TLS instance and a PlatformEventSource.
|
||||
if (connection_) {
|
||||
auto* connection = connection_.get();
|
||||
x11::Connection::Set(std::move(connection_));
|
||||
connection->platform_event_source =
|
||||
std::make_unique<X11EventSource>(connection);
|
||||
}
|
||||
return std::make_unique<X11CanvasSurface>(widget);
|
||||
}
|
||||
|
||||
scoped_refptr<gfx::NativePixmap> X11SurfaceFactory::CreateNativePixmap(
|
||||
gfx::AcceleratedWidget widget,
|
||||
gpu::VulkanDeviceQueue* device_queue,
|
||||
gfx::Size size,
|
||||
viz::SharedImageFormat format,
|
||||
gfx::BufferUsage usage,
|
||||
std::optional<gfx::Size> framebuffer_size) {
|
||||
scoped_refptr<gfx::NativePixmapDmaBuf> pixmap;
|
||||
auto buffer =
|
||||
ui::GBMSupportX11::GetInstance()->CreateBuffer(format, size, usage);
|
||||
if (buffer) {
|
||||
gfx::NativePixmapHandle handle = buffer->ExportHandle();
|
||||
if (handle.planes.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
pixmap = base::MakeRefCounted<gfx::NativePixmapDmaBuf>(size, format,
|
||||
std::move(handle));
|
||||
}
|
||||
|
||||
// CreateNativePixmap is non-blocking operation. Thus, it is safe to call it
|
||||
// and return the result with the provided callback.
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
bool X11SurfaceFactory::CanCreateNativePixmapForFormat(
|
||||
viz::SharedImageFormat format) {
|
||||
return ui::GBMSupportX11::GetInstance()->CanCreateBufferForFormat(format);
|
||||
}
|
||||
|
||||
scoped_refptr<gfx::NativePixmap>
|
||||
X11SurfaceFactory::CreateNativePixmapFromHandle(
|
||||
gfx::AcceleratedWidget widget,
|
||||
gfx::Size size,
|
||||
viz::SharedImageFormat format,
|
||||
gfx::NativePixmapHandle handle) {
|
||||
scoped_refptr<gfx::NativePixmapDmaBuf> pixmap;
|
||||
auto buffer = ui::GBMSupportX11::GetInstance()->CreateBufferFromHandle(
|
||||
size, format, std::move(handle));
|
||||
if (buffer) {
|
||||
gfx::NativePixmapHandle buffer_handle = buffer->ExportHandle();
|
||||
if (buffer_handle.planes.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
pixmap = base::MakeRefCounted<gfx::NativePixmapDmaBuf>(
|
||||
size, format, std::move(buffer_handle));
|
||||
}
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
bool X11SurfaceFactory::IsFormatSupportedForTexturing(
|
||||
viz::SharedImageFormat format) const {
|
||||
return ui::GBMSupportX11::GetInstance()->CanCreateBufferForFormat(format);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
// Copyright 2016 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_
|
||||
#define UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "components/viz/common/resources/shared_image_format.h"
|
||||
#include "gpu/vulkan/buildflags.h"
|
||||
#include "ui/gfx/x/connection.h"
|
||||
#include "ui/gl/gl_surface.h"
|
||||
#include "ui/ozone/public/gl_ozone.h"
|
||||
#include "ui/ozone/public/surface_factory_ozone.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
// Handles GL initialization and surface/context creation for X11.
|
||||
class X11SurfaceFactory : public SurfaceFactoryOzone {
|
||||
public:
|
||||
explicit X11SurfaceFactory(std::unique_ptr<x11::Connection> connection);
|
||||
|
||||
X11SurfaceFactory(const X11SurfaceFactory&) = delete;
|
||||
X11SurfaceFactory& operator=(const X11SurfaceFactory&) = delete;
|
||||
|
||||
~X11SurfaceFactory() override;
|
||||
|
||||
// SurfaceFactoryOzone:
|
||||
std::vector<gl::GLImplementationParts> GetAllowedGLImplementations() override;
|
||||
GLOzone* GetGLOzone(const gl::GLImplementationParts& implementation) override;
|
||||
#if BUILDFLAG(ENABLE_VULKAN)
|
||||
std::unique_ptr<gpu::VulkanImplementation> CreateVulkanImplementation(
|
||||
bool use_swiftshader,
|
||||
bool allow_protected_memory) override;
|
||||
#endif
|
||||
std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
|
||||
gfx::AcceleratedWidget widget) override;
|
||||
scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
|
||||
gfx::AcceleratedWidget widget,
|
||||
gpu::VulkanDeviceQueue* device_queue,
|
||||
gfx::Size size,
|
||||
viz::SharedImageFormat format,
|
||||
gfx::BufferUsage usage,
|
||||
std::optional<gfx::Size> framebuffer_size = std::nullopt) override;
|
||||
bool CanCreateNativePixmapForFormat(viz::SharedImageFormat format) override;
|
||||
scoped_refptr<gfx::NativePixmap> CreateNativePixmapFromHandle(
|
||||
gfx::AcceleratedWidget widget,
|
||||
gfx::Size size,
|
||||
viz::SharedImageFormat format,
|
||||
gfx::NativePixmapHandle handle) override;
|
||||
|
||||
bool IsFormatSupportedForTexturing(
|
||||
viz::SharedImageFormat format) const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<GLOzone> egl_implementation_;
|
||||
|
||||
std::unique_ptr<x11::Connection> connection_;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_X11_X11_SURFACE_FACTORY_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,521 @@
|
||||
// Copyright 2014 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_H_
|
||||
#define UI_OZONE_PLATFORM_X11_X11_WINDOW_H_
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/cancelable_callback.h"
|
||||
#include "base/containers/flat_set.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/raw_ref.h"
|
||||
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h"
|
||||
#include "ui/base/x/x11_desktop_window_move_client.h"
|
||||
#include "ui/base/x/x11_drag_drop_client.h"
|
||||
#include "ui/base/x/x11_move_loop_delegate.h"
|
||||
#include "ui/events/platform/platform_event_dispatcher.h"
|
||||
#include "ui/gfx/geometry/insets.h"
|
||||
#include "ui/gfx/x/connection.h"
|
||||
#include "ui/gfx/x/event.h"
|
||||
#include "ui/gfx/x/sync.h"
|
||||
#include "ui/gfx/x/xfixes.h"
|
||||
#include "ui/gfx/x/xproto.h"
|
||||
#include "ui/platform_window/extensions/workspace_extension.h"
|
||||
#include "ui/platform_window/extensions/x11_extension.h"
|
||||
#include "ui/platform_window/platform_window.h"
|
||||
#include "ui/platform_window/platform_window_init_properties.h"
|
||||
#include "ui/platform_window/wm/wm_drag_handler.h"
|
||||
#include "ui/platform_window/wm/wm_move_loop_handler.h"
|
||||
#include "ui/platform_window/wm/wm_move_resize_handler.h"
|
||||
|
||||
class SkPath;
|
||||
|
||||
namespace x11 {
|
||||
class GeometryCache;
|
||||
class WmSync;
|
||||
} // namespace x11
|
||||
|
||||
namespace ui {
|
||||
|
||||
class PlatformWindowDelegate;
|
||||
class X11ExtensionDelegate;
|
||||
class X11MoveLoop;
|
||||
class WorkspaceExtensionDelegate;
|
||||
|
||||
// PlatformWindow implementation for X11.
|
||||
class X11Window : public PlatformWindow,
|
||||
public WmMoveResizeHandler,
|
||||
public PlatformEventDispatcher,
|
||||
public x11::EventObserver,
|
||||
public WorkspaceExtension,
|
||||
public X11Extension,
|
||||
public WmDragHandler,
|
||||
public XDragDropClient::Delegate,
|
||||
public X11MoveLoopDelegate,
|
||||
public WmMoveLoopHandler,
|
||||
public X11DesktopWindowMoveClient::Delegate {
|
||||
public:
|
||||
explicit X11Window(PlatformWindowDelegate* platform_window_delegate);
|
||||
|
||||
X11Window(const X11Window&) = delete;
|
||||
X11Window& operator=(const X11Window&) = delete;
|
||||
|
||||
~X11Window() override;
|
||||
|
||||
virtual void Initialize(PlatformWindowInitProperties properties);
|
||||
|
||||
// X11WindowManager calls this.
|
||||
void OnXWindowLostCapture();
|
||||
|
||||
void OnCursorUpdate();
|
||||
|
||||
gfx::AcceleratedWidget GetWidget() const;
|
||||
gfx::Rect GetOuterBounds() const;
|
||||
void SetTransientWindow(x11::Window window);
|
||||
|
||||
bool has_pointer() const { return has_pointer_; }
|
||||
|
||||
// PlatformWindow:
|
||||
void Show(bool inactive) override;
|
||||
void Hide() override;
|
||||
void Close() override;
|
||||
bool IsVisible() const override;
|
||||
void PrepareForShutdown() override;
|
||||
void SetBoundsInPixels(const gfx::Rect& bounds) override;
|
||||
gfx::Rect GetBoundsInPixels() const override;
|
||||
void SetBoundsInDIP(const gfx::Rect& bounds) override;
|
||||
gfx::Rect GetBoundsInDIP() const override;
|
||||
void SetTitle(const std::u16string& title) override;
|
||||
void SetCapture() override;
|
||||
void ReleaseCapture() override;
|
||||
bool HasCapture() const override;
|
||||
void SetFullscreen(bool fullscreen, int64_t target_display_id) override;
|
||||
void Maximize() override;
|
||||
void Minimize() override;
|
||||
void Restore() override;
|
||||
void ShowWindowControlsMenu(const gfx::Point& point) override;
|
||||
PlatformWindowState GetPlatformWindowState() const override;
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
void SetUseNativeFrame(bool use_native_frame) override;
|
||||
bool ShouldUseNativeFrame() const override;
|
||||
void SetCursor(scoped_refptr<PlatformCursor> cursor) override;
|
||||
void MoveCursorTo(const gfx::Point& location) override;
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override;
|
||||
void SetRestoredBoundsInDIP(const gfx::Rect& bounds) final;
|
||||
gfx::Rect GetRestoredBoundsInDIP() const final;
|
||||
bool ShouldWindowContentsBeTransparent() const override;
|
||||
void SetZOrderLevel(ZOrderLevel order) override;
|
||||
ZOrderLevel GetZOrderLevel() const override;
|
||||
void StackAbove(gfx::AcceleratedWidget widget) override;
|
||||
void StackAtTop() override;
|
||||
void FlashFrame(bool flash_frame) override;
|
||||
void SetShape(std::unique_ptr<ShapeRects> native_shape,
|
||||
const gfx::Transform& transform) override;
|
||||
void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
|
||||
void SetWindowIcons(const gfx::ImageSkia& window_icon,
|
||||
const gfx::ImageSkia& app_icon) override;
|
||||
void SizeConstraintsChanged() override;
|
||||
void SetOpacity(float opacity) override;
|
||||
bool CanSetDecorationInsets() const override;
|
||||
void SetOpaqueRegion(
|
||||
std::optional<std::vector<gfx::Rect>> region_px) override;
|
||||
void SetInputRegion(std::optional<std::vector<gfx::Rect>> region_px) override;
|
||||
void NotifyStartupComplete(const std::string& startup_id) override;
|
||||
|
||||
// WorkspaceExtension:
|
||||
std::string GetWorkspace() const override;
|
||||
void SetVisibleOnAllWorkspaces(bool always_visible) override;
|
||||
bool IsVisibleOnAllWorkspaces() const override;
|
||||
void SetWorkspaceExtensionDelegate(
|
||||
WorkspaceExtensionDelegate* delegate) override;
|
||||
|
||||
// X11Extension:
|
||||
bool IsSyncExtensionAvailable() const override;
|
||||
bool IsWmTiling() const override;
|
||||
void OnCompleteSwapAfterResize(const gfx::Size& new_size) override;
|
||||
gfx::Rect GetXRootWindowOuterBounds() const override;
|
||||
void LowerXWindow() override;
|
||||
void SetOverrideRedirect(bool override_redirect) override;
|
||||
bool CanResetOverrideRedirect() const override;
|
||||
void SetX11ExtensionDelegate(X11ExtensionDelegate* delegate) override;
|
||||
bool IsWmSyncActiveForTest() override;
|
||||
|
||||
// x11::EventObserver:
|
||||
void OnEvent(const x11::Event& event) override;
|
||||
|
||||
protected:
|
||||
PlatformWindowDelegate* platform_window_delegate() const {
|
||||
return platform_window_delegate_;
|
||||
}
|
||||
|
||||
void OnXWindowStateChanged();
|
||||
void OnXWindowDamageEvent(const gfx::Rect& damage_rect);
|
||||
void OnXWindowCloseRequested();
|
||||
void OnXWindowIsActiveChanged(bool active);
|
||||
void OnXWindowWorkspaceChanged();
|
||||
void OnXWindowLostPointerGrab();
|
||||
void OnXWindowSelectionEvent(const x11::SelectionNotifyEvent& xev);
|
||||
void OnXWindowDragDropEvent(const x11::ClientMessageEvent& xev);
|
||||
std::optional<gfx::Size> GetMinimumSizeForXWindow();
|
||||
std::optional<gfx::Size> GetMaximumSizeForXWindow();
|
||||
SkPath GetWindowMaskForXWindow();
|
||||
|
||||
private:
|
||||
FRIEND_TEST_ALL_PREFIXES(X11WindowTest, Shape);
|
||||
FRIEND_TEST_ALL_PREFIXES(X11WindowTest, WindowManagerTogglesFullscreen);
|
||||
FRIEND_TEST_ALL_PREFIXES(X11WindowTest,
|
||||
ToggleMinimizePropogateToPlatformWindowDelegate);
|
||||
|
||||
void UpdateDecorationInsets();
|
||||
|
||||
// PlatformEventDispatcher:
|
||||
bool CanDispatchEvent(const PlatformEvent& event) override;
|
||||
uint32_t DispatchEvent(const PlatformEvent& event) override;
|
||||
|
||||
void DispatchUiEvent(ui::Event* event, const x11::Event& xev);
|
||||
|
||||
// WmMoveResizeHandler
|
||||
void DispatchHostWindowDragMovement(
|
||||
int hittest,
|
||||
const gfx::Point& pointer_location_in_px) override;
|
||||
|
||||
// WmMoveLoopHandler:
|
||||
bool RunMoveLoop(const gfx::Vector2d& drag_offset) override;
|
||||
void EndMoveLoop() override;
|
||||
|
||||
// WmDragHandler:
|
||||
bool StartDrag(const OSExchangeData& data,
|
||||
int operations,
|
||||
mojom::DragEventSource source,
|
||||
gfx::NativeCursor cursor,
|
||||
bool can_grab_pointer,
|
||||
base::OnceClosure drag_started_callback,
|
||||
WmDragHandler::DragFinishedCallback drag_finished_callback,
|
||||
WmDragHandler::LocationDelegate* delegate) override;
|
||||
void CancelDrag() override;
|
||||
void UpdateDragImage(const gfx::ImageSkia& image,
|
||||
const gfx::Vector2d& offset) override;
|
||||
|
||||
// XDragDropClient::Delegate
|
||||
std::optional<gfx::AcceleratedWidget> GetDragWidget() override;
|
||||
int UpdateDrag(const gfx::Point& screen_point) override;
|
||||
void UpdateCursor(mojom::DragOperation negotiated_operation) override;
|
||||
void OnBeginForeignDrag(x11::Window window) override;
|
||||
void OnEndForeignDrag() override;
|
||||
void OnBeforeDragLeave() override;
|
||||
mojom::DragOperation PerformDrop() override;
|
||||
void EndDragLoop() override;
|
||||
|
||||
// X11MoveLoopDelegate
|
||||
void OnMouseMovement(const gfx::Point& screen_point,
|
||||
int flags,
|
||||
base::TimeTicks event_time) override;
|
||||
void OnMouseReleased() override;
|
||||
void OnMoveLoopEnded() override;
|
||||
|
||||
// X11DesktopWindowMoveClient::Delegate:
|
||||
void SetBoundsOnMove(const gfx::Rect& requested_bounds) override;
|
||||
scoped_refptr<X11Cursor> GetLastCursor() override;
|
||||
gfx::Size GetSize() override;
|
||||
|
||||
void QuitDragLoop();
|
||||
|
||||
// Handles `event` as an Atk Key Event
|
||||
bool HandleAsAtkEvent(const x11::Event& event);
|
||||
|
||||
// Adjusts |requested_size_in_pixels| to avoid the WM "feature" where setting
|
||||
// the window size to the monitor size causes the WM to set the EWMH for
|
||||
// fullscreen.
|
||||
gfx::Size AdjustSizeForDisplay(const gfx::Size& requested_size_in_pixels);
|
||||
|
||||
// Creates the X window with the given properties.
|
||||
// Depending on presence of the compositing manager and window type, may
|
||||
// change the opacity, in which case returns the final opacity type through
|
||||
// |opacity|.
|
||||
void CreateXWindow(const PlatformWindowInitProperties& properties);
|
||||
void CloseXWindow();
|
||||
void Map(bool inactive = false);
|
||||
void SetWMStateFullscreen(bool fullscreen);
|
||||
void SetWMStateMaximize(bool maximize);
|
||||
bool IsActive() const;
|
||||
bool IsTargetedBy(const x11::Event& xev) const;
|
||||
void HandleEvent(const x11::Event& xev);
|
||||
|
||||
bool IsMinimized() const;
|
||||
bool IsMaximized() const;
|
||||
bool IsFullscreen() const;
|
||||
|
||||
void SetFlashFrameHint(bool flash_frame);
|
||||
void UpdateMinAndMaxSize();
|
||||
void DispatchResize(bool origin_changed);
|
||||
void CancelResize();
|
||||
|
||||
// Resets the window region for the current window bounds if necessary.
|
||||
void ResetWindowRegion();
|
||||
|
||||
x11::Window window() const { return xwindow_; }
|
||||
x11::Window root_window() const { return x_root_window_; }
|
||||
std::vector<x11::Rectangle>* shape() const { return window_shape_.get(); }
|
||||
|
||||
// Updates |xwindow_|'s _NET_WM_USER_TIME if |xwindow_| is active.
|
||||
void UpdateWMUserTime(ui::Event* event);
|
||||
|
||||
// Called on an XFocusInEvent, XFocusOutEvent, XIFocusInEvent, or an
|
||||
// XIFocusOutEvent.
|
||||
void OnFocusEvent(bool focus_in,
|
||||
x11::NotifyMode mode,
|
||||
x11::NotifyDetail detail);
|
||||
|
||||
// Called on an XEnterWindowEvent, XLeaveWindowEvent, XIEnterEvent, or an
|
||||
// XILeaveEvent.
|
||||
void OnCrossingEvent(bool enter,
|
||||
bool focus_in_window_or_ancestor,
|
||||
x11::NotifyMode mode,
|
||||
x11::NotifyDetail detail);
|
||||
|
||||
// Called when |xwindow_|'s _NET_WM_STATE property is updated.
|
||||
void OnWMStateUpdated();
|
||||
|
||||
WindowTiledEdges GetTiledState() const;
|
||||
|
||||
// Called when |xwindow_|'s _NET_FRAME_EXTENTS property is updated.
|
||||
void OnFrameExtentsUpdated();
|
||||
|
||||
void OnConfigureEvent(const x11::ConfigureNotifyEvent& event);
|
||||
|
||||
void OnWorkspaceUpdated();
|
||||
|
||||
void OnWindowMapped();
|
||||
|
||||
// Record the activation state.
|
||||
void BeforeActivationStateChanged();
|
||||
|
||||
// Handle the state change since BeforeActivationStateChanged().
|
||||
void AfterActivationStateChanged();
|
||||
|
||||
void MaybeUpdateOcclusionState();
|
||||
|
||||
void DelayedResize(bool origin_changed);
|
||||
|
||||
// If mapped, sends a message to the window manager to enable or disable the
|
||||
// states |state1| and |state2|. Otherwise, the states will be enabled or
|
||||
// disabled on the next map. It's the caller's responsibility to make sure
|
||||
// atoms are set and unset in the appropriate pairs. For example, if a caller
|
||||
// sets (_NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ), it would
|
||||
// be invalid to unset the maximized state by making two calls like
|
||||
// (_NET_WM_STATE_MAXIMIZED_VERT, x11::None), (_NET_WM_STATE_MAXIMIZED_HORZ,
|
||||
// x11::None).
|
||||
void SetWMSpecState(bool enabled, x11::Atom state1, x11::Atom state2);
|
||||
|
||||
// Updates |window_properties_| with |new_window_properties|.
|
||||
void UpdateWindowProperties(
|
||||
const base::flat_set<x11::Atom>& new_window_properties);
|
||||
|
||||
void UnconfineCursor();
|
||||
|
||||
void UpdateWindowRegion(std::unique_ptr<std::vector<x11::Rectangle>> region);
|
||||
|
||||
void NotifyBoundsChanged(bool origin_changed);
|
||||
|
||||
// Initializes as a status icon window.
|
||||
bool InitializeAsStatusIcon();
|
||||
|
||||
void SetBoundsWithWmSync(const gfx::Rect& bounds_px);
|
||||
|
||||
void OnWmSynced();
|
||||
|
||||
void OnBoundsChanged(const std::optional<gfx::Rect>& old_bounds_px,
|
||||
const gfx::Rect& new_bounds_px);
|
||||
|
||||
void MaybeUpdateSyncCounter();
|
||||
|
||||
// Stores current state of this window.
|
||||
PlatformWindowState state_ = PlatformWindowState::kUnknown;
|
||||
|
||||
WindowTiledEdges tiled_state_;
|
||||
|
||||
const raw_ptr<PlatformWindowDelegate> platform_window_delegate_;
|
||||
|
||||
raw_ptr<WorkspaceExtensionDelegate, DanglingUntriaged>
|
||||
workspace_extension_delegate_ = nullptr;
|
||||
|
||||
raw_ptr<X11ExtensionDelegate, DanglingUntriaged> x11_extension_delegate_ =
|
||||
nullptr;
|
||||
|
||||
// Tells if the window got a ::Close call.
|
||||
bool is_shutting_down_ = false;
|
||||
|
||||
// The z-order level of the window; the window exhibits "always on top"
|
||||
// behavior if > 0.
|
||||
ui::ZOrderLevel z_order_ = ui::ZOrderLevel::kNormal;
|
||||
|
||||
// The bounds of our window before the window was maximized.
|
||||
gfx::Rect restored_bounds_in_pixels_;
|
||||
|
||||
std::unique_ptr<X11DesktopWindowMoveClient> x11_window_move_client_;
|
||||
|
||||
// Whether the drop handler has notified that the drag has entered.
|
||||
bool notified_enter_ = false;
|
||||
// Keeps the last negotiated operations returned by the drop handler.
|
||||
int allowed_drag_operations_ = 0;
|
||||
|
||||
// Handles XDND events going through this window.
|
||||
std::unique_ptr<XDragDropClient> drag_drop_client_;
|
||||
WmDragHandler::DragFinishedCallback drag_finished_callback_;
|
||||
raw_ptr<WmDragHandler::LocationDelegate, DanglingUntriaged>
|
||||
drag_location_delegate_ = nullptr;
|
||||
|
||||
// Run loop used while dragging from this window.
|
||||
std::unique_ptr<X11MoveLoop> drag_loop_;
|
||||
|
||||
// Events that we have selected on the source window of the incoming drag.
|
||||
x11::ScopedEventSelector source_window_events_;
|
||||
|
||||
// The display and the native X window hosting the root window.
|
||||
const raw_ref<x11::Connection> connection_;
|
||||
x11::Window xwindow_ = x11::Window::None;
|
||||
x11::Window x_root_window_ = x11::Window::None;
|
||||
|
||||
// Any native, modal dialog hanging from this window.
|
||||
x11::Window transient_window_ = x11::Window::None;
|
||||
|
||||
// Events selected on |xwindow_|.
|
||||
x11::ScopedEventSelector xwindow_events_;
|
||||
|
||||
// The window manager state bits.
|
||||
base::flat_set<x11::Atom> window_properties_;
|
||||
|
||||
// Is this window able to receive focus?
|
||||
bool activatable_ = true;
|
||||
|
||||
// Was this window initialized with the override_redirect window attribute?
|
||||
bool override_redirect_ = false;
|
||||
|
||||
std::optional<std::u16string> window_title_;
|
||||
|
||||
// Whether the window is visible with respect to Aura.
|
||||
bool window_mapped_in_client_ = false;
|
||||
|
||||
// Whether the window is mapped with respect to the X server.
|
||||
bool window_mapped_in_server_ = false;
|
||||
|
||||
// The bounds of `xwindow_`. If `bounds_wm_sync_` is active, then
|
||||
// `last_set_bounds_px_` should be treated as the current bounds. Otherwise,
|
||||
// the bounds from `geometry_cache_` should be used.
|
||||
gfx::Rect last_set_bounds_px_;
|
||||
std::unique_ptr<x11::WmSync> bounds_wm_sync_;
|
||||
std::unique_ptr<x11::GeometryCache> geometry_cache_;
|
||||
|
||||
x11::VisualId visual_id_{};
|
||||
|
||||
// Whether we used an ARGB visual for our window.
|
||||
bool visual_has_alpha_ = false;
|
||||
|
||||
// The workspace containing |xwindow_|. This will be std::nullopt when
|
||||
// _NET_WM_DESKTOP is unset.
|
||||
std::optional<int> workspace_;
|
||||
|
||||
// True if the window should stay on top of most other windows.
|
||||
bool is_always_on_top_ = false;
|
||||
|
||||
// True if the window is security-sensitive. Implies |is_always_on_top_|.
|
||||
bool is_security_surface_ = false;
|
||||
|
||||
// True if the window is fully obscured by another window.
|
||||
bool is_occluded_ = false;
|
||||
|
||||
PlatformWindowOcclusionState occlusion_state_ =
|
||||
PlatformWindowOcclusionState::kUnknown;
|
||||
|
||||
// Does |xwindow_| have the pointer grab (XI2 or normal)?
|
||||
bool has_pointer_grab_ = false;
|
||||
|
||||
// The focus-tracking state variables are as described in
|
||||
// gtk/docs/focus_tracking.txt
|
||||
//
|
||||
// |xwindow_| is active iff:
|
||||
// (|has_window_focus_| || |has_pointer_focus_|) &&
|
||||
// !|ignore_keyboard_input_|
|
||||
|
||||
// Is the pointer in |xwindow_| or one of its children?
|
||||
bool has_pointer_ = false;
|
||||
|
||||
// Is |xwindow_| or one of its children focused?
|
||||
bool has_window_focus_ = false;
|
||||
|
||||
// (An ancestor window or the PointerRoot is focused) && |has_pointer_|.
|
||||
// |has_pointer_focus_| == true is the odd case where we will receive keyboard
|
||||
// input when |has_window_focus_| == false. |has_window_focus_| and
|
||||
// |has_pointer_focus_| are mutually exclusive.
|
||||
bool has_pointer_focus_ = false;
|
||||
|
||||
// X11 does not support defocusing windows; you can only focus a different
|
||||
// window. If we would like to be defocused, we just ignore keyboard input we
|
||||
// no longer care about.
|
||||
bool ignore_keyboard_input_ = false;
|
||||
|
||||
// Used for tracking activation state in {Before|After}ActivationStateChanged.
|
||||
bool was_active_ = false;
|
||||
bool had_pointer_ = false;
|
||||
bool had_pointer_grab_ = false;
|
||||
bool had_window_focus_ = false;
|
||||
|
||||
// True if a Maximize() call should be done after mapping the window.
|
||||
bool should_maximize_after_map_ = false;
|
||||
|
||||
// True if GrabPointer() should be called after mapping the window.
|
||||
bool should_grab_pointer_after_map_ = false;
|
||||
|
||||
// Whether we currently are flashing our frame. This feature is implemented
|
||||
// by setting the urgency hint with the window manager, which can draw
|
||||
// attention to the window or completely ignore the hint. We stop flashing
|
||||
// the frame when |xwindow_| gains focus or handles a mouse button event.
|
||||
bool urgency_hint_set_ = false;
|
||||
|
||||
// |xwindow_|'s minimum size.
|
||||
gfx::Size min_size_in_pixels_;
|
||||
|
||||
// |xwindow_|'s maximum size.
|
||||
gfx::Size max_size_in_pixels_;
|
||||
|
||||
// The window shape if the window is non-rectangular.
|
||||
std::unique_ptr<std::vector<x11::Rectangle>> window_shape_;
|
||||
|
||||
// Whether |window_shape_| was set via SetShape().
|
||||
bool custom_window_shape_ = false;
|
||||
|
||||
// True if the window has title-bar / borders provided by the window manager.
|
||||
bool use_native_frame_ = false;
|
||||
|
||||
// The size of the window manager provided borders (if any).
|
||||
gfx::Insets native_window_frame_borders_in_pixels_;
|
||||
|
||||
// Used for synchronizing between `xwindow_` and the WM during resizing.
|
||||
x11::Sync::Counter update_counter_{};
|
||||
std::optional<x11::Sync::Int64> configure_counter_value_;
|
||||
std::optional<gfx::Size> last_configure_size_;
|
||||
std::optional<gfx::Size> last_swapped_size_;
|
||||
|
||||
base::CancelableOnceClosure delayed_resize_task_;
|
||||
|
||||
// Keep track of barriers to confine cursor.
|
||||
bool has_pointer_barriers_ = false;
|
||||
std::array<x11::XFixes::Barrier, 4> pointer_barriers_;
|
||||
|
||||
scoped_refptr<X11Cursor> last_cursor_;
|
||||
|
||||
base::CancelableOnceCallback<void(x11::Cursor)> on_cursor_loaded_;
|
||||
|
||||
base::WeakPtrFactory<X11Window> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_X11_X11_WINDOW_H_
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ui/ozone/platform/x11/x11_window_manager.h"
|
||||
|
||||
#include "ui/ozone/platform/x11/x11_window.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace {
|
||||
|
||||
X11WindowManager* g_instance = nullptr;
|
||||
|
||||
} // namespace
|
||||
|
||||
X11WindowManager::X11WindowManager() {
|
||||
DCHECK(!g_instance) << "There should only be a single X11WindowManager";
|
||||
g_instance = this;
|
||||
}
|
||||
|
||||
X11WindowManager::~X11WindowManager() = default;
|
||||
|
||||
// static
|
||||
X11WindowManager* X11WindowManager::GetInstance() {
|
||||
if (!g_instance) {
|
||||
auto manager = std::make_unique<X11WindowManager>();
|
||||
X11WindowManager* manager_ptr = manager.release();
|
||||
DCHECK_EQ(g_instance, manager_ptr);
|
||||
}
|
||||
return g_instance;
|
||||
}
|
||||
|
||||
void X11WindowManager::GrabEvents(X11Window* window) {
|
||||
DCHECK_NE(located_events_grabber_, window);
|
||||
|
||||
// Grabbing the mouse is asynchronous. However, we synchronously start
|
||||
// forwarding all mouse events received by Chrome to the
|
||||
// aura::WindowEventDispatcher which has capture. This makes capture
|
||||
// synchronous for all intents and purposes if either:
|
||||
// - |located_events_grabber_| is set to have capture.
|
||||
// OR
|
||||
// - The topmost window underneath the mouse is managed by Chrome.
|
||||
auto* old_grabber = located_events_grabber_.get();
|
||||
|
||||
// Update |located_events_grabber_| prior to calling OnXWindowLostCapture() to
|
||||
// avoid releasing pointer grab.
|
||||
located_events_grabber_ = window;
|
||||
if (old_grabber)
|
||||
old_grabber->OnXWindowLostCapture();
|
||||
|
||||
// the X11Window calls GrabPointer by itself.
|
||||
}
|
||||
|
||||
void X11WindowManager::UngrabEvents(X11Window* window) {
|
||||
DCHECK_EQ(located_events_grabber_, window);
|
||||
// Release mouse grab asynchronously. A window managed by Chrome is likely
|
||||
// the topmost window underneath the mouse so the capture release being
|
||||
// asynchronous is likely inconsequential.
|
||||
auto* old_grabber = located_events_grabber_.get();
|
||||
located_events_grabber_ = nullptr;
|
||||
old_grabber->OnXWindowLostCapture();
|
||||
}
|
||||
|
||||
void X11WindowManager::AddWindow(X11Window* window) {
|
||||
DCHECK(window);
|
||||
auto widget = window->GetWidget();
|
||||
DCHECK_NE(gfx::kNullAcceleratedWidget, widget);
|
||||
DCHECK(!windows_.contains(widget));
|
||||
windows_.emplace(widget, window);
|
||||
}
|
||||
|
||||
void X11WindowManager::RemoveWindow(X11Window* window) {
|
||||
DCHECK(window);
|
||||
auto widget = window->GetWidget();
|
||||
auto it = windows_.find(widget);
|
||||
// The XWindow might not have been initialized due to some errors.
|
||||
if (widget == gfx::kNullAcceleratedWidget) {
|
||||
DCHECK(it == windows_.end());
|
||||
} else {
|
||||
CHECK(it != windows_.end());
|
||||
if (window_mouse_currently_on_ == it->second)
|
||||
window_mouse_currently_on_ = nullptr;
|
||||
windows_.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
X11Window* X11WindowManager::GetWindow(gfx::AcceleratedWidget widget) const {
|
||||
auto it = windows_.find(widget);
|
||||
return it != windows_.end() ? it->second : nullptr;
|
||||
}
|
||||
|
||||
void X11WindowManager::MouseOnWindow(X11Window* window) {
|
||||
if (window_mouse_currently_on_ == window)
|
||||
return;
|
||||
|
||||
window_mouse_currently_on_ = window;
|
||||
window->OnCursorUpdate();
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// Copyright 2019 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_
|
||||
#define UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "ui/gfx/native_ui_types.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class X11Window;
|
||||
|
||||
class X11WindowManager {
|
||||
public:
|
||||
X11WindowManager();
|
||||
|
||||
X11WindowManager(const X11WindowManager&) = delete;
|
||||
X11WindowManager& operator=(const X11WindowManager&) = delete;
|
||||
|
||||
~X11WindowManager();
|
||||
|
||||
// Returns instance of X11WindowManager.
|
||||
static X11WindowManager* GetInstance();
|
||||
|
||||
// Sets a given X11Window as the recipient for events and calls
|
||||
// OnLostCapture for another |located_events_grabber_| if it has been set
|
||||
// previously.
|
||||
void GrabEvents(X11Window* window);
|
||||
|
||||
// Unsets a given X11Window as the recipient for events and calls
|
||||
// OnLostCapture.
|
||||
void UngrabEvents(X11Window* window);
|
||||
|
||||
// Gets the current X11PlatformWindow recipient of mouse events.
|
||||
X11Window* located_events_grabber() const { return located_events_grabber_; }
|
||||
|
||||
// Gets the window corresponding to the AcceleratedWidget |widget|.
|
||||
void AddWindow(X11Window* window);
|
||||
void RemoveWindow(X11Window* window);
|
||||
X11Window* GetWindow(gfx::AcceleratedWidget widget) const;
|
||||
|
||||
void MouseOnWindow(X11Window* delegate);
|
||||
|
||||
const X11Window* window_mouse_currently_on_for_test() const {
|
||||
return window_mouse_currently_on_;
|
||||
}
|
||||
|
||||
private:
|
||||
raw_ptr<X11Window> located_events_grabber_ = nullptr;
|
||||
raw_ptr<X11Window> window_mouse_currently_on_ = nullptr;
|
||||
|
||||
base::flat_map<gfx::AcceleratedWidget, raw_ptr<X11Window, CtnExperimental>>
|
||||
windows_;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_H_
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2015 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_
|
||||
#define UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ui/gfx/native_ui_types.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class OverlayCandidatesOzone;
|
||||
|
||||
// Responsible for providing the oracles used to decide when overlays can be
|
||||
// used.
|
||||
class OverlayManagerOzone {
|
||||
public:
|
||||
virtual ~OverlayManagerOzone() {}
|
||||
|
||||
// Get the hal struct to check for overlay support.
|
||||
virtual std::unique_ptr<OverlayCandidatesOzone> CreateOverlayCandidates(
|
||||
gfx::AcceleratedWidget w) = 0;
|
||||
|
||||
bool allow_sync_and_real_buffer_page_flip_testing() const {
|
||||
return allow_sync_and_real_buffer_page_flip_testing_;
|
||||
}
|
||||
|
||||
// Tell the manager that the overlay delegation is enabled. This is only
|
||||
// useful for Wayland as checking for overlay support depends on
|
||||
// features::IsDelegatedCompositingEnabled, which cannot be accessed from
|
||||
// //ui/ozone.
|
||||
// TODO(msisov, petermcneeley): remove this once Wayland uses only delegated
|
||||
// context.
|
||||
virtual void SetContextDelegated() {}
|
||||
|
||||
protected:
|
||||
// TODO(fangzhoug): Some Chrome OS boards still use the legacy video decoder.
|
||||
// Remove this once ChromeOSVideoDecoder is on everywhere.
|
||||
bool allow_sync_and_real_buffer_page_flip_testing_ = false;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_OZONE_PUBLIC_OVERLAY_MANAGER_OZONE_H_
|
||||
Reference in New Issue
Block a user