|
4 | 4 | import QtQuick |
5 | 5 | import QtQuick.Layouts |
6 | 6 | import QtQuick.Controls |
| 7 | +import QtQuick.Window |
7 | 8 | import Quickshell |
8 | | -import Quickshell.Wayland |
9 | 9 | import Quickshell.Io |
10 | 10 |
|
11 | 11 | ShellRoot { |
12 | 12 | id: root |
13 | 13 |
|
14 | | - // Welcome wizard runs on all screens, full screen |
15 | | - Variants { |
16 | | - model: Quickshell.screens |
17 | | - |
18 | | - delegate: Component { |
19 | | - PanelWindow { |
20 | | - id: welcomeWindow |
21 | | - required property var modelData |
22 | | - property var screen: modelData |
23 | | - |
24 | | - anchors.fill: true |
25 | | - color: "#1a1b26" // Tokyonight background |
26 | | - |
27 | | - // Only show wizard on primary screen |
28 | | - property bool isPrimary: screen === Quickshell.screens[0] |
29 | | - |
30 | | - // Background for non-primary screens |
31 | | - Rectangle { |
32 | | - anchors.fill: parent |
33 | | - visible: !isPrimary |
34 | | - color: "#1a1b26" |
35 | | - |
36 | | - Text { |
37 | | - anchors.centerIn: parent |
38 | | - text: "Hypercube" |
39 | | - font.pixelSize: 48 |
40 | | - font.weight: Font.Medium |
41 | | - color: "#7aa2f7" |
42 | | - opacity: 0.3 |
43 | | - } |
44 | | - } |
45 | | - |
46 | | - // Wizard on primary screen |
47 | | - Loader { |
48 | | - anchors.fill: parent |
49 | | - active: isPrimary |
50 | | - sourceComponent: WelcomeWizard {} |
51 | | - } |
52 | | - } |
| 14 | + // Simple fullscreen window for cage compositor |
| 15 | + Window { |
| 16 | + id: welcomeWindow |
| 17 | + visible: true |
| 18 | + visibility: Window.FullScreen |
| 19 | + color: "#1a1b26" // Tokyonight background |
| 20 | + title: "Hypercube Setup" |
| 21 | + |
| 22 | + // Wizard content |
| 23 | + WelcomeWizard { |
| 24 | + anchors.fill: parent |
53 | 25 | } |
54 | 26 | } |
55 | 27 |
|
@@ -662,29 +634,51 @@ ShellRoot { |
662 | 634 | } |
663 | 635 | } |
664 | 636 |
|
| 637 | + property bool isCreating: false |
| 638 | + |
665 | 639 | function createUser() { |
| 640 | + if (isCreating) return |
| 641 | + isCreating = true |
666 | 642 | errorMessage = "" |
667 | 643 | userCreateProcess.running = true |
668 | 644 | } |
669 | 645 |
|
| 646 | + // Escape single quotes in strings for shell safety |
| 647 | + function shellEscape(str: string): string { |
| 648 | + return str.replace(/'/g, "'\\''") |
| 649 | + } |
| 650 | + |
670 | 651 | Process { |
671 | 652 | id: userCreateProcess |
| 653 | + // Runs as root via greetd initial_session |
672 | 654 | command: ["sh", "-c", |
673 | | - "useradd -m -G wheel -c '" + (fullName || username) + "' '" + username + "' && " + |
674 | | - "echo '" + username + ":" + password + "' | chpasswd && " + |
| 655 | + "useradd -m -G wheel -c '" + shellEscape(fullName || username) + "' '" + shellEscape(username) + "' && " + |
| 656 | + "echo '" + shellEscape(username) + ":" + shellEscape(password) + "' | chpasswd && " + |
675 | 657 | // Save theme config for the new user |
676 | | - "mkdir -p /home/" + username + "/.config/hypercube && " + |
677 | | - "echo '{\"appearance\":{\"darkMode\":" + (selectedDarkMode ? "true" : "false") + ",\"accentColor\":\"" + selectedAccent + "\"}}' > /home/" + username + "/.config/hypercube/shell.json && " + |
678 | | - "chown -R " + username + ":" + username + " /home/" + username + "/.config" |
| 658 | + "mkdir -p '/home/" + shellEscape(username) + "/.config/hypercube' && " + |
| 659 | + "echo '{\"appearance\":{\"darkMode\":" + (selectedDarkMode ? "true" : "false") + ",\"accentColor\":\"" + selectedAccent + "\"}}' > '/home/" + shellEscape(username) + "/.config/hypercube/shell.json' && " + |
| 660 | + "chown -R '" + shellEscape(username) + "':'" + shellEscape(username) + "' '/home/" + shellEscape(username) + "/.config'" |
679 | 661 | ] |
680 | 662 |
|
681 | 663 | running: false |
682 | | - onExited: { |
683 | | - if (exitCode === 0) { |
684 | | - // Exit quickshell, which will cause Hyprland to exit |
| 664 | + onExited: (code, status) => { |
| 665 | + isCreating = false |
| 666 | + if (code === 0) { |
| 667 | + // Success - exit quickshell to return to greetd |
685 | 668 | Qt.quit() |
686 | 669 | } else { |
687 | | - errorMessage = "Failed to create user. Exit code: " + exitCode |
| 670 | + errorMessage = "Failed to create user (error " + code + "). Please try again." |
| 671 | + } |
| 672 | + } |
| 673 | + } |
| 674 | + |
| 675 | + // Allow exiting with Escape key |
| 676 | + Shortcut { |
| 677 | + sequence: "Escape" |
| 678 | + onActivated: { |
| 679 | + if (!isCreating) { |
| 680 | + // Exit without creating user - greetd will show regreet |
| 681 | + Qt.quit() |
688 | 682 | } |
689 | 683 | } |
690 | 684 | } |
|
0 commit comments