Skip to content

Commit 602066f

Browse files
authored
Update main_window.py
1 parent 22b77c7 commit 602066f

File tree

1 file changed

+114
-177
lines changed

1 file changed

+114
-177
lines changed

main_window.py

Lines changed: 114 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -220,236 +220,172 @@ def setup_ui(self):
220220
dxvk_async_check.stateChanged.connect(self.update_settings)
221221
settings_layout.addWidget(dxvk_async_check, row, 0)
222222
row += 1
223-
prefix_label = QLabel("Prefixes Location:")
224-
prefix_value = QLabel(self.config_manager.prefixes_dir)
225-
prefix_value.setStyleSheet("color: #888888;")
226-
settings_layout.addWidget(prefix_label, row, 0)
227-
settings_layout.addWidget(prefix_value, row, 1)
228-
row += 1
229-
protons_label = QLabel("Protons Location:")
230-
protons_value = QLabel(self.config_manager.protons_dir)
231-
protons_value.setStyleSheet("color: #888888;")
232-
settings_layout.addWidget(protons_label, row, 0)
233-
settings_layout.addWidget(protons_value, row, 1)
234-
settings_layout.setRowStretch(row, 1)
235223
tabs.addTab(settings_widget, 'Settings')
236-
# About tab
237-
about_widget = QWidget()
238-
about_layout = QVBoxLayout(about_widget)
239-
about_text = QTextEdit()
240-
about_text.setReadOnly(True)
241-
about_text.setText("Hacker Launcher v1.0\nGitHub: https://github.com/HackerOS-Linux-System/Hacker-Mode\nA launcher for running games with Proton/Wine easily.")
242-
about_layout.addWidget(about_text)
243-
tabs.addTab(about_widget, 'About')
244224
layout.addWidget(tabs)
245225
self.setCentralWidget(central)
246226

247-
def switch_to_plasma(self):
248-
try:
249-
subprocess.run(['/usr/share/HackerOS/Scripts/Bin/revert_to_plasma.sh'], check=True)
250-
except Exception as e:
251-
QMessageBox.warning(self, 'Error', f'Failed to switch to Plasma: {str(e)}')
252-
253-
def shutdown_system(self):
254-
try:
255-
subprocess.run(['shutdown', '0'], check=True)
256-
except Exception as e:
257-
QMessageBox.warning(self, 'Error', f'Failed to shutdown: {str(e)}')
258-
259-
def reboot_system(self):
260-
try:
261-
subprocess.run(['reboot'], check=True)
262-
except Exception as e:
263-
QMessageBox.warning(self, 'Error', f'Failed to reboot: {str(e)}')
264-
265-
def log_out(self):
266-
try:
267-
subprocess.run(['qdbus', 'org.kde.ksmserver', '/KSMServer', 'org.kde.KSMServerInterface.logout', '0', '0', '0'], check=True)
268-
except Exception as e:
269-
QMessageBox.warning(self, 'Error', f'Failed to log out: {str(e)}')
270-
271-
def start_proton_loading(self):
272-
self.protons_table.setRowCount(0)
273-
self.proton_thread = LoadProtonsThread(self.proton_manager)
274-
self.proton_thread.protons_loaded.connect(self.load_protons)
275-
self.proton_thread.start()
276-
277227
def update_settings(self):
278228
sender = self.sender()
279-
obj_name = sender.objectName()
280-
if obj_name == 'theme_combo':
229+
if sender.objectName() == 'theme_combo':
281230
self.settings['theme'] = sender.currentText()
282-
elif obj_name == 'runner_combo':
231+
elif sender.objectName() == 'runner_combo':
283232
self.settings['default_runner'] = sender.currentText()
284-
elif obj_name == 'update_combo':
233+
elif sender.objectName() == 'update_combo':
285234
self.settings['auto_update'] = sender.currentText()
286-
elif obj_name == 'esync_check':
235+
elif sender.objectName() == 'esync_check':
287236
self.settings['enable_esync'] = sender.isChecked()
288-
elif obj_name == 'fsync_check':
237+
elif sender.objectName() == 'fsync_check':
289238
self.settings['enable_fsync'] = sender.isChecked()
290-
elif obj_name == 'dxvk_async_check':
239+
elif sender.objectName() == 'dxvk_async_check':
291240
self.settings['enable_dxvk_async'] = sender.isChecked()
292241
self.config_manager.save_settings(self.settings)
293242

