Fix high CPU usage on tiling WMs when moving windows across monitors (#737)

This commit restricts an Xfwm4-specific DPI-preserving hack to Xfwm4
only. The hack saves and restores the DPI-adjusted size until the actual
size matches. On tiling WMs like i3 this fails, since the size is
constrained by the layout. This in turn causes a never-ending
XResizeWindow vs. XConfigureWindow fight between the WM and the client,
making the WM, winit client, and Xorg consume all CPU cycles available.
This commit is contained in:
Jasper Mattsson 2018-12-19 05:20:31 +02:00 committed by Francesca Plebani
parent fd349f1822
commit 4b4c73cee4
2 changed files with 5 additions and 2 deletions

View file

@ -1,5 +1,6 @@
# Unreleased
- On X11 with a tiling WM, fixed high CPU usage when moving windows across monitors.
- On X11, fixed panic caused by dropping the window before running the event loop.
- Introduce `WindowBuilderExt::with_app_id` to allow setting the application ID on Wayland.
- On Windows, catch panics in event loop child thread and forward them to the parent thread. This prevents an invocation of undefined behavior due to unwinding into foreign code.

View file

@ -499,10 +499,12 @@ impl EventsLoop {
}
// This is a hack to ensure that the DPI adjusted resize is actually applied on all WMs. KWin
// doesn't need this, but Xfwm does.
// doesn't need this, but Xfwm does. The hack should not be run on other WMs, since tiling
// WMs constrain the window size, making the resize fail. This would cause an endless stream of
// XResizeWindow requests, making Xorg, the winit client, and the WM consume 100% of CPU.
if let Some(adjusted_size) = shared_state_lock.dpi_adjusted {
let rounded_size = (adjusted_size.0.round() as u32, adjusted_size.1.round() as u32);
if new_inner_size == rounded_size {
if new_inner_size == rounded_size || !util::wm_name_is_one_of(&["Xfwm4"]) {
// When this finally happens, the event will not be synthetic.
shared_state_lock.dpi_adjusted = None;
} else {