simonkrauter / NiGui

Cross-platform desktop GUI toolkit written in Nim
MIT License
722 stars 51 forks source link

Window always on top #80

Closed phillvancejr closed 4 years ago

phillvancejr commented 4 years ago

Hello I'm wondering if it is possible to make the main window topmost and float on top of all other application windows?

simonkrauter commented 4 years ago

This hasn't added yet. The question is: Is this really something an application should do? I rather think it's an anti-feature.

Deeper thoughts: How can one application decide that it is more important to be visible that other applications? What if multiple applications set this flag, which one is then in the foreground?

phillvancejr commented 4 years ago

For me being able to make a window stay on top of others is very import. I'm a graphic designer and I write automation/helper tools for myself and coworkers. We work in Adobe Illustrator primarily but the tools I make need to be accessed and used frequently so it is convenient if the small tool window (which is usually quite small, the size of an Illustrator palette) can float above the Illustrator window at all times so whenever you click back into Illustrator you don't have to go back and find the tool again under your other open windows. I'm essentially making additional palettes for Illustrator.

The logical follow up question is: why not use Illustrator's built in gui scripting/plugin apis? There are three primary reasons;

  1. The pure javascript gui api that Adobe provides does not allow you to create windows that both remain above other windows and allow interaction with illustrator simultaneously. You can create a window that floats on top of Illustrator, but you cannot interact with Illustrator until you close this window. Alternatively you can create a window that allows you to interact with Illustrator while it exists, however this window will not remain on top, it will go to the bottom of the window stack after clicking the Illustrator window. These windows do not have dock icons, so to reactivate it you have to click on the window, and if Illustrator is on top of it, that means minimizing or moving Illustrator to the side to be able to click on the window. Neither option is efficient for a tool that is accessed frequently.

  2. Adobe provides two alternative apis that can create native Illustrator palettes, however these require creating dedicated plugins which must be installed in the plugin directory. For my team this is not a great option because it requires Admin approval for installation, and most of my team members do not have admin rights on their machines due to company policy. In order to install the plugins every designer would have to open an IT Help desk ticket and have the IT guys login remotely and approve the installation. This would also have to be done every time I update the tool, thus I prefer a solution which allows users to install the tools in a folder that do not require Admin approval.

  3. The Adobe apis don't all allow easy access to external processes. For example running and external shell processes is actually impossible using the normal Illustrator javascript api. File IO is also a huge pain, and it just generally lacks many convenient high level features that Nim offers. I could use the c++ plugin api which can be mixed with normal c++ code, but, I don't necessarily want to use this api for small tools, because of #2 above, and because of c++'s lack of abstractions which slow down development (that is I want to use a higher level language for productivity).

So, thus far I have been writing tools in Python with Tkinter or PyQt. Both libraries provide the window always on top feature, but I want to switch to Nim because on top of just preferring the language, distribution is much easier.

Deeper Thoughts answer: The way Tkinter and PyQt handle it is that all windows that have the always on top flag set float above all windows that do not have this flag. When a window that does not have this flag set is activated, the floating window still floats above but just doesn't have focus. When multiple windows set this flag, the most recently activated application is the top most.

Right now I am using the wxWidgets bindings which allow this feature. However it would be nice to use a smaller library that has a more Nim-like interface which is why I am interested in trying NiGui. However for me that lack of always on top ability is a deal breaker for my specific use case. I do of course realize how niche my use case is.

simonkrauter commented 4 years ago

Ok, now I understand your use case. For Windows it's easy to implement: HWND_TOPMOST or WS_EX_TOPMOST. For Gtk I found gtk_window_set_keep_above. I will try it the next days.