294243
def load_games(self):
295-
self.games_list.setRowCount(0)
296244
self.games = self.config_manager.load_games()
297245
self.games_list.setRowCount(len(self.games))
298246
for i, game in enumerate(self.games):
299247
self.games_list.setItem(i, 0, QTableWidgetItem(game['name']))
300248
self.games_list.setItem(i, 1, QTableWidgetItem(game['runner']))
301249
self.games_list.setItem(i, 2, QTableWidgetItem(game.get('launch_options', '')))
302-
self.games_list.resizeColumnsToContents()
303250

304-
def load_protons(self, protons):
251+
def start_proton_loading(self):
252+
self.protons_table.clearContents()
305253
self.protons_table.setRowCount(0)
254+
thread = LoadProtonsThread(self.proton_manager)
255+
thread.protons_loaded.connect(self.load_protons)
256+
thread.start()
257+
258+
def load_protons(self, protons):
306259
self.protons_table.setRowCount(len(protons))
307-
for i, proton in enumerate(protons):
308-
self.protons_table.setItem(i, 0, QTableWidgetItem(proton['version']))
309-
self.protons_table.setItem(i, 1, QTableWidgetItem(proton['type']))
310-
self.protons_table.setItem(i, 2, QTableWidgetItem(proton['date']))
311-
self.protons_table.setItem(i, 3, QTableWidgetItem(proton['status']))
312-
self.protons_table.resizeColumnsToContents()
260+
for i, p in enumerate(protons):
261+
self.protons_table.setItem(i, 0, QTableWidgetItem(p['version']))
262+
self.protons_table.setItem(i, 1, QTableWidgetItem(p['type']))
263+
self.protons_table.setItem(i, 2, QTableWidgetItem(p['date']))
264+
self.protons_table.setItem(i, 3, QTableWidgetItem(p['status']))
265+
266+
def switch_to_plasma(self):
267+
try:
268+
subprocess.run(['startplasma-x11'], check=True)
269+
self.close()
270+
except Exception as e:
271+
QMessageBox.warning(self, 'Error', str(e))
272+
273+
def shutdown_system(self):
274+
subprocess.run(['systemctl', 'poweroff'])
275+
276+
def reboot_system(self):
277+
subprocess.run(['systemctl', 'reboot'])
278+
279+
def log_out(self):
280+
subprocess.run(['loginctl', 'terminate-user', os.getlogin()])
313281

