I am running a little program in python that launches a small window that needs to stay on top of all the other windows. I believe this is OS specific, how is it done in GNU-Linux with GNOME?
[Update - Solution for Windows]
Lovely, I think I got it working. I am using Python 2.5.4 with Pygame 1.9.1 in Eclipse on Vista 64-bit. Thus, this is for windows systems. The SetWindowPos
function is documented Here. I will refer to this in my explanation.
Imports:
from ctypes import windll
Then I set up a variable that calls the "SetWindowPos" in user32:
SetWindowPos = windll.user32.SetWindowPos
Now, let's say I just made a window:
screen = pygame.display.set_mode((100,100), pygame.NOFRAME)
The next line is the key. This sets the window to be on top of other windows.
SetWindowPos(pygame.display.get_wm_info()['window'], -1, x, y, 0, 0, 0x0001)
Basically, You supply the hWnd
(Window Handle) with the window ID returned from a call to display.get_wm_info()
. Now the function can edit the window you just initialized.
The -1
is our hWndInsertAfter
.
The MSDN site says:
A window can be made a topmost window either by setting the hWndInsertAfter parameter to HWND_TOPMOST and ensuring that the SWP_NOZORDER flag is not set, or by setting a window's position in the Z order so that it is above any existing topmost windows. When a non-topmost window is made topmost, its owned windows are also made topmost. Its owners, however, are not changed.
So, the -1
makes sure the window is above any other existing topmost windows, but this may not work in all cases. Maybe a -2 beats a -1? It currently works for me. :)
The x
and y
specify the new coordinates for the window being set. I wanted the window to stay at its current position when the SetWindowPos
function was called on it. Alas, I couldn't find a way to easily pass the current window (x,y) position into the function. I was able to find a work around, but assume I shouldn't introduce a new topic into this question.
The 0, 0,
are supposed to specify the new width and height of the window, in pixels. Well, that functionality is already in your pygame.display.set_mode()
function, so I left them at 0. The 0x0001
ignores these parameters.
0x0001
corresponds to SWP_NOSIZE and is my only uFlag. A list of all the available uFlags are on the provided documentation page. Some of their Hex representations are as follows:
- SWP_NOSIZE = 0x0001
- SWP_NOMOVE = 0x0002
- SWP_NOZORDER = 0x0004
- SWP_NOREDRAW = 0x0008
- SWP_NOACTIVATE = 0x0010
- SWP_FRAMECHANGED = 0x0020
- SWP_SHOWWINDOW = 0x0040
- SWP_HIDEWINDOW = 0x0080
- SWP_NOCOPYBITS = 0x0100
- SWP_NOOWNERZORDER = 0x0200
- SWP_NOSENDCHANGING = 0x0400
That should be it! Hope it works for you!
Credit to John Popplewell at john@johnnypops.demon.co.uk for his help.