[SOLVED] take over system focus

Post

Posted
Rating:
#1 (In Topic #1074)
Avatar
Enthusiast
sadams54 is in the usergroup ‘Enthusiast’
 I am working on another project and need a little help.

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?
Online now: No Back to the top

Post

Posted
Rating:
#2
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
There are several, if not many, ways to do this. I think the most elegant from the users point of view is using the dbus Notify demon.

Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Guru
cogier is in the usergroup ‘Guru’
This may help.

Code (gambas)

  1. Public Sub Form_Open()
  2.  
  3.   Wait 5
  4.   Shell "notify-send IMPORTANT! 'IMPORTANT message'"
  5.   Message("IMPORTANT\n\nImportant message", "OK")
  6.  
Online now: No Back to the top

Post

Posted
Rating:
#4
Regular
vuott is in the usergroup ‘Regular’
If your program is a command-line interface (CLI), then :? I would proceed as follows:

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:

Code (gambas)

  1. Public Sub Main()
  2.  
  3.   Wait 4
  4.  
  5.   Message.Warning("Message !")
  6.  

Europaeus sum !

<COLOR color="#FF8000">Amare memorentes atque deflentes ad mortem silenter labimur.</COLOR>
Online now: No Back to the top

Post

Posted
Rating:
#5
Guru
BruceSteers is in the usergroup ‘Guru’
 You need to find the active screen. i find the best way is with the Mouse.ScreenX, Mouse.ScreenY properties.

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.

Attachment
Online now: No Back to the top

Post

Posted
Rating:
#6
Guru
BruceSteers is in the usergroup ‘Guru’
 The first method is to make your notification happen by your own Form popping up.

You set the following…

MyNotifyForm.Stacking = Window.Above
MyNotifyForm.TopOnly = True

Then when MyNotifyForm opens it should be on top of any other window.
Online now: No Back to the top

Post

Posted
Rating:
#7
Avatar
Enthusiast
sadams54 is in the usergroup ‘Enthusiast’
I tested out some of this and it works fine except for where it is really needed. None seem to pop up a notification over another application that is running full screen such as VLC or totem. I need to be able to put a message up even over a full screen app.
Online now: No Back to the top

Post

Posted
Rating:
#8
Guru
BruceSteers is in the usergroup ‘Guru’
Odd , because i used this simple code..

Code (gambas)

  1.  
  2. Public Sub OpenTestWindow()
  3.  
  4.   w.W = 300
  5.   w.H = 200
  6.   w.Move(Screens[1].X + 100, 100)
  7.   w.Stacking = Window.Above
  8.   w.TopOnly = True
  9.  
  10.   w.Show
  11.  
  12.  
  13.  
  14.  

if SMPlayer or vlc is running on Screens[1] then the window opens on top, perfectly visible.
Online now: No Back to the top

Post

Posted
Rating:
#9
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
The notify (dbus) method will. That's it job. If it doesn't work then something is awry with the distribution you are using.
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

Online now: No Back to the top

Post

Posted
Rating:
#10
Avatar
Enthusiast
sadams54 is in the usergroup ‘Enthusiast’
I will give another try to the code bruce gave. But the mention of KDE made me cringe because now I am wondering if I have to worry about what desktop is being used. Something I had not considered.
Online now: No Back to the top

Post

Posted
Rating:
#11
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
Weeeeelll, If you want to control the desktop then I guess that you are going to take into consideration "the desktop".  ;)
Or use the dbus notify method. (I believe that I may have mentioned this before  :) )

Online now: No Back to the top

Post

Posted
Rating:
#12
Avatar
Enthusiast
sadams54 is in the usergroup ‘Enthusiast’
 I did more testing and the code

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.
Online now: No Back to the top

Post

Posted
Rating:
#13
Guru
BruceSteers is in the usergroup ‘Guru’
My code and vlc has no problem on X (see screenshot)

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)

  1. Public Sub OpenTestWindow()
  2.  
  3. Wait 2  ' wait for me to move the mouse to VLC screen to test.
  4.  
  5.   ' find what screen the mouse is on...
  6.   Dim hRect As Rect, iScreen As Integer
  7.   If Screens.Count > 1 Then
  8.     For Each hScreen As Screen In Screens
  9.       hRect = Rect(hScreen.X, hScreen.Y, hScreen.W, hScreen.H)
  10.       If hRect.Contains(Mouse.ScreenX, Mouse.ScreenY) Then Break
  11.       Inc iScreen
  12.     Next
  13.  
  14.   ' Make window on mouse screen
  15.   w.W = 300
  16.   w.H = 200
  17.   w.Move(Screens[iScreen].X + 100, Screens[iScreen].Y + 100)
  18.   w.Utility = True
  19.  
  20.   ' open window
  21.   w.Show
  22.   Wait 0.1
  23.   ' force it to front
  24.   w.Stacking = Window.Above
  25.   w.TopOnly = True
  26.   w.Activate
  27.  
  28.  

Image

(Click to enlarge)

Online now: No Back to the top

Post

Posted
Rating:
#14
Avatar
Enthusiast
sadams54 is in the usergroup ‘Enthusiast’
Bruce you are a genius. That worked perfectly. and deadpool is awesome.
Online now: No Back to the top

Post

Posted
Rating:
#15
Avatar
Regular
Godzilla is in the usergroup ‘Regular’
 This is a great thread and very helpful.

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.

Attachment
Online now: No Back to the top

Post

Posted
Rating:
#16
Avatar
Guru
cogier is in the usergroup ‘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. :D

Attachment
Online now: No Back to the top

Post

Posted
Rating:
#17
Avatar
Regular
Godzilla is in the usergroup ‘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. :D

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.  :D

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.
Online now: No Back to the top
1 guest and 0 members have just viewed this.