314282
def add_game(self):
315283
add_dialog = QDialog(self)
316-
add_dialog.setWindowTitle("Add New Game")
317-
dlg_layout = QGridLayout()
318-
row = 0
319-
name_label = QLabel('Game Name:')
284+
add_dialog.setWindowTitle("Add Game")
285+
layout = QGridLayout()
286+
name_label = QLabel("Game Name:")
320287
name_edit = QLineEdit()
321-
name_edit.setPlaceholderText("Enter game name")
322-
dlg_layout.addWidget(name_label, row, 0)
323-
dlg_layout.addWidget(name_edit, row, 1, 1, 2)
324-
row += 1
325-
exe_label = QLabel('Executable / App ID:')
326-
exe_edit = QLineEdit()
327-
exe_edit.setPlaceholderText("Select game executable or enter Steam App ID")
328-
browse_btn = QPushButton(QIcon.fromTheme("folder"), 'Browse')
329-
browse_btn.clicked.connect(lambda: exe_edit.setText(QFileDialog.getOpenFileName(self, 'Select Executable', '/', 'Executables (*.exe *.bat);;All Files (*)')[0]))
330-
dlg_layout.addWidget(exe_label, row, 0)
331-
dlg_layout.addWidget(exe_edit, row, 1)
332-
dlg_layout.addWidget(browse_btn, row, 2)
333-
row += 1
334-
runner_label = QLabel('Runner:')
288+
layout.addWidget(name_label, 0, 0)
289+
layout.addWidget(name_edit, 0, 1)
290+
runner_label = QLabel("Runner:")
335291
runner_combo = QComboBox()
336292
runner_combo.addItems(['Native', 'Wine', 'Proton', 'Flatpak', 'Steam'])
337293
runner_combo.setCurrentText(self.settings['default_runner'])
338-
dlg_layout.addWidget(runner_label, row, 0)
339-
dlg_layout.addWidget(runner_combo, row, 1, 1, 2)
340-
row += 1
341-
proton_label = QLabel('Proton Version:')
342-
proton_combo = QComboBox()
343-
proton_combo.addItems([p['version'] for p in self.proton_manager.get_installed_protons()])
344-
proton_widget = QWidget()
345-
proton_layout = QHBoxLayout()
346-
proton_layout.addWidget(proton_label)
347-
proton_layout.addWidget(proton_combo)
348-
proton_widget.setLayout(proton_layout)
349-
proton_widget.setVisible(runner_combo.currentText() == 'Proton')
350-
dlg_layout.addWidget(proton_widget, row, 0, 1, 3)
351-
row += 1
352-
prefix_label = QLabel('Wine/Proton Prefix:')
294+
layout.addWidget(runner_label, 1, 0)
295+
layout.addWidget(runner_combo, 1, 1)
296+
exe_label = QLabel("Executable/App ID:")
297+
exe_edit = QLineEdit()
298+
browse_btn = QPushButton(QIcon.fromTheme("folder"), 'Browse')
299+
exe_hbox = QHBoxLayout()
300+
exe_hbox.addWidget(exe_edit)
301+
exe_hbox.addWidget(browse_btn)
302+
layout.addWidget(exe_label, 2, 0)
303+
layout.addLayout(exe_hbox, 2, 1)
304+
prefix_label = QLabel("Prefix:")
353305
prefix_edit = QLineEdit()
354-
prefix_edit.setPlaceholderText("Select or enter prefix path")
355-
prefix_browse_btn = QPushButton(QIcon.fromTheme("folder"), 'Browse')
356-
prefix_browse_btn.clicked.connect(lambda: prefix_edit.setText(QFileDialog.getExistingDirectory(self, 'Select Prefix Directory')))
357-
prefix_widget = QWidget()
358-
prefix_layout = QHBoxLayout()
359-
prefix_layout.addWidget(prefix_label)
360-
prefix_layout.addWidget(prefix_edit)
361-
prefix_layout.addWidget(prefix_browse_btn)
362-
prefix_widget.setLayout(prefix_layout)
363-
prefix_widget.setVisible(runner_combo.currentText() in ['Wine', 'Proton'])
364-
dlg_layout.addWidget(prefix_widget, row, 0, 1, 3)
365-
row += 1
366-
launch_label = QLabel('Launch Options:')
367-
launch_edit = QLineEdit()
368-
launch_edit.setPlaceholderText("e.g., --fullscreen --bigpicture --gamescope --adaptive-sync --width=1920 --height=1080")
369-
dlg_layout.addWidget(launch_label, row, 0)
370-
dlg_layout.addWidget(launch_edit, row, 1, 1, 2)
371-
row += 1
372-
dxvk_check = QCheckBox("Enable DXVK/VKD3D")
373-
dxvk_check.setVisible(runner_combo.currentText() in ['Wine', 'Proton'])
374-
dlg_layout.addWidget(dxvk_check, row, 0)
375-
row += 1
376-
esync_check = QCheckBox("Enable Esync (Override)")
377-
esync_check.setVisible(runner_combo.currentText() in ['Wine', 'Proton'])
378-
dlg_layout.addWidget(esync_check, row, 0)
379-
row += 1
380-
fsync_check = QCheckBox("Enable Fsync (Override)")
381-
fsync_check.setVisible(runner_combo.currentText() in ['Wine', 'Proton'])
382-
dlg_layout.addWidget(fsync_check, row, 0)
383-
row += 1
384-
dxvk_async_check = QCheckBox("Enable DXVK Async (Override)")
385-
dxvk_async_check.setVisible(runner_combo.currentText() in ['Wine', 'Proton'])
386-
dlg_layout.addWidget(dxvk_async_check, row, 0)
387-
row += 1
388-
app_id_widget = QWidget()
389-
app_id_layout = QHBoxLayout()
390-
app_id_label = QLabel('Steam App ID:')
391-
app_id_edit = QLineEdit()
392-
app_id_layout.addWidget(app_id_label)
393-
app_id_layout.addWidget(app_id_edit)
394-
app_id_widget.setLayout(app_id_layout)
395-
app_id_widget.setVisible(runner_combo.currentText() == 'Steam')
396-
dlg_layout.addWidget(app_id_widget, row, 0, 1, 3)
397-
row += 1
398-
def update_visibility(text):
399-
proton_widget.setVisible(text == 'Proton')
400-
prefix_widget.setVisible(text in ['Wine', 'Proton'])
401-
app_id_widget.setVisible(text == 'Steam')
402-
browse_btn.setVisible(text != 'Steam')
403-
dxvk_check.setVisible(text in ['Wine', 'Proton'])
404-
esync_check.setVisible(text in ['Wine', 'Proton'])
405-
fsync_check.setVisible(text in ['Wine', 'Proton'])
406-
dxvk_async_check.setVisible(text in ['Wine', 'Proton'])
407-
runner_combo.currentTextChanged.connect(update_visibility)
306+
prefix_browse = QPushButton(QIcon.fromTheme("folder"), 'Browse')
307+
prefix_hbox = QHBoxLayout()
308+
prefix_hbox.addWidget(prefix_edit)
309+
prefix_hbox.addWidget(prefix_browse)
310+
layout.addWidget(prefix_label, 3, 0)
311+
layout.addLayout(prefix_hbox, 3, 1)
312+
options_label = QLabel("Launch Options:")
313+
options_edit = QLineEdit()
314+
layout.addWidget(options_label, 4, 0)
315+
layout.addWidget(options_edit, 4, 1)
316+
esync_check = QCheckBox("Enable Esync")
317+
esync_check.setChecked(self.settings['enable_esync'])
318+
layout.addWidget(esync_check, 5, 0)
319+
fsync_check = QCheckBox("Enable Fsync")
320+
fsync_check.setChecked(self.settings['enable_fsync'])
321+
layout.addWidget(fsync_check, 6, 0)
322+
dxvk_check = QCheckBox("Enable DXVK")
323+
layout.addWidget(dxvk_check, 7, 0)
324+
dxvk_async_check = QCheckBox("Enable DXVK Async")
325+
dxvk_async_check.setChecked(self.settings['enable_dxvk_async'])
326+
layout.addWidget(dxvk_async_check, 8, 0)
327+
def update_ui(text):
328+
is_steam = text == 'Steam'
329+
is_proton_wine = text in ['Proton', 'Wine']
330+
exe_label.setText("App ID:" if is_steam else "Executable:")
331+
prefix_label.setVisible(is_proton_wine)
332+
prefix_edit.setVisible(is_proton_wine)
333+
prefix_browse.setVisible(is_proton_wine)
334+
esync_check.setVisible(is_proton_wine)
335+
fsync_check.setVisible(is_proton_wine)
336+
dxvk_check.setVisible(is_proton_wine)
337+
dxvk_async_check.setVisible(is_proton_wine)
338+
runner_combo.currentTextChanged.connect(update_ui)
339+
update_ui(runner_combo.currentText())
340+
def browse_exe():
341+
if runner_combo.currentText() != 'Steam':
342+
path = QFileDialog.getOpenFileName(self, 'Select Executable', '', 'Executables (*.exe *.bin *.sh);;All Files (*)')[0]
343+
if path:
344+
exe_edit.setText(path)
345+
browse_btn.clicked.connect(browse_exe)
346+
def browse_prefix():
347+
path = QFileDialog.getExistingDirectory(self, 'Select Prefix Folder')
348+
if path:
349+
prefix_edit.setText(path)
350+
prefix_browse.clicked.connect(browse_prefix)
408351
button_layout = QHBoxLayout()
409-
ok_btn = QPushButton(QIcon.fromTheme("dialog-ok"), 'Add Game')
352+
ok_btn = QPushButton(QIcon.fromTheme("dialog-ok"), 'Add')
410353
cancel_btn = QPushButton(QIcon.fromTheme("dialog-cancel"), 'Cancel')
411354
ok_btn.clicked.connect(add_dialog.accept)
412355
cancel_btn.clicked.connect(add_dialog.reject)
413356
button_layout.addStretch()
414357
button_layout.addWidget(ok_btn)
415358
button_layout.addWidget(cancel_btn)
416-
dlg_layout.addLayout(button_layout, row, 0, 1, 3)
417-
add_dialog.setLayout(dlg_layout)
418-
add_dialog.resize(600, 400)
359+
layout.addLayout(button_layout, 9, 0, 1, 2)
360+
add_dialog.setLayout(layout)
361+
add_dialog.resize(500, 400)
419362
if add_dialog.exec() == QDialog.Accepted:
420363
name = name_edit.text()
421-
exe = exe_edit.text()
422364
runner = runner_combo.currentText()
423-
launch_options = launch_edit.text()
424-
enable_dxvk = dxvk_check.isChecked()
365+
exe_or_id = exe_edit.text()
366+
prefix = prefix_edit.text() if runner in ['Wine', 'Proton'] else ''
367+
options = options_edit.text()
425368
enable_esync = esync_check.isChecked()
426369
enable_fsync = fsync_check.isChecked()
370+
enable_dxvk = dxvk_check.isChecked()
427371
enable_dxvk_async = dxvk_async_check.isChecked()
428-
app_id = app_id_edit.text() if runner == 'Steam' else ''
429-
prefix = prefix_edit.text() if runner in ['Wine', 'Proton'] else ''
430-
if runner == 'Proton':
431-
runner = proton_combo.currentText()
432-
if not name or (runner != 'Steam' and not exe) or (runner == 'Steam' and not app_id):
372+
if not name or not exe_or_id:
433373
QMessageBox.warning(self, 'Error', 'Name and Executable/App ID required')
434374
return
435-
if runner in ['Wine', 'Proton'] and not prefix:
436-
prefix = os.path.join(self.config_manager.prefixes_dir, name.replace(' ', '_'))
437-
if prefix:
438-
os.makedirs(prefix, exist_ok=True)
439-
if os.name == 'posix' and ':' in exe:
440-
exe = exe.replace('\\', '/').replace('C:', '/drive_c')
441375
game = {
442376
'name': name,
443-
'exe': exe,
444377
'runner': runner,
445378
'prefix': prefix,
446-
'launch_options': launch_options,
447-
'enable_dxvk': enable_dxvk,
379+
'launch_options': options,
448380
'enable_esync': enable_esync,
449381
'enable_fsync': enable_fsync,
450-
'enable_dxvk_async': enable_dxvk_async,
451-
'app_id': app_id
382+
'enable_dxvk': enable_dxvk,
383+
'enable_dxvk_async': enable_dxvk_async
452384
}
385+
if runner == 'Steam':
386+
game['app_id'] = exe_or_id
387+
else:
388+
game['exe'] = exe_or_id
453389
self.game_manager.add_game(game)
454390
self.load_games()
455391
QMessageBox.information(self, 'Success', 'Game added successfully!')
@@ -463,7 +399,8 @@ def launch_game(self):
463399
game = next((g for g in self.games if g['name'] == name), None)
464400
if game:
465401
try:
466-
self.game_manager.launch_game(game, '--gamescope' in game.get('launch_options', ''))
402+
gamescope = '--gamescope' in game.get('launch_options', '').split()
403+
self.game_manager.launch_game(game, gamescope)
467404
except Exception as e:
468405
logging.error(f"Error launching {name}: {e}")
469406
print(f"Error launching {name}: {e}")

0 commit comments

Comments
 (0)