30
30
config_dir = os .getenv ('XDG_CONFIG_HOME' , os .path .expanduser ('~/.config' ))
31
31
faugus_launcher_dir = f'{ config_dir } /faugus-launcher'
32
32
prefixes_dir = f'{ faugus_launcher_dir } /prefixes'
33
+ logs_dir = f'{ faugus_launcher_dir } /logs'
33
34
icons_dir = f'{ faugus_launcher_dir } /icons'
34
35
banners_dir = f'{ faugus_launcher_dir } /banners'
35
36
config_file_dir = f'{ faugus_launcher_dir } /config.ini'
@@ -125,7 +126,7 @@ def __init__(self):
125
126
126
127
config_file = config_file_dir
127
128
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" )
129
130
130
131
self .games = []
131
132
@@ -168,6 +169,10 @@ def __init__(self):
168
169
self .menu_item_prefix .connect ("activate" , self .on_context_menu_prefix )
169
170
self .context_menu .append (self .menu_item_prefix )
170
171
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
+
171
176
self .context_menu .show_all ()
172
177
173
178
self .load_config ()
@@ -585,6 +590,23 @@ def on_item_right_click(self, widget, event):
585
590
586
591
game = next ((j for j in self .games if j .title == title ), None )
587
592
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
+
588
610
if os .path .isdir (game .prefix ):
589
611
self .menu_item_prefix .set_sensitive (True )
590
612
self .current_prefix = game .prefix
@@ -614,6 +636,105 @@ def on_context_menu_prefix(self, menu_item):
614
636
selected_item = self .flowbox .get_selected_children ()[0 ]
615
637
subprocess .run (["xdg-open" , self .current_prefix ], check = True )
616
638
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
+
617
738
def on_duplicate_clicked (self , widget ):
618
739
selected_children = self .flowbox .get_selected_children ()
619
740
selected_child = selected_children [0 ]
@@ -852,8 +973,9 @@ def load_config(self):
852
973
self .api_key = config_dict .get ('api-key' , '' ).strip ('"' )
853
974
self .start_fullscreen = config_dict .get ('start-fullscreen' , 'False' ) == 'True'
854
975
self .gamepad_navigation = config_dict .get ('gamepad-navigation' , 'False' ) == 'True'
976
+ self .enable_logging = config_dict .get ('enable-logging' , 'False' ) == 'True'
855
977
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" )
857
979
858
980
def create_tray_menu (self ):
859
981
# Create the tray menu
@@ -1153,6 +1275,7 @@ def on_settings_dialog_response(self, dialog, response_id, settings_dialog):
1153
1275
self .entry_api_key = settings_dialog .entry_api_key
1154
1276
self .checkbox_start_fullscreen = settings_dialog .checkbox_start_fullscreen
1155
1277
self .checkbox_gamepad_navigation = settings_dialog .checkbox_gamepad_navigation
1278
+ self .checkbox_enable_logging = settings_dialog .checkbox_enable_logging
1156
1279
1157
1280
self .checkbox_mangohud = settings_dialog .checkbox_mangohud
1158
1281
self .checkbox_gamemode = settings_dialog .checkbox_gamemode
@@ -1170,6 +1293,7 @@ def on_settings_dialog_response(self, dialog, response_id, settings_dialog):
1170
1293
entry_api_key = self .entry_api_key .get_text ()
1171
1294
checkbox_start_fullscreen = self .checkbox_start_fullscreen .get_active ()
1172
1295
checkbox_gamepad_navigation = self .checkbox_gamepad_navigation .get_active ()
1296
+ checkbox_enable_logging = self .checkbox_enable_logging .get_active ()
1173
1297
1174
1298
mangohud_state = self .checkbox_mangohud .get_active ()
1175
1299
gamemode_state = self .checkbox_gamemode .get_active ()
@@ -1187,7 +1311,7 @@ def on_settings_dialog_response(self, dialog, response_id, settings_dialog):
1187
1311
if not validation_result :
1188
1312
return
1189
1313
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 )
1191
1315
self .manage_autostart_file (checkbox_start_boot )
1192
1316
1193
1317
if checkbox_system_tray :
@@ -2377,7 +2501,7 @@ def save_games(self):
2377
2501
with open ("games.json" , "w" , encoding = "utf-8" ) as file :
2378
2502
json .dump (games_data , file , ensure_ascii = False , indent = 4 )
2379
2503
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 ):
2381
2505
# Path to the configuration file
2382
2506
config_file = os .path .join (self .working_directory , 'config.ini' )
2383
2507
@@ -2409,6 +2533,7 @@ def save_config(self, checkbox_state, default_prefix, mangohud_state, gamemode_s
2409
2533
config ['api-key' ] = entry_api_key
2410
2534
config ['start-fullscreen' ] = checkbox_start_fullscreen
2411
2535
config ['gamepad-navigation' ] = checkbox_gamepad_navigation
2536
+ config ['enable-logging' ] = checkbox_enable_logging
2412
2537
2413
2538
# Write configurations back to the file
2414
2539
with open (config_file , 'w' ) as f :
@@ -2532,6 +2657,10 @@ def __init__(self, parent):
2532
2657
self .checkbox_splash_disable = Gtk .CheckButton (label = "Disable splash window" )
2533
2658
self .checkbox_splash_disable .set_active (False )
2534
2659
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
+
2535
2664
# Button Winetricks
2536
2665
self .button_winetricks_default = Gtk .Button (label = "Winetricks" )
2537
2666
self .button_winetricks_default .connect ("clicked" , self .on_button_winetricks_default_clicked )
@@ -2682,6 +2811,7 @@ def __init__(self, parent):
2682
2811
grid_miscellaneous .attach (self .checkbox_system_tray , 0 , 4 , 1 , 1 )
2683
2812
grid_miscellaneous .attach (self .checkbox_start_boot , 0 , 5 , 1 , 1 )
2684
2813
grid_miscellaneous .attach (self .checkbox_close_after_launch , 0 , 6 , 1 , 1 )
2814
+ grid_miscellaneous .attach (self .checkbox_enable_logging , 0 , 7 , 1 , 1 )
2685
2815
2686
2816
grid_interface_mode .attach (self .label_interface , 0 , 0 , 1 , 1 )
2687
2817
grid_interface_mode .attach (self .combo_box_interface , 0 , 1 , 1 , 1 )
@@ -2870,6 +3000,7 @@ def on_button_run_default_clicked(self, widget):
2870
3000
entry_api_key = self .entry_api_key .get_text ()
2871
3001
checkbox_start_fullscreen = self .checkbox_start_fullscreen .get_active ()
2872
3002
checkbox_gamepad_navigation = self .checkbox_gamepad_navigation .get_active ()
3003
+ checkbox_enable_logging = self .checkbox_enable_logging .get_active ()
2873
3004
2874
3005
mangohud_state = self .checkbox_mangohud .get_active ()
2875
3006
gamemode_state = self .checkbox_gamemode .get_active ()
@@ -2881,7 +3012,7 @@ def on_button_run_default_clicked(self, widget):
2881
3012
if default_runner == "GE-Proton Latest (default)" :
2882
3013
default_runner = "GE-Proton"
2883
3014
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 )
2885
3016
self .set_sensitive (False )
2886
3017
2887
3018
self .parent .manage_autostart_file (checkbox_start_boot )
@@ -3025,6 +3156,7 @@ def on_button_winecfg_default_clicked(self, widget):
3025
3156
entry_api_key = self .entry_api_key .get_text ()
3026
3157
checkbox_start_fullscreen = self .checkbox_start_fullscreen .get_active ()
3027
3158
checkbox_gamepad_navigation = self .checkbox_gamepad_navigation .get_active ()
3159
+ checkbox_enable_logging = self .checkbox_enable_logging .get_active ()
3028
3160
3029
3161
mangohud_state = self .checkbox_mangohud .get_active ()
3030
3162
gamemode_state = self .checkbox_gamemode .get_active ()
@@ -3036,7 +3168,7 @@ def on_button_winecfg_default_clicked(self, widget):
3036
3168
if default_runner == "GE-Proton Latest (default)" :
3037
3169
default_runner = "GE-Proton"
3038
3170
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 )
3040
3172
self .set_sensitive (False )
3041
3173
3042
3174
self .parent .manage_autostart_file (checkbox_start_boot )
@@ -3105,6 +3237,7 @@ def on_button_winetricks_default_clicked(self, widget):
3105
3237
entry_api_key = self .entry_api_key .get_text ()
3106
3238
checkbox_start_fullscreen = self .checkbox_start_fullscreen .get_active ()
3107
3239
checkbox_gamepad_navigation = self .checkbox_gamepad_navigation .get_active ()
3240
+ checkbox_enable_logging = self .checkbox_enable_logging .get_active ()
3108
3241
3109
3242
mangohud_state = self .checkbox_mangohud .get_active ()
3110
3243
gamemode_state = self .checkbox_gamemode .get_active ()
@@ -3116,7 +3249,7 @@ def on_button_winetricks_default_clicked(self, widget):
3116
3249
if default_runner == "GE-Proton Latest (default)" :
3117
3250
default_runner = "GE-Proton"
3118
3251
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 )
3120
3253
self .set_sensitive (False )
3121
3254
3122
3255
self .parent .manage_autostart_file (checkbox_start_boot )
@@ -3237,6 +3370,7 @@ def load_config(self):
3237
3370
self .api_key = config_dict .get ('api-key' , '' ).strip ('"' )
3238
3371
start_fullscreen = config_dict .get ('start-fullscreen' , 'False' ) == 'True'
3239
3372
gamepad_navigation = config_dict .get ('gamepad-navigation' , 'False' ) == 'True'
3373
+ enable_logging = config_dict .get ('enable-logging' , 'False' ) == 'True'
3240
3374
3241
3375
self .checkbox_close_after_launch .set_active (close_on_launch )
3242
3376
self .entry_default_prefix .set_text (self .default_prefix )
@@ -3261,6 +3395,7 @@ def load_config(self):
3261
3395
self .checkbox_start_maximized .set_active (start_maximized )
3262
3396
self .checkbox_start_fullscreen .set_active (start_fullscreen )
3263
3397
self .checkbox_gamepad_navigation .set_active (gamepad_navigation )
3398
+ self .checkbox_enable_logging .set_active (enable_logging )
3264
3399
3265
3400
model = self .combo_box_interface .get_model ()
3266
3401
index_to_activate2 = 0
@@ -3273,7 +3408,7 @@ def load_config(self):
3273
3408
self .entry_api_key .set_text (self .api_key )
3274
3409
else :
3275
3410
# 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" )
3277
3412
3278
3413
3279
3414
class Game :
@@ -5442,9 +5577,9 @@ def load_config(self):
5442
5577
5443
5578
else :
5444
5579
# 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" )
5446
5581
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 ):
5448
5583
# Path to the configuration file
5449
5584
config_file = config_file_dir
5450
5585
@@ -5484,6 +5619,7 @@ def save_config(self, checkbox_state, default_prefix, mangohud_state, gamemode_s
5484
5619
config ['api-key' ] = entry_api_key
5485
5620
config ['start-fullscreen' ] = checkbox_start_fullscreen
5486
5621
config ['gamepad-navigation' ] = checkbox_gamepad_navigation
5622
+ config ['enable-logging' ] = checkbox_enable_logging
5487
5623
5488
5624
# Write configurations back to the file
5489
5625
with open (config_file , 'w' ) as f :
0 commit comments