main 6af0a61

archup.script RawHistoryFolder

1# Arch Linux Plymouth Theme Script
2
3Window.SetBackgroundTopColor(0, 0, 0);
4Window.SetBackgroundBottomColor(0, 0, 0);
5
6logo.original_image = Image("logo.png");
7
8# Scale logo to at most 40% of screen height
9logo.max_height = Math.Int(Window.GetHeight() * 0.40);
10if (logo.original_image.GetHeight() > logo.max_height)
11  {
12    logo.scale = logo.max_height / logo.original_image.GetHeight();
13    logo.image = logo.original_image.Scale(
14      Math.Int(logo.original_image.GetWidth() * logo.scale),
15      logo.max_height
16    );
17  }
18else
19  {
20    logo.image = logo.original_image;
21  }
22
23logo.sprite = Sprite(logo.image);
24
25# Center the logo during boot
26logo.normal_x = Window.GetWidth()  / 2 - logo.image.GetWidth()  / 2;
27logo.normal_y = Window.GetHeight() / 2 - logo.image.GetHeight() / 2;
28logo.sprite.SetPosition(logo.normal_x, logo.normal_y, 1);
29logo.sprite.SetOpacity(1);
30
31# Use these to adjust the progress bar timing
32global.fake_progress_limit = 0.7;  # Target percentage for fake progress (0.0 to 1.0)
33global.fake_progress_duration = 15.0;  # Duration in seconds to reach limit
34
35# Progress bar animation variables
36global.fake_progress = 0.0;
37global.real_progress = 0.0;
38global.fake_progress_active = 0; # 0 / 1 boolean
39global.animation_frame = 0;
40global.fake_progress_start_time = 0;  # Track when fake progress started
41global.password_shown = 0;  # Track if password dialog has been shown
42global.max_progress = 0.0;  # Track the maximum progress reached to prevent backwards movement
43
44fun refresh_callback ()
45  {
46    global.animation_frame++;
47
48    # Animate fake progress to limit over time with easing
49    if (global.fake_progress_active == 1)
50      {
51        # Calculate elapsed time since start
52        elapsed_time = global.animation_frame / 50.0;  # Convert frames to seconds (50 FPS)
53
54        # Calculate linear progress ratio (0 to 1) based on time
55        time_ratio = elapsed_time / global.fake_progress_duration;
56        if (time_ratio > 1.0)
57          time_ratio = 1.0;
58
59        # Apply easing curve: ease-out quadratic
60        # Formula: 1 - (1 - x)^2
61        eased_ratio = 1 - ((1 - time_ratio) * (1 - time_ratio));
62
63        # Calculate fake progress based on eased ratio
64        global.fake_progress = eased_ratio * global.fake_progress_limit;
65
66        # Update progress bar with fake progress
67        update_progress_bar(global.fake_progress);
68      }
69  }
70
71
72Plymouth.SetRefreshFunction (refresh_callback);
73
74#----------------------------------------- Helper Functions --------------------------------
75
76fun update_progress_bar(progress)
77  {
78    # Only update if progress is moving forward
79    if (progress > global.max_progress)
80      {
81        global.max_progress = progress;
82        width = Math.Int(progress_bar.original_image.GetWidth() * progress);
83        if (width < 1) width = 1;  # Ensure minimum width of 1 pixel
84
85        progress_bar.image = progress_bar.original_image.Scale(width, progress_bar.original_image.GetHeight());
86        progress_bar.sprite.SetImage(progress_bar.image);
87      }
88  }
89
90fun show_progress_bar()
91  {
92    progress_box.sprite.SetOpacity(1);
93    progress_bar.sprite.SetOpacity(1);
94  }
95
96fun hide_progress_bar()
97  {
98    progress_box.sprite.SetOpacity(0);
99    progress_bar.sprite.SetOpacity(0);
100  }
101
102fun show_password_dialog()
103  {
104    entry.sprite.SetOpacity(1);
105  }
106
107fun hide_password_dialog()
108  {
109    entry.sprite.SetOpacity(0);
110    for (index = 0; bullet.sprites[index]; index++)
111      bullet.sprites[index].SetOpacity(0);
112  }
113
114fun start_fake_progress()
115  {
116    # Don't reset if we already have progress
117    if (global.max_progress == 0.0)
118      {
119        global.fake_progress = 0.0;
120        global.real_progress = 0.0;
121        update_progress_bar(0.0);
122      }
123    global.fake_progress_active = 1;
124    global.animation_frame = 0;
125  }
126
127fun stop_fake_progress()
128  {
129    global.fake_progress_active = 0;
130  }
131
132#----------------------------------------- Dialogue --------------------------------
133
134entry.image = Image("entry.png");
135bullet.image = Image("bullet.png");
136
137# Scale entry to 60% of its original size
138entry.scaled_image = entry.image.Scale(
139  Math.Int(entry.image.GetWidth() * 0.6),
140  Math.Int(entry.image.GetHeight() * 0.6)
141);
142
143# Entry appears below the centered logo with a fixed gap
144dialog_gap = 32;
145entry.dialog_y = logo.normal_y + logo.image.GetHeight() + dialog_gap;
146
147# Safety cap: never push entry off screen
148entry.max_y = Window.GetHeight() - entry.scaled_image.GetHeight() - 20;
149if (entry.dialog_y > entry.max_y)
150  entry.dialog_y = entry.max_y;
151
152entry.x = Window.GetWidth() / 2 - entry.scaled_image.GetWidth() / 2;
153
154entry.sprite = Sprite(entry.scaled_image);
155entry.sprite.SetPosition(entry.x, entry.dialog_y, 10001);
156entry.sprite.SetOpacity(0);
157
158# Bullet array
159bullet.sprites = [];
160
161fun display_normal_callback ()
162  {
163    hide_password_dialog();
164
165    # Restore logo to center when back to normal boot screen
166    logo.sprite.SetPosition(logo.normal_x, logo.normal_y, 1);
167
168    # Get current mode
169    mode = Plymouth.GetMode();
170
171    # Only show progress bar for boot and resume modes
172    if ((mode == "boot" || mode == "resume") && global.password_shown == 1)
173      {
174        show_progress_bar();
175        start_fake_progress();
176      }
177  }
178
179fun display_password_callback (prompt, bullets)
180  {
181    global.password_shown = 1;  # Mark that password dialog has been shown
182
183    # Keep logo at its normal centered position during unlock
184    logo.sprite.SetPosition(logo.normal_x, logo.normal_y, 1);
185
186    # Reset progress when password dialog appears
187    stop_fake_progress();
188    hide_progress_bar();
189    global.max_progress = 0.0;
190    global.fake_progress = 0.0;
191    global.real_progress = 0.0;
192    show_password_dialog();
193
194    # Clear all bullets first
195    for (index = 0; bullet.sprites[index]; index++)
196      bullet.sprites[index].SetOpacity(0);
197
198    # Create and show bullets for current password (max 21)
199    max_bullets = 21;
200    bullets_to_show = bullets;
201    if (bullets_to_show > max_bullets)
202      bullets_to_show = max_bullets;
203
204    for (index = 0; index < bullets_to_show; index++)
205      {
206        if (!bullet.sprites[index])
207          {
208            # Scale bullet image to 6x6 pixels
209            scaled_bullet = bullet.image.Scale(6, 6);
210            bullet.sprites[index] = Sprite(scaled_bullet);
211            bullet.x = entry.x + 12 + index * (6 + 4);
212            bullet.y = entry.dialog_y + entry.scaled_image.GetHeight() / 2 - 3;
213            bullet.sprites[index].SetPosition(bullet.x, bullet.y, 10002);
214          }
215        bullet.sprites[index].SetOpacity(1);
216      }
217  }
218
219Plymouth.SetDisplayNormalFunction(display_normal_callback);
220Plymouth.SetDisplayPasswordFunction(display_password_callback);
221
222#----------------------------------------- Progress Bar --------------------------------
223
224progress_box.image = Image("progress_box.png");
225progress_box.sprite = Sprite(progress_box.image);
226
227progress_box.x = Window.GetWidth() / 2 - progress_box.image.GetWidth() / 2;
228progress_box.y = logo.normal_y + logo.image.GetHeight() + 40;
229progress_box.sprite.SetPosition(progress_box.x, progress_box.y, 0);
230progress_box.sprite.SetOpacity(0);
231
232progress_bar.original_image = Image("progress_bar.png");
233progress_bar.sprite = Sprite();
234progress_bar.image = progress_bar.original_image.Scale(1, progress_bar.original_image.GetHeight());
235
236progress_bar.x = Window.GetWidth() / 2 - progress_bar.original_image.GetWidth() / 2;
237progress_bar.y = progress_box.y + (progress_box.image.GetHeight() - progress_bar.original_image.GetHeight()) / 2;
238progress_bar.sprite.SetPosition(progress_bar.x, progress_bar.y, 1);
239progress_bar.sprite.SetOpacity(0);
240
241fun progress_callback (duration, progress)
242  {
243    global.real_progress = progress;
244
245    # If real progress is above limit, stop fake progress and use real progress
246    if (progress > global.fake_progress_limit)
247      {
248        stop_fake_progress();
249        update_progress_bar(progress);
250      }
251  }
252
253Plymouth.SetBootProgressFunction(progress_callback);
254
255#----------------------------------------- Quit --------------------------------
256
257fun quit_callback ()
258{
259  logo.sprite.SetOpacity (1);
260}
261
262Plymouth.SetQuitFunction(quit_callback);
263
264#----------------------------------------- Message --------------------------------
265
266message_sprite = Sprite();
267message_sprite.SetPosition(10, 10, 10000);
268
269fun display_message_callback (text)
270{
271  my_image = Image.Text(text, 1, 1, 1);
272  message_sprite.SetImage(my_image);
273}
274
275fun hide_message_callback (text)
276{
277  message_sprite.SetOpacity(0);
278}
279
280Plymouth.SetDisplayMessageFunction (display_message_callback);
281Plymouth.SetHideMessageFunction (hide_message_callback);

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