Skip to content

External close of monitor selector breaks screenshot service until restart #4838

Description

@renathossain

Flameshot Version

Flameshot v14.0.0

Installation Type

Linux, MacOS, or Windows Package manager (apt, pacman, eopkg, choco, brew, ...)

Operating System type and version

Arch Linux x86_64

Description

Summary

Closing the monitor selector window via a window manager keybind (e.g., i3's "kill focused window") causes flameshot to hang permanently, making screenshot functionality unusable until flameshot is restarted. The window manager sends a WM_DELETE_WINDOW/QClose event that hides the widget without unblocking the internal event loop.

Root cause

  • In src/utils/screengrabber.cpp, in the selectMonitorAndCrop function, the message "Screenshot already in progress, ..." is triggered if the bool m_monitorSelectionActive is set to true already.
  • This can only happen if the selectMonitorAndCrop function was already run before and reached line 215: m_monitorSelectionActive = true; without reaching line 227: m_monitorSelectionActive = false;.
  • Line 227 is never reached because the program gets stuck on the blocking line 223: loop.exec();.

Why does it get stuck on loop.exec();:

  • The blocking line 223 is only unblocked when m_monitorSelectionLoop->quit() is called. This can only happen in the createMonitorPreviews function on line 448 (the user selects a monitor) or in the eventFilter function on line 477 (the user cancels the screenshot request).
  • When the user closes the monitor selector window using WM_DELETE_WINDOW (e.g. using i3 "kill focused window"), a QClose event is delivered to the QObject, causing the object to permanently hide, but the "User cancelled selection" code is never run to unblock the loop, causing it to remain permanently stuck on the blocking line 223: loop.exec();.

Solution

  • In src/utils/screengrabber.cpp, update the eventFilter function to run the same "User cancelled selection" code on QEvent::Close as well.

Steps to reproduce

Reproduction

  • Run flameshot in the terminal for the tray icon to appear.
  • Click on the flameshot tray icon to take a screenshot.
  • A monitor selector window will appear. Use the i3 "kill focused window" keybind (typically bindsym $mod+Shift+q kill) to close the monitor selector window. Do not use the Esc key to close the window.
  • Once the monitor selector window is closed, press the flameshot tray icon to take a screenshot again.
  • The monitor selector window will fail to launch, with the following message printed in the terminal where the flameshot process is running:
flameshot: error: Screenshot already in progress, please wait for the current screenshot to complete
  • The issue does not occur if the Esc key is used to close the window, because upon using Esc, it is properly handled, printing the following message and ready to take a screenshot again:
flameshot: info: Screenshot cancelled

Screenshots or screen recordings

No response

System Information

Setup

Flameshot: v14.0.0
OS: Arch Linux x86_64
Kernel: Linux 7.1.4-arch1-1
WM: i3 4.25.1 (X11)
CPU: Intel(R) Core(TM) i5-9300H (8) @ 4.10 GHz
GPU 1: NVIDIA GeForce GTX 1650 Mobile / Max-Q [Discrete]
GPU 2: Intel UHD Graphics 630 @ 1.05 GHz [Integrated]
Display: [Built-in] + [External]

Note: 2 monitors are required to reproduce this issue to trigger the monitor selector window.

Flameshot config

[General]
useX11LegacyScreenshot=true
showDesktopNotification=false
showStartupLaunchMessage=false

Relevant i3 Config

for_window [class="flameshot"] floating enable, border pixel 0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Unconfirmed BugThe bug is not confirmed by anyone else.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions