rust-windowing / rust-windowing/winit

Support for activating already running app

Open
#3,964 2 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

DS - win32 S - enhancement
Dominant language
Rust
Stars
6.2k
Forks
1.3k
Avg merge
2d 19h
Merged PRs (30d)
9

Description

Description

To ensure only a single instance of your app can run, you can make use of a crate like single-instance. But an end user expects that, when trying to open the app by running its executable, the app is unconditionally brought into the foreground, no matter whether its relevant window is in the background, arranged, minimized, or hidden, because the app works with a tray icon.

I don't know whether Windows support for such functionality would fit into winit's existing ActivationToken API. In any case, an easy way to implement this functionality on Windows on a low level, is to retrieve a window message via RegisterWindowMessageW() in every app instance using the same app-specific string, and, if the app instance is a follow-up instance, use PostMessageW(HWND_BROADCAST, ...) to request the original app instance to activate its relevant window.

Note: You will know that Windows' SetForegroundWindow() is subject to certain restrictions. In my winit-using Slint app, though, I didn't have any trouble with activating the original app instance's window. The file manager will be the foreground process. Then this from the Microsoft docs will apply: "A process can set the foreground window...only if: ...The calling process was started by the foreground process..." Then, from my anecdotal evidence, Windows seems to allow this follow-up process of my app to transfer the right to successfully call SetForegroundWindow() to my original app instance (maybe because its the same executable path). (Alternatively, there would also be AllowSetForegroundWindow(), which requires retrieving the original app instance's process ID, though.)

However, as far as I can see, winit currently doesn't even support bringing a window into the foreground unconditionally. Window::focus_window() doesn't work for minimized and invisible windows, e.g., and Window::set_visible() probably also doesn't unminimize. Even though at least Windows 10 has a bug regarding arranged windows, there's a way to unconditionally bring a window into the foreground in its correct state: See this code (in another case, I only had success when calling SetForegroundWindow() before ShowWindowAsync(), in a branch where IsWindowVisible() returned true).

I think the functionality of unconditionally bringing a window to the foreground isn't only useful in the context of follow-up app instances, but also, e.g., when your app works with a tray icon, its window was minimized before hiding it in the tray, and the end user wants to show the app's window by clicking on the tray icon.

Somewhat similar issue regarding Wayland: #3633.

Relevant platforms

Windows

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing Window::focus_window(), Window::set_visible(), and the existing ActivationToken API, then compare their behavior with the linked Windows APIs and platform constraints. Done should mean a documented, tested way to unconditionally restore and foreground a hidden or minimized Windows window, including the already-running application use case.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
desktop, operating-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.