Skip to content

[Linux] windowManager.show() triggers immediate onWindowMinimize event after user minimizes the window #580

@eximius313

Description

@eximius313

Description:
I am implementing a system tray application behavior where minimizing the window hides it to the tray.
This logic works perfectly on Windows, but on Linux, I am encountering an issue where the window fails to show up after a specific sequence of events.

It seems that calling windowManager.show() on a previously minimized-and-hidden window causes the onWindowMinimize event to fire immediately. Since my onWindowMinimize logic hides the window, the window effectively never appears (and the taskbar icon is missing).

Platform:

  • Linux Ubuntu 20.0, 22.0, 24,0
  • Flutter version: 3.38.2
  • window_manager version: 0.5.1

Code to Reproduce:
Here is the logic I use to handle visibility and events:

  // Listener
  @override
  void onWindowMinimize() async {
      print('MINIMIZE!');
      // When user minimizes, we actually want to hide the window completely
      await hideWindow();
  }

  Future<void> hideWindow() async {
    await windowManager.hide();
  }

  Future<void> showWindow() async {
    print('0');
    await windowManager.setAlwaysOnTop(true);
    print('1');
    
    // THE PROBLEM: On Linux, this line immediately triggers 'onWindowMinimize'
    // if the window was previously minimized by the user.
    await windowManager.show(); 
    
    print('2');
    await windowManager.setAlwaysOnTop(false);
    print('3');
    await windowManager.focus();
    print('4');
  }

Steps to Reproduce:

  1. Start the application.
  2. Call hideWindow() programmatically.
  3. Call showWindow() (e.g., user clicks system tray icon). -> Works.
  4. User clicks the Minimize button on the window title bar.
    • onWindowMinimize is called.
    • hideWindow() is executed.
  5. Call showWindow() again (e.g., user clicks system tray icon).

Current Behavior (Linux):
The window does not appear. The logs show that windowManager.show() triggers a minimize event immediately, which causes my code to hide the window again.

Logs (Failure):

-> hiding window (Step 2)
Window Event: hide
Window Event: blur
-> user selects "show window" from tray (Step 3)
0
1
Window Event: resize
Window Event: show
2
3
4
Window Event: focus
Window Event: resize
Window Event: resize
-> User minimizes window (Step 4)
Window Event: minimize
MINIMIZE! <-- Listener triggers hideWindow()
Window Event: blur
Window Event: hide
Window Event: move
Window Event: restore
-> user selects "show window" from tray (Step 5)
0
1
Window Event: resize
Window Event: show
2
Window Event: minimize  <-- UNEXPECTED IMMEDIATE EVENT
MINIMIZE! <-- Listener triggers hideWindow()
3
Window Event: hide
Window Event: resize
Window Event: show
4
Window Event: move
Window Event: restore
Window Event: minimize
MINIMIZE!
Window Event: hide
Window Event: restore

-> Window does not show up, and even taskbar icon is missing

Expected Behavior:
The window should simply appear and focus, without triggering a minimize event, similar to how it behaves on Windows.

Workaround:
I found that checking for Linux and explicitly calling restore() before show() fixes the issue.

  Future<void> showWindow() async {
    print('0');
    await windowManager.setAlwaysOnTop(true);
    print('1');
    
    // FIX / WORKAROUND
    if (Platform.isLinux) {
      await windowManager.restore(); 
    }
    
    print('1a');
    await windowManager.show(); 
    print('2');
    await windowManager.setAlwaysOnTop(false);
    print('3');
    await windowManager.focus();
    print('4');
  }

and log shows as expected:

-> hiding window (Step 2)
Window Event: hide
Window Event: blur
-> user selects "show window" from tray (Step 3)
0
1
Window Event: resize
Window Event: show
1a
2
3
4
Window Event: move
Window Event: focus
Window Event: resize
-> User minimizes window (Step 4)
Window Event: minimize
MINIMIZE!
Window Event: blur
Window Event: hide
Window Event: move
Window Event: restore
-> user selects "show window" from tray (Step 5)
0
1
Window Event: resize
Window Event: show
1a
2
3
4
Window Event: move
Window Event: resize
-> window shows up

Is this intended behavior on Linux, or should show() automatically handle the restore state?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions