hyprwm / Hyprland

Hyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
https://hyprland.org
BSD 3-Clause "New" or "Revised" License
18.58k stars 772 forks source link

`IHyprLayout::recalculateWindow()` is called too frequently #6009

Open HardGraphite opened 2 months ago

HardGraphite commented 2 months ago

Hyprland Version

System/Version info ```sh Hyprland, built from branch at commit cba1ade848feac44b2eda677503900639581c3f4 (props: bump version to 0.40.0). Date: Sat May 4 15:42:32 2024 Tag: v0.40.0, commits: 4606 flags: (if any) System Information: System name: Linux Node name: Chartreux Release: 6.8.9-arch1-1 Version: #1 SMP PREEMPT_DYNAMIC Thu, 02 May 2024 17:49:46 +0000 GPU information: 00:02.0 VGA compatible controller [0300]: Intel Corporation HD Graphics 620 [8086:5916] (rev 02) (prog-if 00 [VGA controller]) os-release: NAME="Arch Linux" PRETTY_NAME="Arch Linux" ID=arch BUILD_ID=rolling ANSI_COLOR="38;2;23;147;209" HOME_URL="https://archlinux.org/" DOCUMENTATION_URL="https://wiki.archlinux.org/" SUPPORT_URL="https://bbs.archlinux.org/" BUG_REPORT_URL="https://gitlab.archlinux.org/groups/archlinux/-/issues" PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/" LOGO=archlinux-logo plugins: HyPaper by HardGraphite ver 0.1 ```

Bug or Regression?

Bug

Description

Strictly speaking, this is not a BUG, but can be improved if possible.

I'm developing a layout plugin and I recently noticed that IHyprLayout::recalculateWindow() is called frequently. For example, according to my testing, when opening a window in an empty workspace, this function will be called about 138 times. The followings are the stack backtraces of the first few calls, where function hypaper::Layout::recalculateWindow() comes from my plugin:

#0  hypaper::Layout::recalculateWindow
    (this=0x5555563ab240, win=std::shared_ptr<CWindow> (use count 4, weak count 23) = {...})
    at src/layout.cc:117
#1  0x000055555584abe7 in CDecorationPositioner::onWindowUpdate(std::shared_ptr<CWindow>) ()
#2  0x000055555570b387 in CWindow::updateWindowDecos() ()
#3  0x000055555572bc85 in Events::listener_mapWindow(void*, void*) ()
#4  0x0000555555746f07 in handleWrapped(wl_listener*, void*) ()
...
#0  hypaper::Layout::recalculateWindow
    (this=0x5555563ab240, win=std::shared_ptr<CWindow> (use count 4, weak count 23) = {...})
    at src/layout.cc:117
#1  0x000055555572bcc9 in Events::listener_mapWindow(void*, void*) ()
#2  0x0000555555746f07 in handleWrapped(wl_listener*, void*) ()
...
#0  hypaper::Layout::recalculateWindow
    (this=0x5555563ab240, win=std::shared_ptr<CWindow> (use count 6, weak count 23) = {...})
    at src/layout.cc:117
#1  0x000055555584abe7 in CDecorationPositioner::onWindowUpdate(std::shared_ptr<CWindow>) ()
#2  0x000055555570b387 in CWindow::updateWindowDecos() ()
#3  0x0000555555669248 in CCompositor::updateWindowAnimatedDecorationValues(std::shared_ptr<CWindow>)
    ()
#4  0x000055555572be8e in Events::listener_mapWindow(void*, void*) ()
#5  0x0000555555746f07 in handleWrapped(wl_listener*, void*) ()
...
#0  hypaper::Layout::recalculateWindow
    (this=0x5555563ab240, win=std::shared_ptr<CWindow> (use count 8, weak count 24) = {...})
    at src/layout.cc:117
#1  0x000055555584abe7 in CDecorationPositioner::onWindowUpdate(std::shared_ptr<CWindow>) ()
#2  0x000055555584b3a0 in CDecorationPositioner::repositionDeco(IHyprWindowDecoration*) ()
#3  0x0000555555846ac0 in CHyprDropShadowDecoration::draw(CMonitor*, float) ()
#4  0x00005555558337f5 in CHyprRenderer::renderWindow(std::shared_ptr<CWindow>, CMonitor*, timespec*, bool, eRenderPassMode, bool, bool) ()
#5  0x0000555555835090 in CHyprRenderer::renderWorkspaceWindows(CMonitor*, std::shared_ptr<CWorkspace>, timespec*) ()
#6  0x000055555583a4cb in CHyprRenderer::renderAllClientsForWorkspace(CMonitor*, std::shared_ptr<CWorkspace>, timespec*, Vector2D const&, float const&) ()
#7  0x000055555583b2db in CHyprRenderer::renderWorkspace(CMonitor*, std::shared_ptr<CWorkspace>, timespec*, CBox const&) ()
#8  0x000055555583c8ae in CHyprRenderer::renderMonitor(CMonitor*) ()
#9  0x0000555555746f07 in handleWrapped(wl_listener*, void*) ()
...
#0  0x00007ffff0a4d276 in hypaper::Layout::recalculateWindow
    (this=0x5555563ab240, win=std::shared_ptr<CWindow> (use count 8, weak count 24) = {...})
    at src/layout.cc:117
#1  0x000055555584abe7 in CDecorationPositioner::onWindowUpdate(std::shared_ptr<CWindow>) ()
#2  0x000055555584b3a0 in CDecorationPositioner::repositionDeco(IHyprWindowDecoration*) ()
#3  0x0000555555846ac0 in CHyprDropShadowDecoration::draw(CMonitor*, float) ()
#4  0x00005555558337f5 in CHyprRenderer::renderWindow(std::shared_ptr<CWindow>, CMonitor*, timespec*, bool, eRenderPassMode, bool, bool) ()
#5  0x0000555555835090 in CHyprRenderer::renderWorkspaceWindows(CMonitor*, std::shared_ptr<CWorkspace>, timespec*) ()
#6  0x000055555583a4cb in CHyprRenderer::renderAllClientsForWorkspace(CMonitor*, std::shared_ptr<CWorkspace>, timespec*, Vector2D const&, float const&) ()
#7  0x000055555583b2db in CHyprRenderer::renderWorkspace(CMonitor*, std::shared_ptr<CWorkspace>, timespec*, CBox const&) ()
#8  0x000055555583c8ae in CHyprRenderer::renderMonitor(CMonitor*) ()
#9  0x0000555555746f07 in handleWrapped(wl_listener*, void*) ()
...

...

According to the comment, recalculateWindow() is called when the compositor requests a window to be recalculated, e.g. when pseudo is toggled. I think the window state is expected to be unchanged during operations like window-creation, so it is a waste of time to call recalculateWindow() again and again, although this may not be intentionally designed.

How to reproduce

Create/delete/move a window.

Crash reports, logs, images, videos

No response

zakk4223 commented 2 months ago

Possibly fixed in 96365309de49b5641e61b0028199382dcc25f8b2

I would try using a hyprland with that commit and see if it stops