зеркало из https://github.com/electron/electron.git
fix: calling of X11 functions when running under Wayland (#33355)
* fix: don't call X11 functions in file dialog and message box * refactor: remove unused GtkUiPlatform declaration * fix: set gtk darktheme only when running under X11 * fix: replace X11 window state watcher with implementation using ozone * fix: make sure global menu barr is used only when supported * fix: don't call X11 function in native window views under wayland * style: fix lint issues * fix: use GtkUiPlatform::ShowGtkWindow instead of gtk_window_present directly * refactor: extract CreateGlobalMenuBar into separate function * refactor: move checking for WaylandWindowDecorations inside class * fix: check if we run under X11 only in ozone build * refactor: drop including unused ui/base/ui_base_features.h header * fix: modify ui_gtk_public_header.patch to also export gtk_ui.h * fix: refactor guarding of X11 calls - Introduce patch exposing new electron_can_call_x11 property - Replace defined(USE_OZONE) with BUILDFLAG(OZONE_PLATFORM_X11) flags * fix: remove the last remaining usage of USE_X11 * fix: usage of BUILDFLAG(OZONE_PLATFORM_X11) not building on non ozone * fix: call UpdateWindowState from OnBoundsChanged only under X11
This commit is contained in:
Родитель
1153a5ce5a
Коммит
cdf2b3f4e4
1
BUILD.gn
1
BUILD.gn
|
@ -563,7 +563,6 @@ source_set("electron_lib") {
|
|||
defines += [
|
||||
# Disable warnings for g_settings_list_schemas.
|
||||
"GLIB_DISABLE_DEPRECATION_WARNINGS",
|
||||
"USE_X11=1",
|
||||
]
|
||||
|
||||
sources += [
|
||||
|
|
|
@ -53,8 +53,6 @@ filenames = {
|
|||
"shell/browser/ui/views/global_menu_bar_x11.h",
|
||||
"shell/browser/ui/x/event_disabler.cc",
|
||||
"shell/browser/ui/x/event_disabler.h",
|
||||
"shell/browser/ui/x/window_state_watcher.cc",
|
||||
"shell/browser/ui/x/window_state_watcher.h",
|
||||
"shell/browser/ui/x/x_window_utils.cc",
|
||||
"shell/browser/ui/x/x_window_utils.h",
|
||||
]
|
||||
|
|
|
@ -114,3 +114,4 @@ port_autofill_colors_to_the_color_pipeline.patch
|
|||
build_disable_partition_alloc_on_mac.patch
|
||||
fix_non-client_mouse_tracking_and_message_bubbling_on_windows.patch
|
||||
build_make_libcxx_abi_unstable_false_for_electron.patch
|
||||
introduce_ozoneplatform_electron_can_call_x11_property.patch
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Marek Rusinowski <marekrusinowski@gmail.com>
|
||||
Date: Wed, 23 Mar 2022 21:09:37 +0100
|
||||
Subject: introduce OzonePlatform::electron_can_call_x11 property
|
||||
|
||||
We expose this additonal property in the OzonePlatform to be able to easily
|
||||
determine whatever we can call X11 functions without crashing the application
|
||||
at rutime. It would be best if eventually all usages of this property were
|
||||
replaced with clean ozone native implementations.
|
||||
|
||||
diff --git a/ui/ozone/platform/x11/ozone_platform_x11.cc b/ui/ozone/platform/x11/ozone_platform_x11.cc
|
||||
index 9008af973427d7dab8170449bc5767cebc9d2e9e..e312287e4aca61b51a69c8413088f56f9f704b5e 100644
|
||||
--- a/ui/ozone/platform/x11/ozone_platform_x11.cc
|
||||
+++ b/ui/ozone/platform/x11/ozone_platform_x11.cc
|
||||
@@ -200,6 +200,7 @@ class OzonePlatformX11 : public OzonePlatform,
|
||||
properties->supports_vulkan_swap_chain = true;
|
||||
properties->uses_external_vulkan_image_factory = true;
|
||||
properties->skia_can_fall_back_to_x11 = true;
|
||||
+ properties->electron_can_call_x11 = true;
|
||||
properties->platform_shows_drag_image = false;
|
||||
properties->supports_global_application_menus = true;
|
||||
properties->app_modal_dialogs_use_event_blocker = true;
|
||||
diff --git a/ui/ozone/public/ozone_platform.h b/ui/ozone/public/ozone_platform.h
|
||||
index 22ba32317a74df24249d1528dcaaa28ff18bd0f4..fa57f97520a0327be2c7f5179591ca61b801c8b0 100644
|
||||
--- a/ui/ozone/public/ozone_platform.h
|
||||
+++ b/ui/ozone/public/ozone_platform.h
|
||||
@@ -132,6 +132,10 @@ class COMPONENT_EXPORT(OZONE) OzonePlatform {
|
||||
// Linux only: determines if Skia can fall back to the X11 output device.
|
||||
bool skia_can_fall_back_to_x11 = false;
|
||||
|
||||
+ // Linux only: determines is Electron can call selected X11 functions while
|
||||
+ // it migrates to pure ozone abstractions.
|
||||
+ bool electron_can_call_x11 = false;
|
||||
+
|
||||
// Wayland only: determines whether windows which are not top level ones
|
||||
// should be given parents explicitly.
|
||||
bool set_parent_for_non_top_level_windows = false;
|
|
@ -3,22 +3,32 @@ From: deepak1556 <hop2deep@gmail.com>
|
|||
Date: Fri, 10 Apr 2020 17:47:18 -0700
|
||||
Subject: ui_gtk_public_header.patch
|
||||
|
||||
Allow electron to depend on //ui/gtk/gtk_util.h
|
||||
Allow electron to depend on gtk_util.h and gtk_ui.h from //ui/gtk/
|
||||
|
||||
diff --git a/ui/gtk/BUILD.gn b/ui/gtk/BUILD.gn
|
||||
index 4093df78da0bbb1d8df743942f364cf728ad3414..2f31d99b207ffc3531b5334b5a01239cc1fefb35 100644
|
||||
index 4093df78da0bbb1d8df743942f364cf728ad3414..2f7c404307bfebb0e2890148cf9b0d6d9c68094f 100644
|
||||
--- a/ui/gtk/BUILD.gn
|
||||
+++ b/ui/gtk/BUILD.gn
|
||||
@@ -69,7 +69,7 @@ generate_stubs("gtk_stubs") {
|
||||
@@ -69,7 +69,11 @@ generate_stubs("gtk_stubs") {
|
||||
}
|
||||
|
||||
component("gtk") {
|
||||
- public = [ "gtk_ui_factory.h" ]
|
||||
+ public = [ "gtk_ui_factory.h", "gtk_util.h" ]
|
||||
+ public = [
|
||||
+ "gtk_ui.h",
|
||||
+ "gtk_ui_factory.h",
|
||||
+ "gtk_util.h",
|
||||
+ ]
|
||||
|
||||
sources = [
|
||||
"gtk_color_mixers.cc",
|
||||
@@ -85,7 +85,6 @@ component("gtk") {
|
||||
@@ -79,13 +83,11 @@ component("gtk") {
|
||||
"gtk_key_bindings_handler.cc",
|
||||
"gtk_key_bindings_handler.h",
|
||||
"gtk_ui.cc",
|
||||
- "gtk_ui.h",
|
||||
"gtk_ui_factory.cc",
|
||||
"gtk_ui_platform.h",
|
||||
"gtk_ui_platform_stub.cc",
|
||||
"gtk_ui_platform_stub.h",
|
||||
"gtk_util.cc",
|
||||
|
|
|
@ -36,12 +36,6 @@ class Screen;
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_X11)
|
||||
namespace ui {
|
||||
class GtkUiPlatform;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace device {
|
||||
class GeolocationManager;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "ui/display/win/screen_win.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE) || defined(USE_X11)
|
||||
#if defined(USE_OZONE)
|
||||
#include "ui/base/ui_base_features.h"
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "content/public/browser/desktop_media_id.h"
|
||||
#include "shell/browser/api/electron_api_web_contents.h"
|
||||
#include "shell/browser/native_browser_view_views.h"
|
||||
#include "shell/browser/native_window_features.h"
|
||||
#include "shell/browser/ui/drag_util.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents.h"
|
||||
#include "shell/browser/ui/inspectable_web_contents_view.h"
|
||||
|
@ -55,20 +54,16 @@
|
|||
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
|
||||
#include "ui/views/window/native_frame_view.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#if defined(USE_OZONE)
|
||||
#include "shell/browser/ui/views/global_menu_bar_x11.h"
|
||||
#include "shell/browser/ui/x/event_disabler.h"
|
||||
#include "shell/browser/ui/x/window_state_watcher.h"
|
||||
#include "shell/browser/ui/x/x_window_utils.h"
|
||||
#include "ui/base/x/x11_util.h"
|
||||
#include "ui/gfx/x/shape.h"
|
||||
#include "ui/gfx/x/x11_atom_cache.h"
|
||||
#include "ui/gfx/x/xproto.h"
|
||||
#include "ui/gfx/x/xproto_util.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE) || defined(USE_X11)
|
||||
#include "ui/base/ui_base_features.h"
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#endif
|
||||
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
|
@ -130,6 +125,26 @@ gfx::Rect DIPToScreenRect(HWND hwnd, const gfx::Rect& pixel_bounds) {
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE)
|
||||
|
||||
bool CreateGlobalMenuBar() {
|
||||
return ui::OzonePlatform::GetInstance()
|
||||
->GetPlatformProperties()
|
||||
.supports_global_application_menus;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
|
||||
bool IsX11() {
|
||||
return ui::OzonePlatform::GetInstance()
|
||||
->GetPlatformProperties()
|
||||
.electron_can_call_x11;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
class NativeWindowClientView : public views::ClientView {
|
||||
public:
|
||||
NativeWindowClientView(views::Widget* widget,
|
||||
|
@ -257,12 +272,10 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
|||
params.wm_class_name = base::ToLowerASCII(name);
|
||||
params.wm_class_class = name;
|
||||
|
||||
if (base::FeatureList::IsEnabled(features::kWaylandWindowDecorations)) {
|
||||
auto* native_widget = new views::DesktopNativeWidgetAura(widget());
|
||||
params.native_widget = native_widget;
|
||||
params.desktop_window_tree_host =
|
||||
new ElectronDesktopWindowTreeHostLinux(this, native_widget);
|
||||
}
|
||||
auto* native_widget = new views::DesktopNativeWidgetAura(widget());
|
||||
params.native_widget = native_widget;
|
||||
params.desktop_window_tree_host =
|
||||
new ElectronDesktopWindowTreeHostLinux(this, native_widget);
|
||||
#endif
|
||||
|
||||
widget()->Init(std::move(params));
|
||||
|
@ -274,55 +287,52 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
|||
std::string window_type;
|
||||
options.Get(options::kType, &window_type);
|
||||
|
||||
#if defined(USE_X11)
|
||||
// Start monitoring window states.
|
||||
window_state_watcher_ = std::make_unique<WindowStateWatcher>(this);
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
// Set _GTK_THEME_VARIANT to dark if we have "dark-theme" option set.
|
||||
bool use_dark_theme = false;
|
||||
if (options.Get(options::kDarkTheme, &use_dark_theme) && use_dark_theme) {
|
||||
SetGTKDarkThemeEnabled(use_dark_theme);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
if (parent)
|
||||
SetParentWindow(parent);
|
||||
#endif
|
||||
|
||||
#if defined(USE_X11)
|
||||
// TODO(ckerr): remove in Electron v20.0.0
|
||||
// Before the window is mapped the SetWMSpecState can not work, so we have
|
||||
// to manually set the _NET_WM_STATE.
|
||||
std::vector<x11::Atom> state_atom_list;
|
||||
bool skip_taskbar = false;
|
||||
if (options.Get(options::kSkipTaskbar, &skip_taskbar) && skip_taskbar) {
|
||||
state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11()) {
|
||||
// TODO(ckerr): remove in Electron v20.0.0
|
||||
// Before the window is mapped the SetWMSpecState can not work, so we have
|
||||
// to manually set the _NET_WM_STATE.
|
||||
std::vector<x11::Atom> state_atom_list;
|
||||
bool skip_taskbar = false;
|
||||
if (options.Get(options::kSkipTaskbar, &skip_taskbar) && skip_taskbar) {
|
||||
state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
|
||||
}
|
||||
|
||||
// Before the window is mapped, there is no SHOW_FULLSCREEN_STATE.
|
||||
if (fullscreen) {
|
||||
state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_FULLSCREEN"));
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
// Force using dialog type for child window.
|
||||
window_type = "dialog";
|
||||
|
||||
// Modal window needs the _NET_WM_STATE_MODAL hint.
|
||||
if (is_modal())
|
||||
state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_MODAL"));
|
||||
}
|
||||
|
||||
if (!state_atom_list.empty())
|
||||
SetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
x11::GetAtom("_NET_WM_STATE"), x11::Atom::ATOM,
|
||||
state_atom_list);
|
||||
|
||||
// Set the _NET_WM_WINDOW_TYPE.
|
||||
if (!window_type.empty())
|
||||
SetWindowType(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
window_type);
|
||||
}
|
||||
|
||||
// Before the window is mapped, there is no SHOW_FULLSCREEN_STATE.
|
||||
if (fullscreen) {
|
||||
state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_FULLSCREEN"));
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
// Force using dialog type for child window.
|
||||
window_type = "dialog";
|
||||
|
||||
// Modal window needs the _NET_WM_STATE_MODAL hint.
|
||||
if (is_modal())
|
||||
state_atom_list.push_back(x11::GetAtom("_NET_WM_STATE_MODAL"));
|
||||
}
|
||||
|
||||
if (!state_atom_list.empty())
|
||||
SetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
x11::GetAtom("_NET_WM_STATE"), x11::Atom::ATOM,
|
||||
state_atom_list);
|
||||
|
||||
// Set the _NET_WM_WINDOW_TYPE.
|
||||
if (!window_type.empty())
|
||||
SetWindowType(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
window_type);
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
|
@ -419,11 +429,13 @@ NativeWindowViews::~NativeWindowViews() {
|
|||
}
|
||||
|
||||
void NativeWindowViews::SetGTKDarkThemeEnabled(bool use_dark_theme) {
|
||||
#if defined(USE_X11)
|
||||
const std::string color = use_dark_theme ? "dark" : "light";
|
||||
x11::SetStringProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
x11::GetAtom("_GTK_THEME_VARIANT"),
|
||||
x11::GetAtom("UTF8_STRING"), color);
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11()) {
|
||||
const std::string color = use_dark_theme ? "dark" : "light";
|
||||
x11::SetStringProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
x11::GetAtom("_GTK_THEME_VARIANT"),
|
||||
x11::GetAtom("UTF8_STRING"), color);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -478,7 +490,7 @@ void NativeWindowViews::Show() {
|
|||
|
||||
NotifyWindowShow();
|
||||
|
||||
#if defined(USE_X11)
|
||||
#if defined(USE_OZONE)
|
||||
if (global_menu_bar_)
|
||||
global_menu_bar_->OnWindowMapped();
|
||||
#endif
|
||||
|
@ -489,7 +501,7 @@ void NativeWindowViews::ShowInactive() {
|
|||
|
||||
NotifyWindowShow();
|
||||
|
||||
#if defined(USE_X11)
|
||||
#if defined(USE_OZONE)
|
||||
if (global_menu_bar_)
|
||||
global_menu_bar_->OnWindowMapped();
|
||||
#endif
|
||||
|
@ -503,7 +515,7 @@ void NativeWindowViews::Hide() {
|
|||
|
||||
NotifyWindowHide();
|
||||
|
||||
#if defined(USE_X11)
|
||||
#if defined(USE_OZONE)
|
||||
if (global_menu_bar_)
|
||||
global_menu_bar_->OnWindowUnmapped();
|
||||
#endif
|
||||
|
@ -525,8 +537,9 @@ bool NativeWindowViews::IsEnabled() {
|
|||
#if BUILDFLAG(IS_WIN)
|
||||
return ::IsWindowEnabled(GetAcceleratedWidget());
|
||||
#elif BUILDFLAG(IS_LINUX)
|
||||
#if defined(USE_X11)
|
||||
return !event_disabler_.get();
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11())
|
||||
return !event_disabler_.get();
|
||||
#endif
|
||||
NOTIMPLEMENTED();
|
||||
return true;
|
||||
|
@ -565,16 +578,18 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
|
|||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
::EnableWindow(GetAcceleratedWidget(), enable);
|
||||
#elif defined(USE_X11)
|
||||
views::DesktopWindowTreeHostPlatform* tree_host =
|
||||
views::DesktopWindowTreeHostLinux::GetHostForWidget(
|
||||
GetAcceleratedWidget());
|
||||
if (enable) {
|
||||
tree_host->RemoveEventRewriter(event_disabler_.get());
|
||||
event_disabler_.reset();
|
||||
} else {
|
||||
event_disabler_ = std::make_unique<EventDisabler>();
|
||||
tree_host->AddEventRewriter(event_disabler_.get());
|
||||
#elif defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11()) {
|
||||
views::DesktopWindowTreeHostPlatform* tree_host =
|
||||
views::DesktopWindowTreeHostLinux::GetHostForWidget(
|
||||
GetAcceleratedWidget());
|
||||
if (enable) {
|
||||
tree_host->RemoveEventRewriter(event_disabler_.get());
|
||||
event_disabler_.reset();
|
||||
} else {
|
||||
event_disabler_ = std::make_unique<EventDisabler>();
|
||||
tree_host->AddEventRewriter(event_disabler_.get());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -798,12 +813,14 @@ bool NativeWindowViews::MoveAbove(const std::string& sourceId) {
|
|||
::SetWindowPos(GetAcceleratedWidget(), GetWindow(otherWindow, GW_HWNDPREV), 0,
|
||||
0, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
#elif defined(USE_X11)
|
||||
if (!IsWindowValid(static_cast<x11::Window>(id.id)))
|
||||
return false;
|
||||
#elif defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11()) {
|
||||
if (!IsWindowValid(static_cast<x11::Window>(id.id)))
|
||||
return false;
|
||||
|
||||
electron::MoveWindowAbove(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
static_cast<x11::Window>(id.id));
|
||||
electron::MoveWindowAbove(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
static_cast<x11::Window>(id.id));
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -818,9 +835,10 @@ void NativeWindowViews::MoveTop() {
|
|||
::SetWindowPos(GetAcceleratedWidget(), HWND_TOP, pos.x(), pos.y(),
|
||||
size.width(), size.height(),
|
||||
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
|
||||
#elif defined(USE_X11)
|
||||
electron::MoveWindowToForeground(
|
||||
static_cast<x11::Window>(GetAcceleratedWidget()));
|
||||
#elif defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11())
|
||||
electron::MoveWindowToForeground(
|
||||
static_cast<x11::Window>(GetAcceleratedWidget()));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1002,9 +1020,10 @@ void NativeWindowViews::SetSkipTaskbar(bool skip) {
|
|||
taskbar->AddTab(GetAcceleratedWidget());
|
||||
taskbar_host_.RestoreThumbarButtons(GetAcceleratedWidget());
|
||||
}
|
||||
#elif defined(USE_X11)
|
||||
SetWMSpecState(static_cast<x11::Window>(GetAcceleratedWidget()), skip,
|
||||
x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
|
||||
#elif defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11())
|
||||
SetWMSpecState(static_cast<x11::Window>(GetAcceleratedWidget()), skip,
|
||||
x11::GetAtom("_NET_WM_STATE_SKIP_TASKBAR"));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1104,24 +1123,28 @@ void NativeWindowViews::SetIgnoreMouseEvents(bool ignore, bool forward) {
|
|||
} else {
|
||||
SetForwardMouseMessages(forward);
|
||||
}
|
||||
#elif defined(USE_X11)
|
||||
auto* connection = x11::Connection::Get();
|
||||
if (ignore) {
|
||||
x11::Rectangle r{0, 0, 1, 1};
|
||||
connection->shape().Rectangles({
|
||||
.operation = x11::Shape::So::Set,
|
||||
.destination_kind = x11::Shape::Sk::Input,
|
||||
.ordering = x11::ClipOrdering::YXBanded,
|
||||
.destination_window = static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
.rectangles = {r},
|
||||
});
|
||||
} else {
|
||||
connection->shape().Mask({
|
||||
.operation = x11::Shape::So::Set,
|
||||
.destination_kind = x11::Shape::Sk::Input,
|
||||
.destination_window = static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
.source_bitmap = x11::Pixmap::None,
|
||||
});
|
||||
#elif defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11()) {
|
||||
auto* connection = x11::Connection::Get();
|
||||
if (ignore) {
|
||||
x11::Rectangle r{0, 0, 1, 1};
|
||||
connection->shape().Rectangles({
|
||||
.operation = x11::Shape::So::Set,
|
||||
.destination_kind = x11::Shape::Sk::Input,
|
||||
.ordering = x11::ClipOrdering::YXBanded,
|
||||
.destination_window =
|
||||
static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
.rectangles = {r},
|
||||
});
|
||||
} else {
|
||||
connection->shape().Mask({
|
||||
.operation = x11::Shape::So::Set,
|
||||
.destination_kind = x11::Shape::Sk::Input,
|
||||
.destination_window =
|
||||
static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
.source_bitmap = x11::Pixmap::None,
|
||||
});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1168,7 +1191,7 @@ bool NativeWindowViews::IsFocusable() {
|
|||
}
|
||||
|
||||
void NativeWindowViews::SetMenu(ElectronMenuModel* menu_model) {
|
||||
#if defined(USE_X11)
|
||||
#if defined(USE_OZONE)
|
||||
// Remove global menu bar.
|
||||
if (global_menu_bar_ && menu_model == nullptr) {
|
||||
global_menu_bar_.reset();
|
||||
|
@ -1177,7 +1200,7 @@ void NativeWindowViews::SetMenu(ElectronMenuModel* menu_model) {
|
|||
}
|
||||
|
||||
// Use global application menu bar when possible.
|
||||
if (ShouldUseGlobalMenuBar()) {
|
||||
if (CreateGlobalMenuBar() && ShouldUseGlobalMenuBar()) {
|
||||
if (!global_menu_bar_)
|
||||
global_menu_bar_ = std::make_unique<GlobalMenuBarX11>(this);
|
||||
if (global_menu_bar_->IsServerStarted()) {
|
||||
|
@ -1264,12 +1287,13 @@ void NativeWindowViews::SetTopBrowserView(NativeBrowserView* view) {
|
|||
void NativeWindowViews::SetParentWindow(NativeWindow* parent) {
|
||||
NativeWindow::SetParentWindow(parent);
|
||||
|
||||
#if defined(USE_X11)
|
||||
x11::SetProperty(
|
||||
static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
x11::Atom::WM_TRANSIENT_FOR, x11::Atom::WINDOW,
|
||||
parent ? static_cast<x11::Window>(parent->GetAcceleratedWidget())
|
||||
: ui::GetX11RootWindow());
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11())
|
||||
x11::SetProperty(
|
||||
static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
x11::Atom::WM_TRANSIENT_FOR, x11::Atom::WINDOW,
|
||||
parent ? static_cast<x11::Window>(parent->GetAcceleratedWidget())
|
||||
: ui::GetX11RootWindow());
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
// To set parentship between windows into Windows is better to play with the
|
||||
// owner instead of the parent, as Windows natively seems to do if a parent
|
||||
|
@ -1347,18 +1371,19 @@ void NativeWindowViews::SetVisibleOnAllWorkspaces(
|
|||
}
|
||||
|
||||
bool NativeWindowViews::IsVisibleOnAllWorkspaces() {
|
||||
#if defined(USE_X11)
|
||||
// Use the presence/absence of _NET_WM_STATE_STICKY in _NET_WM_STATE to
|
||||
// determine whether the current window is visible on all workspaces.
|
||||
x11::Atom sticky_atom = x11::GetAtom("_NET_WM_STATE_STICKY");
|
||||
std::vector<x11::Atom> wm_states;
|
||||
GetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
x11::GetAtom("_NET_WM_STATE"), &wm_states);
|
||||
return std::find(wm_states.begin(), wm_states.end(), sticky_atom) !=
|
||||
wm_states.end();
|
||||
#else
|
||||
return false;
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
if (IsX11()) {
|
||||
// Use the presence/absence of _NET_WM_STATE_STICKY in _NET_WM_STATE to
|
||||
// determine whether the current window is visible on all workspaces.
|
||||
x11::Atom sticky_atom = x11::GetAtom("_NET_WM_STATE_STICKY");
|
||||
std::vector<x11::Atom> wm_states;
|
||||
GetArrayProperty(static_cast<x11::Window>(GetAcceleratedWidget()),
|
||||
x11::GetAtom("_NET_WM_STATE"), &wm_states);
|
||||
return std::find(wm_states.begin(), wm_states.end(), sticky_atom) !=
|
||||
wm_states.end();
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
content::DesktopMediaID NativeWindowViews::GetDesktopMediaID() const {
|
||||
|
|
|
@ -16,6 +16,13 @@
|
|||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/views/widget/widget_observer.h"
|
||||
|
||||
#if defined(USE_OZONE)
|
||||
#include "ui/ozone/buildflags.h"
|
||||
#if BUILDFLAG(OZONE_PLATFORM_X11)
|
||||
#define USE_OZONE_PLATFORM_X11
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "base/win/scoped_gdi_object.h"
|
||||
#include "shell/browser/ui/win/taskbar_host.h"
|
||||
|
@ -32,7 +39,7 @@ class GlobalMenuBarX11;
|
|||
class RootView;
|
||||
class WindowStateWatcher;
|
||||
|
||||
#if defined(USE_X11)
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
class EventDisabler;
|
||||
#endif
|
||||
|
||||
|
@ -259,12 +266,12 @@ class NativeWindowViews : public NativeWindow,
|
|||
// events from resizing the window.
|
||||
extensions::SizeConstraints old_size_constraints_;
|
||||
|
||||
#if defined(USE_X11)
|
||||
#if defined(USE_OZONE)
|
||||
std::unique_ptr<GlobalMenuBarX11> global_menu_bar_;
|
||||
|
||||
// Handles window state events.
|
||||
std::unique_ptr<WindowStateWatcher> window_state_watcher_;
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
// To disable the mouse events.
|
||||
std::unique_ptr<EventDisabler> event_disabler_;
|
||||
#endif
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "base/feature_list.h"
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "shell/browser/native_window_features.h"
|
||||
#include "shell/browser/ui/views/client_frame_view_linux.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "ui/gfx/geometry/skia_conversions.h"
|
||||
|
@ -20,6 +22,14 @@
|
|||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
|
||||
#include "ui/views/window/non_client_view.h"
|
||||
|
||||
#if defined(USE_OZONE)
|
||||
#include "ui/ozone/buildflags.h"
|
||||
#if BUILDFLAG(OZONE_PLATFORM_X11)
|
||||
#define USE_OZONE_PLATFORM_X11
|
||||
#endif
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
||||
ElectronDesktopWindowTreeHostLinux::ElectronDesktopWindowTreeHostLinux(
|
||||
|
@ -46,6 +56,18 @@ void ElectronDesktopWindowTreeHostLinux::OnBoundsChanged(
|
|||
const BoundsChange& change) {
|
||||
views::DesktopWindowTreeHostLinux::OnBoundsChanged(change);
|
||||
UpdateFrameHints();
|
||||
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
if (ui::OzonePlatform::GetInstance()
|
||||
->GetPlatformProperties()
|
||||
.electron_can_call_x11) {
|
||||
// The OnWindowStateChanged should receive all updates but currently under
|
||||
// X11 it doesn't receive changes to the fullscreen status because chromium
|
||||
// is handling the fullscreen state changes synchronously, see
|
||||
// X11Window::ToggleFullscreen in ui/ozone/platform/x11/x11_window.cc.
|
||||
UpdateWindowState(platform_window()->GetPlatformWindowState());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnWindowStateChanged(
|
||||
|
@ -53,6 +75,43 @@ void ElectronDesktopWindowTreeHostLinux::OnWindowStateChanged(
|
|||
ui::PlatformWindowState new_state) {
|
||||
views::DesktopWindowTreeHostLinux::OnWindowStateChanged(old_state, new_state);
|
||||
UpdateFrameHints();
|
||||
UpdateWindowState(new_state);
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::UpdateWindowState(
|
||||
ui::PlatformWindowState new_state) {
|
||||
if (window_state_ == new_state)
|
||||
return;
|
||||
|
||||
switch (window_state_) {
|
||||
case ui::PlatformWindowState::kMinimized:
|
||||
native_window_view_->NotifyWindowRestore();
|
||||
break;
|
||||
case ui::PlatformWindowState::kMaximized:
|
||||
native_window_view_->NotifyWindowUnmaximize();
|
||||
break;
|
||||
case ui::PlatformWindowState::kFullScreen:
|
||||
native_window_view_->NotifyWindowLeaveFullScreen();
|
||||
break;
|
||||
case ui::PlatformWindowState::kUnknown:
|
||||
case ui::PlatformWindowState::kNormal:
|
||||
break;
|
||||
}
|
||||
switch (new_state) {
|
||||
case ui::PlatformWindowState::kMinimized:
|
||||
native_window_view_->NotifyWindowMinimize();
|
||||
break;
|
||||
case ui::PlatformWindowState::kMaximized:
|
||||
native_window_view_->NotifyWindowMaximize();
|
||||
break;
|
||||
case ui::PlatformWindowState::kFullScreen:
|
||||
native_window_view_->NotifyWindowEnterFullScreen();
|
||||
break;
|
||||
case ui::PlatformWindowState::kUnknown:
|
||||
case ui::PlatformWindowState::kNormal:
|
||||
break;
|
||||
}
|
||||
window_state_ = new_state;
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::OnNativeThemeUpdated(
|
||||
|
@ -65,13 +124,15 @@ void ElectronDesktopWindowTreeHostLinux::OnDeviceScaleFactorChanged() {
|
|||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::UpdateFrameHints() {
|
||||
if (SupportsClientFrameShadow() && native_window_view_->has_frame() &&
|
||||
native_window_view_->has_client_frame()) {
|
||||
UpdateClientDecorationHints(static_cast<ClientFrameViewLinux*>(
|
||||
native_window_view_->widget()->non_client_view()->frame_view()));
|
||||
}
|
||||
if (base::FeatureList::IsEnabled(features::kWaylandWindowDecorations)) {
|
||||
if (SupportsClientFrameShadow() && native_window_view_->has_frame() &&
|
||||
native_window_view_->has_client_frame()) {
|
||||
UpdateClientDecorationHints(static_cast<ClientFrameViewLinux*>(
|
||||
native_window_view_->widget()->non_client_view()->frame_view()));
|
||||
}
|
||||
|
||||
SizeConstraintsChanged();
|
||||
SizeConstraintsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ElectronDesktopWindowTreeHostLinux::UpdateClientDecorationHints(
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "shell/browser/ui/views/client_frame_view_linux.h"
|
||||
#include "third_party/skia/include/core/SkRRect.h"
|
||||
#include "ui/native_theme/native_theme_observer.h"
|
||||
#include "ui/platform_window/platform_window.h"
|
||||
#include "ui/views/linux_ui/device_scale_factor_observer.h"
|
||||
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
|
||||
|
||||
|
@ -55,6 +56,7 @@ class ElectronDesktopWindowTreeHostLinux
|
|||
private:
|
||||
void UpdateFrameHints();
|
||||
void UpdateClientDecorationHints(ClientFrameViewLinux* view);
|
||||
void UpdateWindowState(ui::PlatformWindowState new_state);
|
||||
|
||||
NativeWindowViews* native_window_view_; // weak ref
|
||||
|
||||
|
@ -65,6 +67,7 @@ class ElectronDesktopWindowTreeHostLinux
|
|||
&views::LinuxUI::AddDeviceScaleFactorObserver,
|
||||
&views::LinuxUI::RemoveDeviceScaleFactorObserver>
|
||||
scale_observation_{this};
|
||||
ui::PlatformWindowState window_state_ = ui::PlatformWindowState::kUnknown;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
|
|
@ -18,16 +18,9 @@
|
|||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
#include "ui/base/glib/glib_signal.h"
|
||||
#include "ui/gtk/gtk_ui.h"
|
||||
#include "ui/gtk/gtk_util.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE) || defined(USE_X11)
|
||||
#include "ui/base/ui_base_features.h"
|
||||
#endif
|
||||
|
||||
namespace file_dialog {
|
||||
|
||||
static GModule* gtk_module;
|
||||
|
@ -247,14 +240,7 @@ class FileChooserDialog {
|
|||
dl_gtk_native_dialog_show(static_cast<void*>(dialog_));
|
||||
} else {
|
||||
gtk_widget_show_all(GTK_WIDGET(dialog_));
|
||||
|
||||
#if defined(USE_X11)
|
||||
// We need to call gtk_window_present after making the widgets visible
|
||||
// to make sure window gets correctly raised and gets focus.
|
||||
x11::Time time = ui::X11EventSource::GetInstance()->GetTimestamp();
|
||||
gtk_window_present_with_time(GTK_WINDOW(dialog_),
|
||||
static_cast<uint32_t>(time));
|
||||
#endif
|
||||
gtk::GtkUi::GetPlatform()->ShowGtkWindow(GTK_WINDOW(dialog_));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,12 @@
|
|||
#include "ui/events/event_constants.h"
|
||||
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
|
||||
|
||||
#if defined(USE_OZONE) || defined(USE_X11)
|
||||
#include "ui/base/ui_base_features.h"
|
||||
#if defined(USE_OZONE)
|
||||
#include "ui/ozone/buildflags.h"
|
||||
#if BUILDFLAG(OZONE_PLATFORM_X11)
|
||||
#define USE_OZONE_PLATFORM_X11
|
||||
#endif
|
||||
#include "ui/ozone/public/ozone_platform.h"
|
||||
#endif
|
||||
|
||||
namespace electron {
|
||||
|
@ -45,6 +49,8 @@ int EventFlagsFromGdkState(guint state) {
|
|||
return flags;
|
||||
}
|
||||
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
|
||||
guint GetGdkKeyCodeForAccelerator(const ui::Accelerator& accelerator) {
|
||||
// The second parameter is false because accelerator keys are expressed in
|
||||
// terms of the non-shift-modified key.
|
||||
|
@ -64,6 +70,8 @@ GdkModifierType GetGdkModifierForAccelerator(
|
|||
return static_cast<GdkModifierType>(modifier);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
GtkWidget* BuildMenuItemWithImage(const std::string& label, GtkWidget* image) {
|
||||
|
@ -225,13 +233,17 @@ void BuildSubmenuFromModel(ui::MenuModel* model,
|
|||
connect_to_activate = false;
|
||||
}
|
||||
|
||||
#if defined(USE_X11)
|
||||
ui::Accelerator accelerator;
|
||||
if (model->GetAcceleratorAt(i, &accelerator)) {
|
||||
gtk_widget_add_accelerator(menu_item, "activate", nullptr,
|
||||
GetGdkKeyCodeForAccelerator(accelerator),
|
||||
GetGdkModifierForAccelerator(accelerator),
|
||||
GTK_ACCEL_VISIBLE);
|
||||
#if defined(USE_OZONE_PLATFORM_X11)
|
||||
if (ui::OzonePlatform::GetInstance()
|
||||
->GetPlatformProperties()
|
||||
.electron_can_call_x11) {
|
||||
ui::Accelerator accelerator;
|
||||
if (model->GetAcceleratorAt(i, &accelerator)) {
|
||||
gtk_widget_add_accelerator(menu_item, "activate", nullptr,
|
||||
GetGdkKeyCodeForAccelerator(accelerator),
|
||||
GetGdkModifierForAccelerator(accelerator),
|
||||
GTK_ACCEL_VISIBLE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,13 +18,10 @@
|
|||
#include "shell/browser/unresponsive_suppressor.h"
|
||||
#include "ui/base/glib/glib_signal.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/gtk/gtk_ui.h"
|
||||
#include "ui/gtk/gtk_util.h"
|
||||
|
||||
#if defined(USE_X11)
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE) || defined(USE_X11)
|
||||
#if defined(USE_OZONE)
|
||||
#include "ui/base/ui_base_features.h"
|
||||
#endif
|
||||
|
||||
|
@ -161,14 +158,7 @@ class GtkMessageBox : public NativeWindowObserver {
|
|||
|
||||
void Show() {
|
||||
gtk_widget_show(dialog_);
|
||||
|
||||
#if defined(USE_X11)
|
||||
// We need to call gtk_window_present after making the widgets visible to
|
||||
// make sure window gets correctly raised and gets focus.
|
||||
x11::Time time = ui::X11EventSource::GetInstance()->GetTimestamp();
|
||||
gtk_window_present_with_time(GTK_WINDOW(dialog_),
|
||||
static_cast<uint32_t>(time));
|
||||
#endif
|
||||
gtk::GtkUi::GetPlatform()->ShowGtkWindow(GTK_WINDOW(dialog_));
|
||||
}
|
||||
|
||||
int RunSynchronous() {
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "shell/browser/ui/x/window_state_watcher.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "ui/base/x/x11_util.h"
|
||||
#include "ui/gfx/x/x11_atom_cache.h"
|
||||
#include "ui/gfx/x/xproto_util.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
WindowStateWatcher::WindowStateWatcher(NativeWindowViews* window)
|
||||
: window_(window),
|
||||
widget_(window->GetAcceleratedWidget()),
|
||||
net_wm_state_atom_(x11::GetAtom("_NET_WM_STATE")),
|
||||
net_wm_state_hidden_atom_(x11::GetAtom("_NET_WM_STATE_HIDDEN")),
|
||||
net_wm_state_maximized_vert_atom_(
|
||||
x11::GetAtom("_NET_WM_STATE_MAXIMIZED_VERT")),
|
||||
net_wm_state_maximized_horz_atom_(
|
||||
x11::GetAtom("_NET_WM_STATE_MAXIMIZED_HORZ")),
|
||||
net_wm_state_fullscreen_atom_(x11::GetAtom("_NET_WM_STATE_FULLSCREEN")),
|
||||
was_minimized_(window_->IsMinimized()),
|
||||
was_maximized_(window_->IsMaximized()) {
|
||||
ui::X11EventSource::GetInstance()->connection()->AddEventObserver(this);
|
||||
}
|
||||
|
||||
WindowStateWatcher::~WindowStateWatcher() {
|
||||
ui::X11EventSource::GetInstance()->connection()->RemoveEventObserver(this);
|
||||
}
|
||||
|
||||
void WindowStateWatcher::OnEvent(const x11::Event& x11_event) {
|
||||
if (IsWindowStateEvent(x11_event)) {
|
||||
std::vector<x11::Atom> wm_states;
|
||||
if (GetArrayProperty(
|
||||
static_cast<x11::Window>(window_->GetAcceleratedWidget()),
|
||||
net_wm_state_atom_, &wm_states)) {
|
||||
const auto props =
|
||||
base::flat_set<x11::Atom>(std::begin(wm_states), std::end(wm_states));
|
||||
const bool is_minimized = props.contains(net_wm_state_hidden_atom_);
|
||||
const bool is_maximized =
|
||||
props.contains(net_wm_state_maximized_vert_atom_) &&
|
||||
props.contains(net_wm_state_maximized_horz_atom_);
|
||||
const bool is_fullscreen = props.contains(net_wm_state_fullscreen_atom_);
|
||||
|
||||
if (is_minimized != was_minimized_) {
|
||||
if (is_minimized)
|
||||
window_->NotifyWindowMinimize();
|
||||
else
|
||||
window_->NotifyWindowRestore();
|
||||
} else if (is_maximized != was_maximized_) {
|
||||
if (is_maximized)
|
||||
window_->NotifyWindowMaximize();
|
||||
else
|
||||
window_->NotifyWindowUnmaximize();
|
||||
} else {
|
||||
// If this is neither a "maximize" or "minimize" event, then we think it
|
||||
// is a "fullscreen" event.
|
||||
// The "IsFullscreen()" becomes true immediately before "OnEvent"
|
||||
// is called, so we can not handle this like "maximize" and "minimize"
|
||||
// by watching whether they have changed.
|
||||
if (is_fullscreen)
|
||||
window_->NotifyWindowEnterFullScreen();
|
||||
else
|
||||
window_->NotifyWindowLeaveFullScreen();
|
||||
}
|
||||
|
||||
was_minimized_ = is_minimized;
|
||||
was_maximized_ = is_maximized;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WindowStateWatcher::IsWindowStateEvent(const x11::Event& x11_event) const {
|
||||
auto* property = x11_event.As<x11::PropertyNotifyEvent>();
|
||||
return (property && property->atom == net_wm_state_atom_ &&
|
||||
static_cast<uint32_t>(property->window) == widget_);
|
||||
}
|
||||
|
||||
} // namespace electron
|
|
@ -1,45 +0,0 @@
|
|||
// Copyright (c) 2014 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ELECTRON_SHELL_BROWSER_UI_X_WINDOW_STATE_WATCHER_H_
|
||||
#define ELECTRON_SHELL_BROWSER_UI_X_WINDOW_STATE_WATCHER_H_
|
||||
|
||||
#include "ui/events/platform/x11/x11_event_source.h"
|
||||
#include "ui/gfx/x/event.h"
|
||||
|
||||
#include "shell/browser/native_window_views.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class WindowStateWatcher : public x11::EventObserver {
|
||||
public:
|
||||
explicit WindowStateWatcher(NativeWindowViews* window);
|
||||
~WindowStateWatcher() override;
|
||||
|
||||
// disable copy
|
||||
WindowStateWatcher(const WindowStateWatcher&) = delete;
|
||||
WindowStateWatcher& operator=(const WindowStateWatcher&) = delete;
|
||||
|
||||
protected:
|
||||
// x11::EventObserver:
|
||||
void OnEvent(const x11::Event& x11_event) override;
|
||||
|
||||
private:
|
||||
bool IsWindowStateEvent(const x11::Event& x11_event) const;
|
||||
|
||||
NativeWindowViews* window_;
|
||||
gfx::AcceleratedWidget widget_;
|
||||
const x11::Atom net_wm_state_atom_;
|
||||
const x11::Atom net_wm_state_hidden_atom_;
|
||||
const x11::Atom net_wm_state_maximized_vert_atom_;
|
||||
const x11::Atom net_wm_state_maximized_horz_atom_;
|
||||
const x11::Atom net_wm_state_fullscreen_atom_;
|
||||
|
||||
bool was_minimized_ = false;
|
||||
bool was_maximized_ = false;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_UI_X_WINDOW_STATE_WATCHER_H_
|
Загрузка…
Ссылка в новой задаче