Skip to content

Add hwnd parameter to display.set_mode() #1957

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

yunline
Copy link
Contributor

@yunline yunline commented Feb 28, 2023

display.set_mode( ... , hwnd :int = 0 ) # hwnd: The handle of the foreign window.

Embed a pygame window to a foreign window by setting the hwnd parameter to the handle of the target window. If this parameter is not set, the programe will check the environment variable SDL_WINDOWID. If SDL_WINDOWID is not set, a new window will be created.

Test code:

import tkinter
import threading

root=tkinter.Tk()
root.geometry("640x480")
btn=tkinter.Button(root,text="HelloWorld")
btn.pack()
cv=tkinter.Canvas(root)
cv.pack()

off=0
def pg_loop(hwnd):
    import pygame

    sf=pygame.display.set_mode(hwnd=hwnd) 

    pos=(20,20)
    while not off:
        sf.fill((0,0,0))
        pygame.draw.rect(sf,(255,0,0),(*pos,10,10))
        pygame.display.update()

        for event in pygame.event.get():
            if event.type==pygame.MOUSEMOTION:
                pos=event.pos

if __name__ == "__main__":
    hwnd=cv.winfo_id()
    threading.Thread(target=pg_loop,args=(hwnd,)).start()
    root.mainloop()
    off=1

This feature is compatible with OpenGL
Reference about OpenGL compatibility:

@yunline yunline requested a review from a team as a code owner February 28, 2023 10:51
@ankith26 ankith26 added this to the 2.2 milestone Feb 28, 2023
@ankith26 ankith26 added New API This pull request may need extra debate as it adds a new class or function to pygame display pygame.display labels Feb 28, 2023
@oddbookworm
Copy link
Member

oddbookworm commented Mar 11, 2023

This PR has the same problem as #1953 , where keyboard events are not being detected properly and persistently

@Starbuck5 Starbuck5 modified the milestones: 2.2, 2.3 Mar 26, 2023
@Starbuck5 Starbuck5 modified the milestones: 2.3, 2.3.1 May 31, 2023
@Starbuck5 Starbuck5 removed this from the 2.3.1 milestone Jul 29, 2023
Copy link
Member

@MyreMylar MyreMylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First this PR has conflicts that need resolving.

I personally think that a keyword argument like this is an easier thing for users to work with than the old pygame hint style - however I'm also not sure about this entire approach to embedding.

It seems to me, especially now that we are having our own proper window class that the generally proper way to embed aspects of pygame into a foreign window is by drawing/blitting everything to a pygame.Surface/Texture/Whatever SDL 3 uses and then drawing that surface into the foreign window via whatever methods the window manager has for drawing image data to it's windows. It would be nice to carry this neat separation between windows and drawing to a surface/texture onwards into embedding pygame drawing elsewhere.

Event loop code is always going to be messy when mixing and matching window management from different APIs as almost all window management APIs also include some form of input event handling.

I feel like a tutorial/conversion code effort on how to embed a pygame Surface/Texture into three popular window manager/GUI libraries (e.g. tkinter, PyQt5, Kivy) would be the optimal path possibly with some discussion of what event management should be left to the owning window manager (mouse/keyboard) and what could be done in pygame (probably controllers?).

Anyway, that is my overall feeling - this is better than the old pygame way, but that way is backwards compatible so, ugh, we should keep it around but not advertise it. However the overall approach to embedding a window inside a window is weird and we would probably do better with directly converting a pygame Surface/texture to whatever the external window manager of choice uses.

I've only really seen this approach used with tkinter where it doesn't work very well, so its possible my opinion could be changed by smooth running in another window manager.

@MyreMylar MyreMylar marked this pull request as draft November 26, 2023 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display pygame.display New API This pull request may need extra debate as it adds a new class or function to pygame
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants