diff --git a/bin/omarchy-power-menu b/bin/omarchy-power-menu index 6c8d6a7..b9989e4 100755 --- a/bin/omarchy-power-menu +++ b/bin/omarchy-power-menu @@ -15,7 +15,7 @@ show_power_menu() { case "$selection" in *Lock*) hyprlock ;; *Suspend*) systemctl suspend ;; - *Relaunch*) hyprctl dispatch exit ;; + *Relaunch*) uwsm stop ;; *Restart*) systemctl reboot ;; *Shutdown*) systemctl poweroff ;; esac diff --git a/config/environment.d/fcitx.conf b/config/environment.d/fcitx.conf index fbb5e69..ecedbcc 100644 --- a/config/environment.d/fcitx.conf +++ b/config/environment.d/fcitx.conf @@ -1,5 +1,4 @@ INPUT_METHOD=fcitx -GTK_IM_MODULE=fcitx QT_IM_MODULE=fcitx XMODIFIERS=@im=fcitx SDL_IM_MODULE=fcitx diff --git a/default/plymouth/omarchy.script b/default/plymouth/omarchy.script index 07b2cd0..663f4f5 100644 --- a/default/plymouth/omarchy.script +++ b/default/plymouth/omarchy.script @@ -20,6 +20,7 @@ global.fake_progress_active = 0; # 0 / 1 boolean global.animation_frame = 0; global.fake_progress_start_time = 0; # Track when fake progress started global.password_shown = 0; # Track if password dialog has been shown +global.max_progress = 0.0; # Track the maximum progress reached to prevent backwards movement fun refresh_callback () { @@ -55,11 +56,16 @@ Plymouth.SetRefreshFunction (refresh_callback); fun update_progress_bar(progress) { - width = Math.Int(progress_bar.original_image.GetWidth() * progress); - if (width < 1) width = 1; # Ensure minimum width of 1 pixel - - progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight()); - progress_bar.sprite.SetImage(progress_bar.image); + # Only update if progress is moving forward + if (progress > global.max_progress) + { + global.max_progress = progress; + width = Math.Int(progress_bar.original_image.GetWidth() * progress); + if (width < 1) width = 1; # Ensure minimum width of 1 pixel + + progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight()); + progress_bar.sprite.SetImage(progress_bar.image); + } } fun show_progress_bar() @@ -90,11 +96,15 @@ fun hide_password_dialog() fun start_fake_progress() { - global.fake_progress = 0.0; - global.real_progress = 0.0; + # Don't reset if we already have progress + if (global.max_progress == 0.0) + { + global.fake_progress = 0.0; + global.real_progress = 0.0; + update_progress_bar(0.0); + } global.fake_progress_active = 1; global.animation_frame = 0; - update_progress_bar(0.0); } fun stop_fake_progress() @@ -149,8 +159,12 @@ fun display_password_callback (prompt, bullets) { global.password_shown = 1; # Mark that password dialog has been shown + # Reset progress when password dialog appears stop_fake_progress(); hide_progress_bar(); + global.max_progress = 0.0; + global.fake_progress = 0.0; + global.real_progress = 0.0; show_password_dialog(); # Clear all bullets first diff --git a/install/4-config.sh b/install/4-config.sh index 8314790..69adf77 100644 --- a/install/4-config.sh +++ b/install/4-config.sh @@ -7,14 +7,6 @@ mkdir -p ~/.local/share/applications # Use default bashrc from Omarchy echo "source ~/.local/share/omarchy/default/bash/rc" >~/.bashrc -# Login directly as user, rely on disk encryption + hyprlock for security -sudo mkdir -p /etc/systemd/system/getty@tty1.service.d -sudo tee /etc/systemd/system/getty@tty1.service.d/override.conf >/dev/null <~/.bash_profile diff --git a/install/login.sh b/install/login.sh new file mode 100644 index 0000000..48ac5c4 --- /dev/null +++ b/install/login.sh @@ -0,0 +1,115 @@ +#!/bin/bash +# Hyprland launched via UWSM and login directly as user, rely on disk encryption + hyprlock for security +yay -S --noconfirm --needed uwsm + +# Compile the seamless login helper -- needed to prevent seeing terminal between loader and desktop +cat <<'CCODE' >/tmp/seamless-login.c +/* + * Seamless Login - Minimal SDDM-style Plymouth transition + * Replicates SDDM's VT management for seamless auto-login + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + int vt_fd; + int vt_num = 1; // TTY1 + char vt_path[32]; + + if (argc < 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + // Open the VT (simple approach like SDDM) + snprintf(vt_path, sizeof(vt_path), "/dev/tty%d", vt_num); + vt_fd = open(vt_path, O_RDWR); + if (vt_fd < 0) { + perror("Failed to open VT"); + return 1; + } + + // Activate the VT + if (ioctl(vt_fd, VT_ACTIVATE, vt_num) < 0) { + perror("VT_ACTIVATE failed"); + close(vt_fd); + return 1; + } + + // Wait for VT to be active + if (ioctl(vt_fd, VT_WAITACTIVE, vt_num) < 0) { + perror("VT_WAITACTIVE failed"); + close(vt_fd); + return 1; + } + + // Critical: Set graphics mode to prevent console text + if (ioctl(vt_fd, KDSETMODE, KD_GRAPHICS) < 0) { + perror("KDSETMODE KD_GRAPHICS failed"); + close(vt_fd); + return 1; + } + + // Clear VT and close (like SDDM does) + const char *clear_seq = "\33[H\33[2J"; + if (write(vt_fd, clear_seq, strlen(clear_seq)) < 0) { + perror("Failed to clear VT"); + } + + close(vt_fd); + + // Set working directory to user's home + const char *home = getenv("HOME"); + if (home) chdir(home); + + // Now execute the session command + execvp(argv[1], &argv[1]); + perror("Failed to exec session"); + return 1; +} +CCODE + +gcc -o /tmp/seamless-login /tmp/seamless-login.c +sudo mv /tmp/seamless-login /usr/local/bin/seamless-login +sudo chmod +x /usr/local/bin/seamless-login +rm /tmp/seamless-login.c + +cat </dev/null; then # Relying on mkinitcpio to assemble a UKI # https://wiki.archlinux.org/title/Unified_kernel_image if ! grep -q splash /etc/cmdline.d/*.conf; then - # Need splash, create the omarchy file - echo "splash" | sudo tee -a /etc/cmdline.d/omarchy.conf + # Need splash, create the omarchy file + echo "splash" | sudo tee -a /etc/cmdline.d/omarchy.conf fi if ! grep -q quiet /etc/cmdline.d/*.conf; then - # Need quiet, create or append the omarchy file - echo "quiet" | sudo tee -a /etc/cmdline.d/omarchy.conf + # Need quiet, create or append the omarchy file + echo "quiet" | sudo tee -a /etc/cmdline.d/omarchy.conf fi elif [ -f "/etc/kernel/cmdline" ]; then # Alternate UKI kernel cmdline location @@ -95,10 +95,10 @@ if ! command -v plymouth &>/dev/null; then # Add splash and quiet if not present new_cmdline="$current_cmdline" if [[ ! "$current_cmdline" =~ splash ]]; then - new_cmdline="$new_cmdline splash" + new_cmdline="$new_cmdline splash" fi if [[ ! "$current_cmdline" =~ quiet ]]; then - new_cmdline="$new_cmdline quiet" + new_cmdline="$new_cmdline quiet" fi # Trim any leading/trailing spaces diff --git a/migrations/1752292967.sh b/migrations/1752292967.sh new file mode 100644 index 0000000..293d74a --- /dev/null +++ b/migrations/1752292967.sh @@ -0,0 +1,18 @@ +echo "Update to use UWSM and seamless login" +sudo rm /etc/systemd/system/getty@tty1.service.d/override.conf +sudo rmdir /etc/systemd/system/getty@tty1.service.d/ 2>/dev/null || true + +if [ -f "$HOME/.bash_profile" ]; then + # Remove the specific line + sed -i '/^\[\[ -z \$DISPLAY && \$(tty) == \/dev\/tty1 \]\] && exec Hyprland$/d' "$HOME/.bash_profile" + echo "Cleaned up .bash_profile" +fi + +if [ -f "$HOME/.config/environment.d/fcitx.conf" ]; then + echo "Removing GTK_IM_MODULE from fcitx config for Wayland..." + sed -i 's/^GTK_IM_MODULE=fcitx$//' "$HOME/.config/environment.d/fcitx.conf" +fi + +omarchy-refresh-plymouth + +source ~/.local/share/omarchy/install/login.sh