Pygame set window on top without changing it's position

Question:

As I found in the following topic : How to make python window run as "Always On Top"?

I know how to put a window on top. But I would like to keep it at the same position. The autor says that he found a work around to find the x and y values. I would like to know how I can achieve that !

How can I get the x, y values of a pygame window ? Maybe it’s a wrong way of doing.

The effect I am looking for is that the window goes on top when I trigger it with some function call.

For those who know League of legends, when a game starts, the window goes on top and remains at the same coordinates.

Asked By: Waroulolz

||

Answers:

I found a solution that seems pretty well done:

#!/usr/bin/python
# -*- coding: utf-8 -*-


from ctypes import windll, Structure, c_long, byref #windows only


class RECT(Structure):
    _fields_ = [
    ('left',    c_long),
    ('top',     c_long),
    ('right',   c_long),
    ('bottom',  c_long),
    ]
    def width(self):  return self.right  - self.left
    def height(self): return self.bottom - self.top


def onTop(window):
    SetWindowPos = windll.user32.SetWindowPos
    GetWindowRect = windll.user32.GetWindowRect
    rc = RECT()
    GetWindowRect(window, byref(rc))
    SetWindowPos(window, -1, rc.left, rc.top, 0, 0, 0x0001)

Now in order to put a window on top, simply call onTop(pygame.display.get_wm_info()['window']) to handle your pygame window.

Answered By: Waroulolz

There’s a shorter solution using the same function:

from ctypes import windll
SetWindowPos = windll.user32.SetWindowPos

NOSIZE = 1
NOMOVE = 2
TOPMOST = -1
NOT_TOPMOST = -2

def alwaysOnTop(yesOrNo):
    zorder = (NOT_TOPMOST, TOPMOST)[yesOrNo] # choose a flag according to bool
    hwnd = pygame.display.get_wm_info()['window'] # handle to the window
    SetWindowPos(hwnd, zorder, 0, 0, 0, 0, NOMOVE|NOSIZE)
Answered By: kmaork

Getting current window position:

from ctypes import POINTER, WINFUNCTYPE, windll
from ctypes.wintypes import BOOL, HWND, RECT


# get our window ID:
hwnd = pygame.display.get_wm_info()["window"]

# Jump through all the ctypes hoops:
prototype = WINFUNCTYPE(BOOL, HWND, POINTER(RECT))
paramflags = (1, "hwnd"), (2, "lprect")

GetWindowRect = prototype(("GetWindowRect", windll.user32), paramflags)

# finally get our data!
rect = GetWindowRect(hwnd)
print "top, left, bottom, right: ", rect.top, rect.left, rect.bottom, rect.right

# bottom, top, left, right:  644 98 124 644

Putting the window on the foreground:

x = rect.left
y = rect.top
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y)
Answered By: Alexandre Willame

This worked for me

import win32gui
import win32con

win32gui.SetWindowPos(pygame.display.get_wm_info()['window'], win32con.HWND_TOPMOST, 0,0,0,0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)

The window doesn’t move because I used the SWP_NOMOVE tag

Answered By: ZiyadCodes

I am using a Windows 11 system with Python 3.11.2 and for some reason, the SetWindowPos from windll.user32 library does not work. However the same SetWindowPos function from win32gui library works perfectly. Just do the exact answer @ZiyadCodes gave earlier.

To install required libraries:

$ pip install win32gui
$ pip install win32con

To keep pygame window always on top:

import win32gui
from win32con import SetWindowPos

SetWindowPos(pygame.display.get_wm_info()['window'], win32con.HWND_TOPMOST, 0,0,0,0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
Answered By: Arman H
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.