tl;dr How do I create a wxPython application/window so its position is kept between the launches under Wayland?
I have a few wxPython programs I wrote for myself that need to remember their window’s position and size when closed, and restore it when launched again. On Windows and on Linux under X11 I used a simple combination of GetRect()/SetSize(). On Linux under Wayland the “size” part of those functions still works, but an attempt to get the position, through GetRect(), GetPosition() or whatever, always returns (0, 0), and an attempt to set the position yields no result (the window is just centered on the default display or something, looks particularly hilarious for an application that creates multiple windows and they all appear in the center). As I understand after some reading and googling, that is by design - Wayland doesn’t allow applications to manipulate their windows’ position. However, I see some applications still remembering and restoring their windows’ positions between the launches - by themselves, or by somehow delegating that to the desktop environment, I do not know. Sadly, none of them that I have are written in wxPython to look at the sources. How do I create a wxPython application/window so its position is kept between the launches under Wayland?
Here’s my code example for the reference (the positioning part doesn’t work under Wayland - what do I need to change?):
#!/usr/bin/env python3
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, window_id, title):
wx.Frame.__init__(self, parent, window_id, title)
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Show(True)
def ReadSettings(self):
rect = [0, 0, 100, 100]
try:
with open("settings.txt", "r") as f:
rect = [int(s) for s in f.read().split(",")]
except:
pass
self.SetSize(*rect)
def WriteSettings(self):
with open("settings.txt", "w") as f:
f.write(",".join((str(s) for s in self.GetRect())))
def OnClose(self, evt):
self.WriteSettings()
self.Destroy()
app = wx.App(0)
frame = MainWindow(None, -1, "Test")
frame.ReadSettings()
frame.Show(1)
app.MainLoop()