How to know if a Rust application is the frontmost application

Hi, I need to know if a running Rust compiled application is the frontmost application of the system (i.e., it has the user focus), before executing a function.

Cheers!

I think that rather depends on what operating system you are running under and what GUI library you may be using. Need more info.

6 Likes

Yeah!, I've just read that it is not native in Rust as a cross platform feature of the language, isn't it?

I need it mostly for windows and macintosh, but I do not understand how.

Regards.

We'll need to know which GUI framework you're using because it depends on that.

For example, here are lists of crates that provide a GUI framework:

If you're still looking for one, I'm not in a good position to give any advice. I've toyed with a few, but it was long ago, and I didn't go very deep.

EDIT: To give examples in a couple of those frameworks:

  • with FLTK, there's a method to get the widget that currently has the focus, but those frameworks usually work by events, so checking when you get and lose focus is often what you'll find (like here). Note that it's the original framework documentation, so you'll have to find the equivalent in the rs-fltk crate.
  • with egui, you'll get this event when the window gained or lost focus, though there seems to be ways to query which widget has the focus, and so on (searching that doc will give you an idea of the possibilities).

In every framework I've used (WinForms, WPF, Android, Qt, ...), the common way to deal with focus has consistently been through events. When I get an in-focus or out-of-focus event, I react appropriately (clearing a form content, transferring the focus on a particular widget, etc).

1 Like

Would this be something winit provides?

At a glance I see Window in winit::window - Rust which looks relevant (but not quite what you asked for)

1 Like

Thanks. No magic answer, it seems. :face_with_spiral_eyes:

Well, I need it for two type of apps:

  • Basic Rust built utilities running with terminal in-out. I do not know it can be considered a GUI.
  • Tauri apps for desktop.

[Sorry that my questions about Rust are still awkward]

Command line programs don't traditionally have the concept of being "in front" - you might be after spying on the focus events for the terminal emulator/console which is highly platform specific and flakey, or the terminal emulator (ANSI) escape codes for buffer switching (eg tmux), but either way it's nothing like using a GUI.

If your program runs under tmux then it wouldn't even know if device that shows an output of your app even exists at that moment. Asking about whether you app is “frontmost” or not, in such environment, is entirely pointless.

The exact same thing happens with your GUI app if you are working on a remote system and someone uses Citrix to interact with it: you may know if your app is at the top of the window, but the question of whether anyone may interact with it or not is hard to answer… and, probably, mostly useless to answer.

This question has very little to do with Rust itself, I'm afraid.

Check the documentation: here and here.

Not in the usual sense of the word, no. On Linux, it might not be that hard (test it out yourself, I'm sending this message from Win10). On Windows, a GUI application requires setting up a message queue first. Using it, you can "subscribe" to different sorts of events, including focus/activation. If you try to "cheat" and compare GetActiveWindow with GetForegroundWindow while running a console application, the former will just return a zero.

Terminal applications were never designed with (G)UI focus in mind. It's why they're kept in the terminal, after all. If you're up to process console events one-by-one, though - try crossterm. Doesn't detect any focus events while running inside of VSC on my machine, but standalone terminal/cmd works as expected. Again though, be mindful of what you're doing.

Hmmm, the man page does report support for focus events from the terminal, but the way it's phrased does imply it doesn't itself send them for it's own buffer states...