detached 8713086

assets(plymouth): add ArchUp Plymouth theme with custom branding

commit
87130867304f43616223edc94a897c07cfe6d872
author
bnema · · 2025-10-20 18:45 UTC
parent
5974a44
signature
unsigned
8 files · +268 -0
A assets/plymouth/archup.plymouth +11 -0
@@ -0,0 +1,11 @@
1+[Plymouth Theme]
2+Name=ArchUp
3+Description=ArchUp splash screen.
4+ModuleName=script
5+
6+[script]
7+ImageDir=/usr/share/plymouth/themes/archup
8+ScriptFile=/usr/share/plymouth/themes/archup/archup.script
9+ConsoleLogBackgroundColor=0x1a1b26
10+MonospaceFont=Fira Sans 11
11+Font=Fira Sans 11
@@ -0,0 +1,11 @@
1+[Plymouth Theme]
2+Name=ArchUp
3+Description=ArchUp splash screen.
4+ModuleName=script
5+
6+[script]
7+ImageDir=/usr/share/plymouth/themes/archup
8+ScriptFile=/usr/share/plymouth/themes/archup/archup.script
9+ConsoleLogBackgroundColor=0x1a1b26
10+MonospaceFont=Fira Sans 11
11+Font=Fira Sans 11
A assets/plymouth/archup.script +257 -0
@@ -0,0 +1,257 @@
1+# Omarchy Plymouth Theme Script
2+
3+Window.SetBackgroundTopColor(0.101, 0.105, 0.149);
4+Window.SetBackgroundBottomColor(0.101, 0.105, 0.149);
5+
6+logo.image = Image("logo.png");
7+logo.sprite = Sprite(logo.image);
8+logo.sprite.SetX (Window.GetWidth() / 2 - logo.image.GetWidth() / 2);
9+logo.sprite.SetY (Window.GetHeight() / 2 - logo.image.GetHeight() / 2);
10+logo.sprite.SetOpacity (1);
11+
12+# Use these to adjust the progress bar timing
13+global.fake_progress_limit = 0.7; # Target percentage for fake progress (0.0 to 1.0)
14+global.fake_progress_duration = 15.0; # Duration in seconds to reach limit
15+
16+# Progress bar animation variables
17+global.fake_progress = 0.0;
18+global.real_progress = 0.0;
19+global.fake_progress_active = 0; # 0 / 1 boolean
20+global.animation_frame = 0;
21+global.fake_progress_start_time = 0; # Track when fake progress started
22+global.password_shown = 0; # Track if password dialog has been shown
23+global.max_progress = 0.0; # Track the maximum progress reached to prevent backwards movement
24+
25+fun refresh_callback ()
26+ {
27+ global.animation_frame++;
28+
29+ # Animate fake progress to limit over time with easing
30+ if (global.fake_progress_active == 1)
31+ {
32+ # Calculate elapsed time since start
33+ elapsed_time = global.animation_frame / 50.0; # Convert frames to seconds (50 FPS)
34+
35+ # Calculate linear progress ratio (0 to 1) based on time
36+ time_ratio = elapsed_time / global.fake_progress_duration;
37+ if (time_ratio > 1.0)
38+ time_ratio = 1.0;
39+
40+ # Apply easing curve: ease-out quadratic
41+ # Formula: 1 - (1 - x)^2
42+ eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio));
43+
44+ # Calculate fake progress based on eased ratio
45+ global.fake_progress = eased_ratio * global.fake_progress_limit;
46+
47+ # Update progress bar with fake progress
48+ update_progress_bar(global.fake_progress);
49+ }
50+ }
51+
52+
53+Plymouth.SetRefreshFunction (refresh_callback);
54+
55+#----------------------------------------- Helper Functions --------------------------------
56+
57+fun update_progress_bar(progress)
58+ {
59+ # Only update if progress is moving forward
60+ if (progress > global.max_progress)
61+ {
62+ global.max_progress = progress;
63+ width = Math.Int(progress_bar.original_image.GetWidth() * progress);
64+ if (width < 1) width = 1; # Ensure minimum width of 1 pixel
65+
66+ progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight());
67+ progress_bar.sprite.SetImage(progress_bar.image);
68+ }
69+ }
70+
71+fun show_progress_bar()
72+ {
73+ progress_box.sprite.SetOpacity(1);
74+ progress_bar.sprite.SetOpacity(1);
75+ }
76+
77+fun hide_progress_bar()
78+ {
79+ progress_box.sprite.SetOpacity(0);
80+ progress_bar.sprite.SetOpacity(0);
81+ }
82+
83+fun show_password_dialog()
84+ {
85+ lock.sprite.SetOpacity(1);
86+ entry.sprite.SetOpacity(1);
87+ }
88+
89+fun hide_password_dialog()
90+ {
91+ lock.sprite.SetOpacity(0);
92+ entry.sprite.SetOpacity(0);
93+ for (index = 0; bullet.sprites[index]; index++)
94+ bullet.sprites[index].SetOpacity(0);
95+ }
96+
97+fun start_fake_progress()
98+ {
99+ # Don't reset if we already have progress
100+ if (global.max_progress == 0.0)
101+ {
102+ global.fake_progress = 0.0;
103+ global.real_progress = 0.0;
104+ update_progress_bar(0.0);
105+ }
106+ global.fake_progress_active = 1;
107+ global.animation_frame = 0;
108+ }
109+
110+fun stop_fake_progress()
111+ {
112+ global.fake_progress_active = 0;
113+ }
114+
115+#----------------------------------------- Dialogue --------------------------------
116+
117+lock.image = Image("lock.png");
118+entry.image = Image("entry.png");
119+bullet.image = Image("bullet.png");
120+
121+entry.sprite = Sprite(entry.image);
122+entry.x = Window.GetWidth()/2 - entry.image.GetWidth() / 2;
123+entry.y = logo.sprite.GetY() + logo.image.GetHeight() + 40;
124+entry.sprite.SetPosition(entry.x, entry.y, 10001);
125+entry.sprite.SetOpacity(0);
126+
127+# Scale lock to be slightly shorter than entry field height
128+# Original lock is 84x96, entry height determines scale
129+lock_height = entry.image.GetHeight() * 0.8;
130+lock_scale = lock_height / 96;
131+lock_width = 84 * lock_scale;
132+
133+scaled_lock = lock.image.Scale(lock_width, lock_height);
134+lock.sprite = Sprite(scaled_lock);
135+lock.x = entry.x - lock_width - 15;
136+lock.y = entry.y + entry.image.GetHeight()/2 - lock_height/2;
137+lock.sprite.SetPosition(lock.x, lock.y, 10001);
138+lock.sprite.SetOpacity(0);
139+
140+# Bullet array
141+bullet.sprites = [];
142+
143+fun display_normal_callback ()
144+ {
145+ hide_password_dialog();
146+
147+ # Get current mode
148+ mode = Plymouth.GetMode();
149+
150+ # Only show progress bar for boot and resume modes
151+ if ((mode == "boot" || mode == "resume") && global.password_shown == 1)
152+ {
153+ show_progress_bar();
154+ start_fake_progress();
155+ }
156+ }
157+
158+fun display_password_callback (prompt, bullets)
159+ {
160+ global.password_shown = 1; # Mark that password dialog has been shown
161+
162+ # Reset progress when password dialog appears
163+ stop_fake_progress();
164+ hide_progress_bar();
165+ global.max_progress = 0.0;
166+ global.fake_progress = 0.0;
167+ global.real_progress = 0.0;
168+ show_password_dialog();
169+
170+ # Clear all bullets first
171+ for (index = 0; bullet.sprites[index]; index++)
172+ bullet.sprites[index].SetOpacity(0);
173+
174+ # Create and show bullets for current password (max 21)
175+ max_bullets = 21;
176+ bullets_to_show = bullets;
177+ if (bullets_to_show > max_bullets)
178+ bullets_to_show = max_bullets;
179+
180+ for (index = 0; index < bullets_to_show; index++)
181+ {
182+ if (!bullet.sprites[index])
183+ {
184+ # Scale bullet image to 7x7 pixels
185+ scaled_bullet = bullet.image.Scale(7, 7);
186+ bullet.sprites[index] = Sprite(scaled_bullet);
187+ bullet.x = entry.x + 20 + index * (7 + 5);
188+ bullet.y = entry.y + entry.image.GetHeight() / 2 - 3.5;
189+ bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002);
190+ }
191+ bullet.sprites[index].SetOpacity(1);
192+ }
193+ }
194+
195+Plymouth.SetDisplayNormalFunction(display_normal_callback);
196+Plymouth.SetDisplayPasswordFunction(display_password_callback);
197+
198+#----------------------------------------- Progress Bar --------------------------------
199+
200+progress_box.image = Image("progress_box.png");
201+progress_box.sprite = Sprite(progress_box.image);
202+
203+progress_box.x = Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
204+progress_box.y = entry.y + entry.image.GetHeight() / 2 - progress_box.image.GetHeight() / 2;
205+progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);
206+progress_box.sprite.SetOpacity(0);
207+
208+progress_bar.original_image = Image("progress_bar.png");
209+progress_bar.sprite = Sprite();
210+progress_bar.image = progress_bar.original_image.Scale(1, progress_bar.original_image.GetHeight());
211+
212+progress_bar.x = Window.GetWidth() / 2 - progress_bar.original_image.GetWidth() / 2;
213+progress_bar.y = progress_box.y + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
214+progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);
215+progress_bar.sprite.SetOpacity(0);
216+
217+fun progress_callback (duration, progress)
218+ {
219+ global.real_progress = progress;
220+
221+ # If real progress is above limit, stop fake progress and use real progress
222+ if (progress > global.fake_progress_limit)
223+ {
224+ stop_fake_progress();
225+ update_progress_bar(progress);
226+ }
227+ }
228+
229+Plymouth.SetBootProgressFunction(progress_callback);
230+
231+#----------------------------------------- Quit --------------------------------
232+
233+fun quit_callback ()
234+{
235+ logo.sprite.SetOpacity (1);
236+}
237+
238+Plymouth.SetQuitFunction(quit_callback);
239+
240+#----------------------------------------- Message --------------------------------
241+
242+message_sprite = Sprite();
243+message_sprite.SetPosition(10, 10, 10000);
244+
245+fun display_message_callback (text)
246+{
247+ my_image = Image.Text(text, 1, 1, 1);
248+ message_sprite.SetImage(my_image);
249+}
250+
251+fun hide_message_callback (text)
252+{
253+ message_sprite.SetOpacity(0);
254+}
255+
256+Plymouth.SetDisplayMessageFunction (display_message_callback);
257+Plymouth.SetHideMessageFunction (hide_message_callback);
@@ -0,0 +1,257 @@
1+# Omarchy Plymouth Theme Script
2+
3+Window.SetBackgroundTopColor(0.101, 0.105, 0.149);
4+Window.SetBackgroundBottomColor(0.101, 0.105, 0.149);
5+
6+logo.image = Image("logo.png");
7+logo.sprite = Sprite(logo.image);
8+logo.sprite.SetX (Window.GetWidth() / 2 - logo.image.GetWidth() / 2);
9+logo.sprite.SetY (Window.GetHeight() / 2 - logo.image.GetHeight() / 2);
10+logo.sprite.SetOpacity (1);
11+
12+# Use these to adjust the progress bar timing
13+global.fake_progress_limit = 0.7; # Target percentage for fake progress (0.0 to 1.0)
14+global.fake_progress_duration = 15.0; # Duration in seconds to reach limit
15+
16+# Progress bar animation variables
17+global.fake_progress = 0.0;
18+global.real_progress = 0.0;
19+global.fake_progress_active = 0; # 0 / 1 boolean
20+global.animation_frame = 0;
21+global.fake_progress_start_time = 0; # Track when fake progress started
22+global.password_shown = 0; # Track if password dialog has been shown
23+global.max_progress = 0.0; # Track the maximum progress reached to prevent backwards movement
24+
25+fun refresh_callback ()
26+ {
27+ global.animation_frame++;
28+
29+ # Animate fake progress to limit over time with easing
30+ if (global.fake_progress_active == 1)
31+ {
32+ # Calculate elapsed time since start
33+ elapsed_time = global.animation_frame / 50.0; # Convert frames to seconds (50 FPS)
34+
35+ # Calculate linear progress ratio (0 to 1) based on time
36+ time_ratio = elapsed_time / global.fake_progress_duration;
37+ if (time_ratio > 1.0)
38+ time_ratio = 1.0;
39+
40+ # Apply easing curve: ease-out quadratic
41+ # Formula: 1 - (1 - x)^2
42+ eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio));
43+
44+ # Calculate fake progress based on eased ratio
45+ global.fake_progress = eased_ratio * global.fake_progress_limit;
46+
47+ # Update progress bar with fake progress
48+ update_progress_bar(global.fake_progress);
49+ }
50+ }
51+
52+
53+Plymouth.SetRefreshFunction (refresh_callback);
54+
55+#----------------------------------------- Helper Functions --------------------------------
56+
57+fun update_progress_bar(progress)
58+ {
59+ # Only update if progress is moving forward
60+ if (progress > global.max_progress)
61+ {
62+ global.max_progress = progress;
63+ width = Math.Int(progress_bar.original_image.GetWidth() * progress);
64+ if (width < 1) width = 1; # Ensure minimum width of 1 pixel
65+
66+ progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight());
67+ progress_bar.sprite.SetImage(progress_bar.image);
68+ }
69+ }
70+
71+fun show_progress_bar()
72+ {
73+ progress_box.sprite.SetOpacity(1);
74+ progress_bar.sprite.SetOpacity(1);
75+ }
76+
77+fun hide_progress_bar()
78+ {
79+ progress_box.sprite.SetOpacity(0);
80+ progress_bar.sprite.SetOpacity(0);
81+ }
82+
83+fun show_password_dialog()
84+ {
85+ lock.sprite.SetOpacity(1);
86+ entry.sprite.SetOpacity(1);
87+ }
88+
89+fun hide_password_dialog()
90+ {
91+ lock.sprite.SetOpacity(0);
92+ entry.sprite.SetOpacity(0);
93+ for (index = 0; bullet.sprites[index]; index++)
94+ bullet.sprites[index].SetOpacity(0);
95+ }
96+
97+fun start_fake_progress()
98+ {
99+ # Don't reset if we already have progress
100+ if (global.max_progress == 0.0)
101+ {
102+ global.fake_progress = 0.0;
103+ global.real_progress = 0.0;
104+ update_progress_bar(0.0);
105+ }
106+ global.fake_progress_active = 1;
107+ global.animation_frame = 0;
108+ }
109+
110+fun stop_fake_progress()
111+ {
112+ global.fake_progress_active = 0;
113+ }
114+
115+#----------------------------------------- Dialogue --------------------------------
116+
117+lock.image = Image("lock.png");
118+entry.image = Image("entry.png");
119+bullet.image = Image("bullet.png");
120+
121+entry.sprite = Sprite(entry.image);
122+entry.x = Window.GetWidth()/2 - entry.image.GetWidth() / 2;
123+entry.y = logo.sprite.GetY() + logo.image.GetHeight() + 40;
124+entry.sprite.SetPosition(entry.x, entry.y, 10001);
125+entry.sprite.SetOpacity(0);
126+
127+# Scale lock to be slightly shorter than entry field height
128+# Original lock is 84x96, entry height determines scale
129+lock_height = entry.image.GetHeight() * 0.8;
130+lock_scale = lock_height / 96;
131+lock_width = 84 * lock_scale;
132+
133+scaled_lock = lock.image.Scale(lock_width, lock_height);
134+lock.sprite = Sprite(scaled_lock);
135+lock.x = entry.x - lock_width - 15;
136+lock.y = entry.y + entry.image.GetHeight()/2 - lock_height/2;
137+lock.sprite.SetPosition(lock.x, lock.y, 10001);
138+lock.sprite.SetOpacity(0);
139+
140+# Bullet array
141+bullet.sprites = [];
142+
143+fun display_normal_callback ()
144+ {
145+ hide_password_dialog();
146+
147+ # Get current mode
148+ mode = Plymouth.GetMode();
149+
150+ # Only show progress bar for boot and resume modes
151+ if ((mode == "boot" || mode == "resume") && global.password_shown == 1)
152+ {
153+ show_progress_bar();
154+ start_fake_progress();
155+ }
156+ }
157+
158+fun display_password_callback (prompt, bullets)
159+ {
160+ global.password_shown = 1; # Mark that password dialog has been shown
161+
162+ # Reset progress when password dialog appears
163+ stop_fake_progress();
164+ hide_progress_bar();
165+ global.max_progress = 0.0;
166+ global.fake_progress = 0.0;
167+ global.real_progress = 0.0;
168+ show_password_dialog();
169+
170+ # Clear all bullets first
171+ for (index = 0; bullet.sprites[index]; index++)
172+ bullet.sprites[index].SetOpacity(0);
173+
174+ # Create and show bullets for current password (max 21)
175+ max_bullets = 21;
176+ bullets_to_show = bullets;
177+ if (bullets_to_show > max_bullets)
178+ bullets_to_show = max_bullets;
179+
180+ for (index = 0; index < bullets_to_show; index++)
181+ {
182+ if (!bullet.sprites[index])
183+ {
184+ # Scale bullet image to 7x7 pixels
185+ scaled_bullet = bullet.image.Scale(7, 7);
186+ bullet.sprites[index] = Sprite(scaled_bullet);
187+ bullet.x = entry.x + 20 + index * (7 + 5);
188+ bullet.y = entry.y + entry.image.GetHeight() / 2 - 3.5;
189+ bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002);
190+ }
191+ bullet.sprites[index].SetOpacity(1);
192+ }
193+ }
194+
195+Plymouth.SetDisplayNormalFunction(display_normal_callback);
196+Plymouth.SetDisplayPasswordFunction(display_password_callback);
197+
198+#----------------------------------------- Progress Bar --------------------------------
199+
200+progress_box.image = Image("progress_box.png");
201+progress_box.sprite = Sprite(progress_box.image);
202+
203+progress_box.x = Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
204+progress_box.y = entry.y + entry.image.GetHeight() / 2 - progress_box.image.GetHeight() / 2;
205+progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);
206+progress_box.sprite.SetOpacity(0);
207+
208+progress_bar.original_image = Image("progress_bar.png");
209+progress_bar.sprite = Sprite();
210+progress_bar.image = progress_bar.original_image.Scale(1, progress_bar.original_image.GetHeight());
211+
212+progress_bar.x = Window.GetWidth() / 2 - progress_bar.original_image.GetWidth() / 2;
213+progress_bar.y = progress_box.y + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
214+progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);
215+progress_bar.sprite.SetOpacity(0);
216+
217+fun progress_callback (duration, progress)
218+ {
219+ global.real_progress = progress;
220+
221+ # If real progress is above limit, stop fake progress and use real progress
222+ if (progress > global.fake_progress_limit)
223+ {
224+ stop_fake_progress();
225+ update_progress_bar(progress);
226+ }
227+ }
228+
229+Plymouth.SetBootProgressFunction(progress_callback);
230+
231+#----------------------------------------- Quit --------------------------------
232+
233+fun quit_callback ()
234+{
235+ logo.sprite.SetOpacity (1);
236+}
237+
238+Plymouth.SetQuitFunction(quit_callback);
239+
240+#----------------------------------------- Message --------------------------------
241+
242+message_sprite = Sprite();
243+message_sprite.SetPosition(10, 10, 10000);
244+
245+fun display_message_callback (text)
246+{
247+ my_image = Image.Text(text, 1, 1, 1);
248+ message_sprite.SetImage(my_image);
249+}
250+
251+fun hide_message_callback (text)
252+{
253+ message_sprite.SetOpacity(0);
254+}
255+
256+Plymouth.SetDisplayMessageFunction (display_message_callback);
257+Plymouth.SetHideMessageFunction (hide_message_callback);
A assets/plymouth/bullet.png +0 -0 binary file: no text diff

binary file: no text diff

A assets/plymouth/entry.png +0 -0 binary file: no text diff

binary file: no text diff

A assets/plymouth/lock.png +0 -0 binary file: no text diff

binary file: no text diff

A assets/plymouth/logo.png +0 -0 binary file: no text diff

binary file: no text diff

A assets/plymouth/progress_bar.png +0 -0 binary file: no text diff

binary file: no text diff

A assets/plymouth/progress_box.png +0 -0 binary file: no text diff

binary file: no text diff

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 0

    ↑↓ moveenter openesc close