in libcef/browser/native/window_x11.cc [334:424]
void CefWindowX11::ProcessXEvent(const x11::Event& event) {
if (auto* configure = event.As<x11::ConfigureNotifyEvent>()) {
DCHECK_EQ(xwindow_, configure->event);
DCHECK_EQ(xwindow_, configure->window);
// It's possible that the X window may be resized by some other means
// than from within Aura (e.g. the X window manager can change the
// size). Make sure the root window size is maintained properly.
bounds_ = gfx::Rect(configure->x, configure->y, configure->width,
configure->height);
if (browser_.get()) {
auto child = FindChild(xwindow_);
if (child != x11::Window::None) {
// Resize the child DesktopWindowTreeHostLinux to match this window.
x11::ConfigureWindowRequest req{
.window = child,
.width = bounds_.width(),
.height = bounds_.height(),
};
connection_->ConfigureWindow(req);
browser_->NotifyMoveOrResizeStarted();
}
}
} else if (auto* client = event.As<x11::ClientMessageEvent>()) {
if (client->type == x11::GetAtom(kWMProtocols)) {
x11::Atom protocol = static_cast<x11::Atom>(client->data.data32[0]);
if (protocol == x11::GetAtom(kWMDeleteWindow)) {
// We have received a close message from the window manager.
if (!browser_ || browser_->TryCloseBrowser()) {
// Allow the close.
connection_->DestroyWindow({xwindow_});
xwindow_ = x11::Window::None;
if (browser_) {
// Force the browser to be destroyed and release the reference
// added in PlatformCreateWindow().
static_cast<AlloyBrowserHostImpl*>(browser_.get())
->WindowDestroyed();
}
delete this;
}
} else if (protocol == x11::GetAtom(kNetWMPing)) {
x11::ClientMessageEvent reply_event = *client;
reply_event.window = parent_xwindow_;
x11::SendEvent(reply_event, reply_event.window,
x11::EventMask::SubstructureNotify |
x11::EventMask::SubstructureRedirect);
}
}
} else if (auto* focus = event.As<x11::FocusEvent>()) {
if (focus->opcode == x11::FocusEvent::In) {
// This message is received first followed by a "_NET_ACTIVE_WINDOW"
// message sent to the root window. When X11DesktopHandler handles the
// "_NET_ACTIVE_WINDOW" message it will erroneously mark the WebView
// (hosted in a DesktopWindowTreeHostLinux) as unfocused. Use a delayed
// task here to restore the WebView's focus state.
if (!focus_pending_) {
focus_pending_ = true;
CEF_POST_DELAYED_TASK(CEF_UIT,
base::BindOnce(&CefWindowX11::ContinueFocus,
weak_ptr_factory_.GetWeakPtr()),
100);
}
} else {
// Cancel the pending focus change if some other window has gained focus
// while waiting for the async task to run. Otherwise we can get stuck in
// a focus change loop.
if (focus_pending_)
focus_pending_ = false;
}
} else if (auto* property = event.As<x11::PropertyNotifyEvent>()) {
const auto& wm_state_atom = x11::GetAtom(kNetWMState);
if (property->atom == wm_state_atom) {
// State change event like minimize/maximize.
if (browser_.get()) {
auto child = FindChild(xwindow_);
if (child != x11::Window::None) {
// Forward the state change to the child DesktopWindowTreeHostLinux
// window so that resource usage will be reduced while the window is
// minimized. |atom_list| may be empty.
std::vector<x11::Atom> atom_list;
x11::GetArrayProperty(xwindow_, wm_state_atom, &atom_list);
x11::SetArrayProperty(child, wm_state_atom, x11::Atom::ATOM,
atom_list);
}
}
}
}
}