[SOLVED] take over system focus
Posted
#1
(In Topic #1074)
Enthusiast

My program is running in the background all the time but I want to interrupt a user no matter what he is doing or working on and show a message from my program on the screen on top of anything else including full screen apps. I have no clue how to make this happen and my research is obviously not going well. Any ideas that work?
Posted
Regular

Posted
Guru

Posted
Regular

1) activate a Graphics Component anyway (for example: gb.gui.qt);
2) place, where needed in the code, the display of "Message" window.
Simple explanatory example:
Europaeus sum !
<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
Posted
Guru

By default you cannot force a Message box to appear on a selected screen (by default Message only appears on Screens[0])
There are ways around it.
you can either open a custom message Form moved to the required screen.
Or i made a hack that will move any gambas Modal window or you can set a list of window names like FMessage (Message) FInput (InputBox)
See the attached program.
It creates and starts a Timer just before the ShowModal function is called. then the Timer force moves the active Message window to the desired screen or window depending on how it is set
Normal (normal gambas mode, always Screens[0])
Same Screen (opens on the screen the mouse is on)
Same Window (stacked at top-left) (attaches to top-left of active window)
Same Window (centered) (centered on active window)
To use it in your own prog just put the Form.class in your .src folder and compile then set the modal mode as I have in the example.
Posted
Guru

You set the following…
MyNotifyForm.Stacking = Window.Above
MyNotifyForm.TopOnly = True
Then when MyNotifyForm opens it should be on top of any other window.
Posted
Enthusiast

Posted
Guru

if SMPlayer or vlc is running on Screens[1] then the window opens on top, perfectly visible.
Posted
Regular

Note Cogier's code above may need to be adjusted depending on what notification daemon you have and are running.*
In a terminal type "notify-send –help" which should give you the syntax needed.
* The notification daemon is a user optioned thing set at login. For example here the distro notifier is some kde thingo which I dislike, so I use dunst instead which is predictable and simple. Others on this machine use the kde one, so just beware of this if you are in a multiuser situation.
b
Posted
Enthusiast

Posted
Regular

Or use the dbus notify method. (I believe that I may have mentioned this before
Posted
Enthusiast

Public Sub OpenTestWindow()
Dim w As Window = New Window
w.W = 300
w.H = 200
w.Move(Screens[1].X + 100, 100)
w.Stacking = Window.Above
w.TopOnly = True
w.Show
End
will open a window but it is under the VLC full screen. I am still trying to find a way to pop up a window even over a full screen app. or find that it just can't be done. VLC "jitters" for a second when the message pops under it but that is all.
Maybe we are not on the same page as to what full screen means. I am for example bringing up vlc and double click the window so it uses the entire screen. No controls or edges. This on fedora 37 using wayland (yes I know yuck but I need to be able to work with default installs). Even on X I get the same behavior.
Posted
Guru

I did find that TopOnly = True and Stacking = Window.Above do not operate as expected where the window should remain on top but if i click the vlc window it pops to front above the other window, but the other window initially is above vlc here.
I've had to make a couple of workarounds on my software to make something that worked on other systems but didn't work on fedora function properly.
Maybe try this way, it works for me.
I first open the window, then set the flags to bring it to front after it's opened…
Code (gambas)
Posted
Enthusiast

Posted
Regular

I've struggled with coming up with a solution to this problem myself, and failed. I have to hand it to BruceSteers for sharing his method, which solved the problem for me.
I'm attaching my own code, based on Bruce's code. I'm trying to help anyone easily be able to plug Bruce's method into their own code. And use it as a replacement for Gambas' built-in Message() function.
It uses it a simple function that loads a child form, where I've more or less re-created the Gambas Message() window. Depending on how you call the function, it can show information alerts, warning alerts, and a Yes/No question dialog. All with appropriate icons.
Hopefully in the future, something like Bruce's "Window.Above" can be built into the Gambas Message() function and be there as a user option.
I'm not in league with the great coders on this forum. So if anyone would like to improve on this code, make it more logical, make it even easier for anyone to plug it into their own applications as a replacement for Message(), I welcome it and look forward to it.
Posted
Guru

I'm not in league with the great coders on this forum. So if anyone would like to improve on this code, make it more logical, make it even easier for anyone to plug it into their own applications as a replacement for Message(), I welcome it and look forward to it.
Well, you asked! I hope I have simplified this. Anyway, I had a bit of fun doing it.
Posted
Regular

cogier said
I'm not in league with the great coders on this forum. So if anyone would like to improve on this code, make it more logical, make it even easier for anyone to plug it into their own applications as a replacement for Message(), I welcome it and look forward to it.
Well, you asked! I hope I have simplified this. Anyway, I had a bit of fun doing it.![]()
OnTopMessage-0.0.1.tar.gz
Bravo cogier! You nailed it. And great idea to put the function that does the work in the child form. And you took me to school. I will learn a lot from studying your much-improved code.
I haven't had time to try it yet. But I think for anyone wanting to plug this functionality into their own code, simply copy (from cogier's code) ".src/OTMessage.class" and ".src/OTMessage.form" and paste it into your project's ".src/" folder. And using simple calls from your main form (using the examples from cogier's code) will give you Message() popups that will never be hidden behind itself, or any other application.
Thank you cogier for taking the time to work on this. And I'm glad it was fun for you.
UPDATE: copying (from cogier's code) ".src/OTMessage.class" and ".src/OTMessage.form" and pasting it into your project's ".src/" folder allows you to easily plug this functionality into any of your projects. I recommend also copying the 3 icons "info.png", "question.png", and "warning.png" into your application's base folder. But it's only cosmetic. Message windows will still function normally, without error.
1 guest and 0 members have just viewed this.



