mirror of
https://github.com/electron/electron.git
synced 2026-10-28 11:44:46 +08:00
fix: honor win.setEnabled(false) and modal parents under Wayland (#54427)
On Linux, disabling a window (setEnabled(false), or opening a modal child) only took effect under X11; under Wayland the window kept receiving input and isEnabled() always returned true. Replace the X11-only EventDisabler rewriter with the window tree host's DisableEventListening(), which blocks event dispatch the same way on both X11 and Wayland, and run the disabling specs on Wayland too.
This commit is contained in:
1 parent
783bf56ab7
commit
ff6681b1ff
6 files changed
+11
-88
No files matched your search
@@ -63,8 +63,6 @@ filenames = {
|
||||
"shell/browser/ui/views/global_menu_bar_registrar_x11.h",
|
||||
"shell/browser/ui/views/global_menu_bar_x11.cc",
|
||||
"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/x_window_utils.cc",
|
||||
"shell/browser/ui/x/x_window_utils.h",
|
||||
]
|
||||
|
||||
@@ -76,7 +76,6 @@
|
||||
|
||||
#if BUILDFLAG(SUPPORTS_OZONE_X11)
|
||||
#include "shell/browser/ui/views/global_menu_bar_x11.h"
|
||||
#include "shell/browser/ui/x/event_disabler.h"
|
||||
#include "shell/browser/ui/x/x_window_utils.h"
|
||||
#include "ui/gfx/x/atom_cache.h"
|
||||
#include "ui/gfx/x/connection.h"
|
||||
@@ -691,10 +690,7 @@ bool NativeWindowViews::IsEnabled() const {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
return ::IsWindowEnabled(GetAcceleratedWidget());
|
||||
#elif BUILDFLAG(IS_LINUX)
|
||||
if (x11_util::IsX11())
|
||||
return !event_disabler_.get();
|
||||
NOTIMPLEMENTED();
|
||||
return true;
|
||||
return !enable_event_listening_;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -728,17 +724,12 @@ void NativeWindowViews::SetEnabledInternal(bool enable) {
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
::EnableWindow(GetAcceleratedWidget(), enable);
|
||||
#else
|
||||
if (x11_util::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());
|
||||
}
|
||||
if (enable) {
|
||||
enable_event_listening_.RunAndReset();
|
||||
} else {
|
||||
auto* tree_host = static_cast<views::DesktopWindowTreeHostLinux*>(
|
||||
GetNativeWindow()->GetHost());
|
||||
enable_event_listening_.ReplaceClosure(tree_host->DisableEventListening());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "base/functional/callback_helpers.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/no_destructor.h"
|
||||
#include "shell/browser/ui/views/root_view.h"
|
||||
@@ -43,10 +44,6 @@ namespace electron {
|
||||
class GlobalMenuBarX11;
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(SUPPORTS_OZONE_X11)
|
||||
class EventDisabler;
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
gfx::Rect ScreenToDIPRect(HWND hwnd, const gfx::Rect& pixel_bounds);
|
||||
#endif
|
||||
@@ -297,11 +294,9 @@ class NativeWindowViews : public NativeWindow,
|
||||
|
||||
#if BUILDFLAG(IS_LINUX)
|
||||
std::unique_ptr<GlobalMenuBarX11> global_menu_bar_;
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(SUPPORTS_OZONE_X11)
|
||||
// To disable the mouse events.
|
||||
std::unique_ptr<EventDisabler> event_disabler_;
|
||||
// Set while the window is disabled; running it re-enables event dispatch.
|
||||
base::ScopedClosureRunner enable_event_listening_;
|
||||
#endif
|
||||
|
||||
// The color to use as the theme and symbol colors respectively for WCO.
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) 2016 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/event_disabler.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace electron {
|
||||
|
||||
EventDisabler::EventDisabler() = default;
|
||||
|
||||
EventDisabler::~EventDisabler() = default;
|
||||
|
||||
ui::EventRewriteStatus EventDisabler::RewriteEvent(
|
||||
const ui::Event& event,
|
||||
std::unique_ptr<ui::Event>* rewritten_event) {
|
||||
return ui::EVENT_REWRITE_DISCARD;
|
||||
}
|
||||
|
||||
ui::EventRewriteStatus EventDisabler::NextDispatchEvent(
|
||||
const ui::Event& last_event,
|
||||
std::unique_ptr<ui::Event>* new_event) {
|
||||
return ui::EVENT_REWRITE_CONTINUE;
|
||||
}
|
||||
|
||||
} // namespace electron
|
||||
@@ -1,34 +0,0 @@
|
||||
// Copyright (c) 2016 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_EVENT_DISABLER_H_
|
||||
#define ELECTRON_SHELL_BROWSER_UI_X_EVENT_DISABLER_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ui/events/event_rewriter.h"
|
||||
|
||||
namespace electron {
|
||||
|
||||
class EventDisabler : public ui::EventRewriter {
|
||||
public:
|
||||
EventDisabler();
|
||||
~EventDisabler() override;
|
||||
|
||||
// disable copy
|
||||
EventDisabler(const EventDisabler&) = delete;
|
||||
EventDisabler& operator=(const EventDisabler&) = delete;
|
||||
|
||||
// ui::EventRewriter:
|
||||
ui::EventRewriteStatus RewriteEvent(
|
||||
const ui::Event& event,
|
||||
std::unique_ptr<ui::Event>* rewritten_event) override;
|
||||
ui::EventRewriteStatus NextDispatchEvent(
|
||||
const ui::Event& last_event,
|
||||
std::unique_ptr<ui::Event>* new_event) override;
|
||||
};
|
||||
|
||||
} // namespace electron
|
||||
|
||||
#endif // ELECTRON_SHELL_BROWSER_UI_X_EVENT_DISABLER_H_
|
||||
@@ -6509,7 +6509,7 @@ describe('BrowserWindow module', () => {
|
||||
}
|
||||
});
|
||||
|
||||
ifdescribe(process.platform !== 'darwin' && !isWayland)('disabling parent windows', () => {
|
||||
ifdescribe(process.platform !== 'darwin')('disabling parent windows', () => {
|
||||
it('can disable and enable a window', () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.setEnabled(false);
|
||||
|
||||
Reference in new issue
Block a user