Hide and show the LutrisWindow via the tray icon

Clicking it will toggle the visibility of the LutrisWindow, This is a bit trickier than it seems though; we need tor restore its position as that gets reset, and therefore we must save it when hiding.

Further, hiding a window that has a transient dialog breaks GTK
messily, so I don't allow that.

Resolves #4352
This commit is contained in:
Daniel Johnson 2022-07-09 11:44:54 -04:00
parent 52b275ca0c
commit 8a597efba2
3 changed files with 40 additions and 13 deletions

View file

@ -69,10 +69,7 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
update_desktop_icons()
load_icon_theme()
self.application = application
self.window_x = settings.read_setting("window_x")
self.window_y = settings.read_setting("window_y")
if self.window_x and self.window_y:
self.move(int(self.window_x), int(self.window_y))
self.restore_window_position()
self.threads_stoppers = []
self.window_size = (width, height)
self.maximized = settings.read_setting("maximized") == "True"
@ -589,6 +586,24 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
self.emit("view-updated")
return True
def save_window_state(self):
"""Saves the window's size position and state as settings."""
width, height = self.window_size
settings.write_setting("width", width)
settings.write_setting("height", height)
if self.window_x and self.window_y:
settings.write_setting("window_x", self.window_x)
settings.write_setting("window_y", self.window_y)
settings.write_setting("maximized", self.maximized)
def restore_window_position(self):
"""Restores the window position only; we call this when showing
the window, but restore the other settings only when creating it."""
self.window_x = settings.read_setting("window_x")
self.window_y = settings.read_setting("window_y")
if self.window_x and self.window_y:
self.move(int(self.window_x), int(self.window_y))
def on_service_login(self, service):
AsyncCall(service.reload, None)
return True
@ -627,14 +642,13 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
for stopper in self.threads_stoppers:
stopper()
# Save settings
width, height = self.window_size
settings.write_setting("width", width)
settings.write_setting("height", height)
if self.window_x and self.window_y:
settings.write_setting("window_x", self.window_x)
settings.write_setting("window_y", self.window_y)
settings.write_setting("maximized", self.maximized)
@GtkTemplate.Callback
def on_hide(self, *_args):
self.save_window_state()
@GtkTemplate.Callback
def on_show(self, *_args):
self.restore_window_position()
@GtkTemplate.Callback
def on_preferences_activate(self, *_args):

View file

@ -77,7 +77,18 @@ class LutrisStatusIcon:
def on_activate(self, _status_icon, _event=None):
"""Callback to show or hide the window"""
self.application.window.present()
app_window = self.application.window
if app_window.window.get_visible():
# If the wndow has any transients, hiding it will hide them too
# never to be shown again, which is broken. So we don't allow that.
windows = Gtk.Window.list_toplevels()
for w in windows:
if w.get_transient_for() == self.application.window:
return
app_window.window.hide()
else:
app_window.window.show()
def on_menu_popup(self, _status_icon, button, time):
"""Callback to show the contextual menu"""

View file

@ -25,6 +25,8 @@
<property name="title" translatable="yes">Lutris</property>
<property name="icon-name">lutris</property>
<signal name="destroy" handler="on_destroy" swapped="no"/>
<signal name="hide" handler="on_hide" swapped="no"/>
<signal name="show" handler="on_show" swapped="no"/>
<signal name="size-allocate" handler="on_resize" swapped="no"/>
<child>
<object class="GtkStack">