Skip to content

Commit 8eaf3f0

Browse files
authored
Added an option to record and show logs
1 parent f27ee72 commit 8eaf3f0

File tree

2 files changed

+175
-14
lines changed

2 files changed

+175
-14
lines changed

faugus-launcher.py

+146-10
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
config_dir = os.getenv('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
3131
faugus_launcher_dir = f'{config_dir}/faugus-launcher'
3232
prefixes_dir = f'{faugus_launcher_dir}/prefixes'
33+
logs_dir = f'{faugus_launcher_dir}/logs'
3334
icons_dir = f'{faugus_launcher_dir}/icons'
3435
banners_dir = f'{faugus_launcher_dir}/banners'
3536
config_file_dir = f'{faugus_launcher_dir}/config.ini'
@@ -125,7 +126,7 @@ def __init__(self):
125126

126127
config_file = config_file_dir
127128
if not os.path.exists(config_file):
128-
self.save_config("False", prefixes_dir, "False", "False", "False", "GE-Proton", "True", "False", "False", "False", "List", "False", "", "False", "False")
129+
self.save_config("False", prefixes_dir, "False", "False", "False", "GE-Proton", "True", "False", "False", "False", "List", "False", "", "False", "False", "False")
129130

130131
self.games = []
131132

@@ -168,6 +169,10 @@ def __init__(self):
168169
self.menu_item_prefix.connect("activate", self.on_context_menu_prefix)
169170
self.context_menu.append(self.menu_item_prefix)
170171

172+
self.menu_show_logs = Gtk.MenuItem(label="Show logs")
173+
self.menu_show_logs.connect("activate", self.on_context_show_logs)
174+
self.context_menu.append(self.menu_show_logs)
175+
171176
self.context_menu.show_all()
172177

173178
self.load_config()
@@ -585,6 +590,23 @@ def on_item_right_click(self, widget, event):
585590

586591
game = next((j for j in self.games if j.title == title), None)
587592

593+
title_formatted = re.sub(r'[^a-zA-Z0-9\s]', '', title)
594+
title_formatted = title_formatted.replace(' ', '-')
595+
title_formatted = '-'.join(title_formatted.lower().split())
596+
597+
self.log_file_path = f"{logs_dir}/{title_formatted}/steam-0.log"
598+
self.umu_log_file_path = f"{logs_dir}/{title_formatted}/umu.log"
599+
600+
if self.enable_logging:
601+
self.menu_show_logs.set_visible(True)
602+
if os.path.exists(self.log_file_path):
603+
self.menu_show_logs.set_sensitive(True)
604+
self.current_title = title
605+
else:
606+
self.menu_show_logs.set_sensitive(False)
607+
else:
608+
self.menu_show_logs.set_visible(False)
609+
588610
if os.path.isdir(game.prefix):
589611
self.menu_item_prefix.set_sensitive(True)
590612
self.current_prefix = game.prefix
@@ -614,6 +636,105 @@ def on_context_menu_prefix(self, menu_item):
614636
selected_item = self.flowbox.get_selected_children()[0]
615637
subprocess.run(["xdg-open", self.current_prefix], check=True)
616638

639+
def on_context_show_logs(self, menu_item):
640+
selected_item = self.flowbox.get_selected_children()[0]
641+
self.on_show_logs_clicked(selected_item)
642+
643+
def on_show_logs_clicked(self, widget):
644+
dialog = Gtk.Dialog(title=f"{self.current_title} Logs", parent=self, modal=True)
645+
dialog.set_icon_from_file(faugus_png)
646+
dialog.set_default_size(1280, 720)
647+
if faugus_session:
648+
dialog.fullscreen()
649+
650+
scrolled_window1 = Gtk.ScrolledWindow()
651+
scrolled_window1.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
652+
text_view1 = Gtk.TextView()
653+
text_view1.set_editable(False)
654+
text_buffer1 = text_view1.get_buffer()
655+
with open(self.log_file_path, "r") as log_file:
656+
text_buffer1.set_text(log_file.read())
657+
scrolled_window1.add(text_view1)
658+
659+
scrolled_window2 = Gtk.ScrolledWindow()
660+
scrolled_window2.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
661+
text_view2 = Gtk.TextView()
662+
text_view2.set_editable(False)
663+
text_buffer2 = text_view2.get_buffer()
664+
with open(self.umu_log_file_path, "r") as log_file:
665+
text_buffer2.set_text(log_file.read())
666+
scrolled_window2.add(text_view2)
667+
668+
def copy_to_clipboard(button):
669+
current_page = notebook.get_current_page()
670+
if current_page == 0: # Tab 1: Proton
671+
start_iter, end_iter = text_buffer1.get_bounds()
672+
text_to_copy = text_buffer1.get_text(start_iter, end_iter, False)
673+
elif current_page == 1: # Tab 2: UMU-Launcher
674+
start_iter, end_iter = text_buffer2.get_bounds()
675+
text_to_copy = text_buffer2.get_text(start_iter, end_iter, False)
676+
else:
677+
text_to_copy = ""
678+
679+
clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
680+
clipboard.set_text(text_to_copy, -1)
681+
clipboard.store()
682+
683+
def open_location(button):
684+
subprocess.run(["xdg-open", os.path.dirname(self.log_file_path)], check=True)
685+
686+
button_copy_clipboard = Gtk.Button(label="Copy to clipboard")
687+
button_copy_clipboard.set_size_request(150, -1)
688+
button_copy_clipboard.connect("clicked", copy_to_clipboard)
689+
690+
button_open_location = Gtk.Button(label="Open file location")
691+
button_open_location.set_size_request(150, -1)
692+
button_open_location.connect("clicked", open_location)
693+
694+
notebook = Gtk.Notebook()
695+
notebook.set_margin_start(10)
696+
notebook.set_margin_end(10)
697+
notebook.set_margin_top(10)
698+
notebook.set_margin_bottom(10)
699+
notebook.set_halign(Gtk.Align.FILL)
700+
notebook.set_valign(Gtk.Align.FILL)
701+
notebook.set_vexpand(True)
702+
notebook.set_hexpand(True)
703+
704+
tab_box1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
705+
tab_label1 = Gtk.Label(label="Proton")
706+
tab_label1.set_width_chars(15)
707+
tab_label1.set_xalign(0.5)
708+
tab_box1.pack_start(tab_label1, True, True, 0)
709+
tab_box1.set_hexpand(True)
710+
711+
tab_box2 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
712+
tab_label2 = Gtk.Label(label="UMU-Launcher")
713+
tab_label2.set_width_chars(15)
714+
tab_label2.set_xalign(0.5)
715+
tab_box2.pack_start(tab_label2, True, True, 0)
716+
tab_box2.set_hexpand(True)
717+
718+
notebook.append_page(scrolled_window1, tab_box1)
719+
notebook.append_page(scrolled_window2, tab_box2)
720+
721+
content_area = dialog.get_content_area()
722+
box_bottom = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
723+
box_bottom.set_margin_start(10)
724+
box_bottom.set_margin_end(10)
725+
box_bottom.set_margin_bottom(10)
726+
box_bottom.pack_start(button_copy_clipboard, True, True, 0)
727+
box_bottom.pack_start(button_open_location, True, True, 0)
728+
729+
content_area.add(notebook)
730+
content_area.add(box_bottom)
731+
732+
tab_box1.show_all()
733+
tab_box2.show_all()
734+
dialog.show_all()
735+
dialog.run()
736+
dialog.destroy()
737+
617738
def on_duplicate_clicked(self, widget):
618739
selected_children = self.flowbox.get_selected_children()
619740
selected_child = selected_children[0]
@@ -852,8 +973,9 @@ def load_config(self):
852973
self.api_key = config_dict.get('api-key', '').strip('"')
853974
self.start_fullscreen = config_dict.get('start-fullscreen', 'False') == 'True'
854975
self.gamepad_navigation = config_dict.get('gamepad-navigation', 'False') == 'True'
976+
self.enable_logging = config_dict.get('enable-logging', 'False') == 'True'
855977
else:
856-
self.save_config(False, '', "False", "False", "False", "GE-Proton", "True", "False", "False", "False", "List", "False", "", "False", "False")
978+
self.save_config(False, '', "False", "False", "False", "GE-Proton", "True", "False", "False", "False", "List", "False", "", "False", "False", "False")
857979

858980
def create_tray_menu(self):
859981
# Create the tray menu
@@ -1153,6 +1275,7 @@ def on_settings_dialog_response(self, dialog, response_id, settings_dialog):
11531275
self.entry_api_key = settings_dialog.entry_api_key
11541276
self.checkbox_start_fullscreen = settings_dialog.checkbox_start_fullscreen
11551277
self.checkbox_gamepad_navigation = settings_dialog.checkbox_gamepad_navigation
1278+
self.checkbox_enable_logging = settings_dialog.checkbox_enable_logging
11561279

11571280
self.checkbox_mangohud = settings_dialog.checkbox_mangohud
11581281
self.checkbox_gamemode = settings_dialog.checkbox_gamemode
@@ -1170,6 +1293,7 @@ def on_settings_dialog_response(self, dialog, response_id, settings_dialog):
11701293
entry_api_key = self.entry_api_key.get_text()
11711294
checkbox_start_fullscreen = self.checkbox_start_fullscreen.get_active()
11721295
checkbox_gamepad_navigation = self.checkbox_gamepad_navigation.get_active()
1296+
checkbox_enable_logging = self.checkbox_enable_logging.get_active()
11731297

11741298
mangohud_state = self.checkbox_mangohud.get_active()
11751299
gamemode_state = self.checkbox_gamemode.get_active()
@@ -1187,7 +1311,7 @@ def on_settings_dialog_response(self, dialog, response_id, settings_dialog):
11871311
if not validation_result:
11881312
return
11891313

1190-
self.save_config(checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation)
1314+
self.save_config(checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation, checkbox_enable_logging)
11911315
self.manage_autostart_file(checkbox_start_boot)
11921316

11931317
if checkbox_system_tray:
@@ -2377,7 +2501,7 @@ def save_games(self):
23772501
with open("games.json", "w", encoding="utf-8") as file:
23782502
json.dump(games_data, file, ensure_ascii=False, indent=4)
23792503

2380-
def save_config(self, checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation):
2504+
def save_config(self, checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation, checkbox_enable_logging):
23812505
# Path to the configuration file
23822506
config_file = os.path.join(self.working_directory, 'config.ini')
23832507

@@ -2409,6 +2533,7 @@ def save_config(self, checkbox_state, default_prefix, mangohud_state, gamemode_s
24092533
config['api-key'] = entry_api_key
24102534
config['start-fullscreen'] = checkbox_start_fullscreen
24112535
config['gamepad-navigation'] = checkbox_gamepad_navigation
2536+
config['enable-logging'] = checkbox_enable_logging
24122537

24132538
# Write configurations back to the file
24142539
with open(config_file, 'w') as f:
@@ -2532,6 +2657,10 @@ def __init__(self, parent):
25322657
self.checkbox_splash_disable = Gtk.CheckButton(label="Disable splash window")
25332658
self.checkbox_splash_disable.set_active(False)
25342659

2660+
# Create checkbox for 'Enable logging' option
2661+
self.checkbox_enable_logging = Gtk.CheckButton(label="Enable logging")
2662+
self.checkbox_enable_logging.set_active(False)
2663+
25352664
# Button Winetricks
25362665
self.button_winetricks_default = Gtk.Button(label="Winetricks")
25372666
self.button_winetricks_default.connect("clicked", self.on_button_winetricks_default_clicked)
@@ -2682,6 +2811,7 @@ def __init__(self, parent):
26822811
grid_miscellaneous.attach(self.checkbox_system_tray, 0, 4, 1, 1)
26832812
grid_miscellaneous.attach(self.checkbox_start_boot, 0, 5, 1, 1)
26842813
grid_miscellaneous.attach(self.checkbox_close_after_launch, 0, 6, 1, 1)
2814+
grid_miscellaneous.attach(self.checkbox_enable_logging, 0, 7, 1, 1)
26852815

26862816
grid_interface_mode.attach(self.label_interface, 0, 0, 1, 1)
26872817
grid_interface_mode.attach(self.combo_box_interface, 0, 1, 1, 1)
@@ -2870,6 +3000,7 @@ def on_button_run_default_clicked(self, widget):
28703000
entry_api_key = self.entry_api_key.get_text()
28713001
checkbox_start_fullscreen = self.checkbox_start_fullscreen.get_active()
28723002
checkbox_gamepad_navigation = self.checkbox_gamepad_navigation.get_active()
3003+
checkbox_enable_logging = self.checkbox_enable_logging.get_active()
28733004

28743005
mangohud_state = self.checkbox_mangohud.get_active()
28753006
gamemode_state = self.checkbox_gamemode.get_active()
@@ -2881,7 +3012,7 @@ def on_button_run_default_clicked(self, widget):
28813012
if default_runner == "GE-Proton Latest (default)":
28823013
default_runner = "GE-Proton"
28833014

2884-
self.parent.save_config(checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation)
3015+
self.parent.save_config(checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation, checkbox_enable_logging)
28853016
self.set_sensitive(False)
28863017

28873018
self.parent.manage_autostart_file(checkbox_start_boot)
@@ -3025,6 +3156,7 @@ def on_button_winecfg_default_clicked(self, widget):
30253156
entry_api_key = self.entry_api_key.get_text()
30263157
checkbox_start_fullscreen = self.checkbox_start_fullscreen.get_active()
30273158
checkbox_gamepad_navigation = self.checkbox_gamepad_navigation.get_active()
3159+
checkbox_enable_logging = self.checkbox_enable_logging.get_active()
30283160

30293161
mangohud_state = self.checkbox_mangohud.get_active()
30303162
gamemode_state = self.checkbox_gamemode.get_active()
@@ -3036,7 +3168,7 @@ def on_button_winecfg_default_clicked(self, widget):
30363168
if default_runner == "GE-Proton Latest (default)":
30373169
default_runner = "GE-Proton"
30383170

3039-
self.parent.save_config(checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation)
3171+
self.parent.save_config(checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation, checkbox_enable_logging)
30403172
self.set_sensitive(False)
30413173

30423174
self.parent.manage_autostart_file(checkbox_start_boot)
@@ -3105,6 +3237,7 @@ def on_button_winetricks_default_clicked(self, widget):
31053237
entry_api_key = self.entry_api_key.get_text()
31063238
checkbox_start_fullscreen = self.checkbox_start_fullscreen.get_active()
31073239
checkbox_gamepad_navigation = self.checkbox_gamepad_navigation.get_active()
3240+
checkbox_enable_logging = self.checkbox_enable_logging.get_active()
31083241

31093242
mangohud_state = self.checkbox_mangohud.get_active()
31103243
gamemode_state = self.checkbox_gamemode.get_active()
@@ -3116,7 +3249,7 @@ def on_button_winetricks_default_clicked(self, widget):
31163249
if default_runner == "GE-Proton Latest (default)":
31173250
default_runner = "GE-Proton"
31183251

3119-
self.parent.save_config(checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation)
3252+
self.parent.save_config(checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation, checkbox_enable_logging)
31203253
self.set_sensitive(False)
31213254

31223255
self.parent.manage_autostart_file(checkbox_start_boot)
@@ -3237,6 +3370,7 @@ def load_config(self):
32373370
self.api_key = config_dict.get('api-key', '').strip('"')
32383371
start_fullscreen = config_dict.get('start-fullscreen', 'False') == 'True'
32393372
gamepad_navigation = config_dict.get('gamepad-navigation', 'False') == 'True'
3373+
enable_logging = config_dict.get('enable-logging', 'False') == 'True'
32403374

32413375
self.checkbox_close_after_launch.set_active(close_on_launch)
32423376
self.entry_default_prefix.set_text(self.default_prefix)
@@ -3261,6 +3395,7 @@ def load_config(self):
32613395
self.checkbox_start_maximized.set_active(start_maximized)
32623396
self.checkbox_start_fullscreen.set_active(start_fullscreen)
32633397
self.checkbox_gamepad_navigation.set_active(gamepad_navigation)
3398+
self.checkbox_enable_logging.set_active(enable_logging)
32643399

32653400
model = self.combo_box_interface.get_model()
32663401
index_to_activate2 = 0
@@ -3273,7 +3408,7 @@ def load_config(self):
32733408
self.entry_api_key.set_text(self.api_key)
32743409
else:
32753410
# Save default configuration if file does not exist
3276-
self.parent.save_config(False, '', "False", "False", "False", "GE-Proton", "True", "False", "False", "False", "List", "False", "", "False", "False")
3411+
self.parent.save_config(False, '', "False", "False", "False", "GE-Proton", "True", "False", "False", "False", "List", "False", "", "False", "False", "False")
32773412

32783413

32793414
class Game:
@@ -5442,9 +5577,9 @@ def load_config(self):
54425577

54435578
else:
54445579
# Save default configuration if file does not exist
5445-
self.save_config(False, '', "False", "False", "False", "GE-Proton", "True", "False", "False", "False", "List", "False", "", "False", "False")
5580+
self.save_config(False, '', "False", "False", "False", "GE-Proton", "True", "False", "False", "False", "List", "False", "", "False", "False", "False")
54465581

5447-
def save_config(self, checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation):
5582+
def save_config(self, checkbox_state, default_prefix, mangohud_state, gamemode_state, sc_controller_state, default_runner, checkbox_discrete_gpu_state, checkbox_splash_disable, checkbox_system_tray, checkbox_start_boot, combo_box_interface, checkbox_start_maximized, entry_api_key, checkbox_start_fullscreen, checkbox_gamepad_navigation, checkbox_enable_logging):
54485583
# Path to the configuration file
54495584
config_file = config_file_dir
54505585

@@ -5484,6 +5619,7 @@ def save_config(self, checkbox_state, default_prefix, mangohud_state, gamemode_s
54845619
config['api-key'] = entry_api_key
54855620
config['start-fullscreen'] = checkbox_start_fullscreen
54865621
config['gamepad-navigation'] = checkbox_gamepad_navigation
5622+
config['enable-logging'] = checkbox_enable_logging
54875623

54885624
# Write configurations back to the file
54895625
with open(config_file, 'w') as f:

0 commit comments

Comments
 (0)