Since I have already blogged about Hyprland a lot, I want to report that Hyprland runs smoothly on this PineBook Pro. I basically reused all my ricing and customizations that I blogged about in my previous posts about Hyprland.
Here are a few screenshots:
That’s all! As I said, this was meant to be a brief report. 🙂
I’m starting a new blog series about Sway, a Wayland Tiling Window Manager (the Wayland version of i3). Though I’ve already blogged about Sway, this post (and a few future ones) are intended as “getting started tutorials”.
I’ll focus on Sway in Arch, in particular, EndeavourOS.
Let’s start by installing EndeavourOS with no graphical environment installed:
Once the installation is finished, let’s log in to a terminal session since we have no Desktop Environment.
Let’s install the main package:
1
sudo pacman-Ssway
The output shows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Sway requires additional setup for privilege escalation. Without this setup,
sway will fail to start with session activation permission failures. Choose one
of the two available options (In alphabetical, not recommended, order):
1. polkit: This will make sway "just work" right after installation but may be
a weightier solution than desired.
2. seatd: Already required as a sway dependency, this is a lighter-weight
solution but requires some user configuration: Enabling the service,
adding your user to the "seat" group, then logging out/in again.
Either option should provide the same functionality/stability. Refer to the
Sway wiki page for information.
Optional dependencies for sway
dmenu: dmenu_path support (used alongside wmenu in default $menu)
foot: Terminal emulator used in the default configuration
i3status: Status line generation
mako: Lightweight notification daemon
polkit: System privilege control. Required if not using seatd service [installed]
swaybg: Wallpaper tool for sway
sway-contrib: Collection of user-contributed scripts for sway
swayidle: Idle management daemon
swaylock: Screen locker
waybar: Highly customizable bar
wmenu: Application launcher used in default config
xorg-xwayland: X11 support
xdg-desktop-portal-gtk: Default xdg-desktop-portal for file picking
The package “polkit” has already been installed (see above), so we should be fine.
Let’s also install “foot” to be able to open a terminal with the default configuration and also “wmenu” and “dmenu” (see the output above about these programs):
1
sudo pacman-Sfoot wmenu demnu
Now, we can start “sway” from the command line.
There’s not much with the default configuration: just the workspace indicator (top-left) and the date and time (top-right), not even a wallpaper (we’ll deal with that in a minute).
We can start a terminal (“foot”) with SUPER+ENTER.
To start an application with the application launcher (by default wmenu/dmenu), for example, “firefox” (if installed) we use SUPER+D and start typing in the prompt appearing in the top left corner; a few letters should be enough til you get to the desired program (and press ENTER to launch it).
Of course, the windows are tiled:
NOTE: the SUPER (i.e., the “Window key”) is the default “mod” modifier for keybindings, but you can change it to something else if you want (e.g., “Alt”).
We can switch workspaces with SUPER+<workspace number>, start other terminals there:
We can focus windows with SUPER+<arrow keys> and move a window to another workspace with SUPER+SHIFT+<workspace number>—and close windows with SUPER+SHIFT+Q.
To move the current window and change its position in the tiling, use SUPER+SHIFT+<arrow keys> (instead of arrow keys, you can also use the H, J, K, and L as in Vim):
Let’s install the package “swaybg” (see the output above; that’s the “Wallpaper tool for sway”):
1
sudo pacman-Sswaybg
Now, let’s reload sway with SUPER+SHIFT+C and…
We have the wallpaper!
It’s time to start customizing the configuration.
Let’s create the directory for the configuration file and start from the default one:
1
2
mkdir-p~/.config/sway
cp/etc/sway/config~/.config/sway/
Now, we can edit the “~/.config/sway/config” file. (note that the file ends with “include /etc/sway/config.d/*”, which properly sets a few environment variables and makes them available to systemd).
The first thing I will customize is the keyboard layout: I have an Italian keyboard, so I have to specify that (the default is an American layout). I’ll add this section somewhere in the config file (e.g., near the comments about other input configurations):
1
2
3
4
5
# right Ctrl to switch
input type:keyboard {
xkb_layout it,us
xkb_options grp:rctrl_toggle
}
This will give me an Italian layout by default, and I can switch to an American layout by pressing the right CTRL.
Save the file, reload with SUPER+SHIFT+C, and experiment with the keyboard layouts.
Let’s change the application launcher, which is not very useful in its current shape. Let’s use the Wayland version of Rofi.
1
sudo pacman-Srofi-wayland
Then, let’s open the Sway config file and change the setting of the $menu as follows:
1
​set$menu"rofi -show drun -show-icons"
Reload Sway and now pressing the SUPRT+D will get us a much nicer application launcher (just start typing to filter the entries):
Let’s install a file manager, like Nemo.
1
sudo pacman-Snemo
Then, we can create a shortcut for opening the file manager; let’s open the Sway config file, define a variable for the file manager (it will make it easier in the future to switch to another file manager, for example) and a key binding, e.g., SUPER+SHIFT+ENTER:
1
2
3
4
set$filemanager nemo
...
   # Start a filemanager
  bindsym$mod+Shift+Returnexec$filemanager
Moreover, I prefer Alacritty as a program for terminal:
1
sudo pacman-Salacritty
Then, we just have to change the “$term” definition in the Sway config file: change the line “set $term foot” to
1
set$term alacritty
Now, we need an Authentication Agent, which pops up a window asking you for a password whenever an app wants to elevate its privileges. I prefer the KDE one:
1
sudo pacman-Spolkit-kde-agent
And start it when Sway starts; so in the Sway configuration file:
1
2
### Autostart applications
exec"/usr/lib/polkit-kde-authentication-agent-1"
Since this is “exec”, not “exec_always”, you need to restart Sway, not simply reload it.
Now, if we run from a terminal a “systemctl” command that needs superuser privileges, we get the pop-up dialog asking for a password:
The configuration file already contains a commented section for locking and screensaver:
Shell
1
2
3
4
5
6
7
8
9
10
11
12
### Idle configuration
#
# Example configuration:
#
# exec swayidle -w \
# timeout 300 'swaylock -f -c 000000' \
# timeout 600 'swaymsg "output * power off"' resume 'swaymsg "output * power on"' \
# before-sleep 'swaylock -f -c 000000'
#
# This will lock your screen after 300 seconds of inactivity, then turn off
# your displays after another 300 seconds, and turn your screens back on when
# resumed. It will also lock your screen before your computer goes to sleep.
So, let’s install the involved programs (also mentioned above when we installed Sway):
1
sudo pacman-Sswayidle swaylock
Uncomment the “exec” command; remember that we need to restart Sway to have that mechanism in action. (Of course, you have to wait for 300 seconds). I’m not covering customization of the lock screen and the like here.
We can also set a key binding to lock the screen manually. I usually use SUPER+L; note that this is already bound as a combination to move on the left window (remember the Vim keybindings above?); so, first, I have to uncomment the corresponding bindings (I uncomment them all because I’m not using them: I prefer arrow keys) and add mine:
1
2
3
4
5
6
7
  # lock the screen
bindsym$mod+lexec swaylock-f-c000000
...
   #bindsym $mod+$left focus left
   #bindsym $mod+$down focus down
   #bindsym $mod+$up focus up
  #bindsym $mod+$right focus right
Let’s install some of the optional packages suggested above when installing Sway (in particular, the “xorg-xwayland” will allow us to run also X applications):
1
2
3
4
sudo pacman-S\
xorg-xwayland\
xdg-desktop-portal-gtk\
xdg-desktop-portal-wlr
That’s all for this first tutorial part; stay tuned for more to come 🙂
It assumes you have already read the first and second posts.
On the bottom, we can see that there are two warnings on our project; let’s click the icon and see them in the “Problems” tab:
Since this is not a Java project managed by Visual Studio Code but a Maven project, we must fix the warning in the POM.
Let’s assume we want to update our project to use the Java version installed in the Gitpod workspace: Java 11 (we can tell that from the warning, but we could also run “java -version” from a terminal to verify that). We open the POM file and update the corresponding properties of Java 1.7: we change “1.7” to “11”:
As soon as we modify the POM, we get a pop-up: the Java LSP detects a change in the project configuration and offers to synchronize the classpath and rebuild the project. Of course, we accept. We accept that, and after a few seconds, the warnings go away.
Note that our choice leads to creating the settings file for this option. We can choose to rebuild the project automatically (“Always”), and the settings file will be updated accordingly. Of course, it makes sense to store such a file in the Git repository.
We can now create a commit with our changes and push them to GitHub.
Remember that the JSON editor is aware of the corresponding schema, so we can enjoy code completion for the string value:
Let’s now say we want to use Java 17 for our project. The workspace provides Java 11, so we must also have Java 17 installed in the Gitpod workspace.
Let’s modify the POM for Java 17 and rebuild the project. Let’s try to run the main file. The Java application still runs, as we can see from the terminal:
Gitpod workspace uses SDKMAN to provide a few versions of tools like the JDK and uses the version required by the project (in this example, Java 17).
We can list the installed JDK in the terminal (and the current one):
1
2
3
$sdk list java|grep installed
||17.0.9.fx|zulu|installed|17.0.9.fx-zulu
|>>>|11.0.21.fx|zulu|installed|11.0.21.fx-zulu
If we wanted to go for Java 21, we should install that version with SDKMAN, but we wouldn’t want to do that manually each time we open a Gitpod workspace. Moreover, instead of the “Zulu” distribution, we might use the “Temurin” distribution.
The recommended way is to provide a custom Dockerfile for our Gitpod workspace to have full explicit control over the versions of the tools we use; this will be part of the Git repository and live with the code.
So we create in the root of our project the file “.gitpod.Dockerfile,” and we configure SDKMAN for the version of Java we want to install and set as the current (the available versions can be discovered with “sdk list java”):
1
2
3
4
5
6
7
FROM gitpod/workspace-full
USER gitpod
RUN bash-c". /home/gitpod/.sdkman/bin/sdkman-init.sh && \
sdk install java 17.0.9-tem && \
sdk default java 17.0.9-tem"
Then, we refer to this Dockerfile in the “.gitpod.yml”:
YAML
1
2
3
image:
file: .gitpod.Dockerfile
...
As before, we can let Gitpod validate our configuration and start a new workspace with the rebuilt Docker image.
As shown in my previous post on Gitpod, you might want to start from a smaller base image with only the needed tools like Java. That would decrease the time to build the custom Docker image. That is out of the scope of this post.
However, rebuilding the Docker image will be done the first time you start a workspace, and the custom image will be cached.
On the new workspace, we can verify that we are using the Java version we installed and set as default:
OpenJDK 64-Bit Server VM Temurin-17.0.9+9 (build 17.0.9+9, mixed mode, sharing)
Again, we commit our changes (including the new custom Dockerfile) and push them to GitHub.
One could use the same strategy for installing a specific version of Maven through SDKMAN. Maven is also installed in the workspace through SDKMAN.
I want to conclude that this process seems long. Still, once you get familiar with the configuration of Gitpod for Java/Maven projects, for new repositories of the same kind, it is enough to immediately put in the Git repository the “.gitpod.yml” and the “.gitpod.Dockerfile.” You can immediately start coding with Gitpod! 🙂
Remember, though, that the first time, you will still have to wait for the build of your custom Docker image.
I love to manage my dotfiles with Chezmoi, which I highly recommend! In a single Git repository, I have common dotfiles and Window Manager specific (KDE, GNOME, Hyprland, and Sway).
However, I prefer to have my Neovim configuration in another Git repository, separate from my Chezmoi dotfiles. I’ve just started learning Neovim, and I’m not yet 100% sure the configuration I use will be the ultimate one (I use Lazyvim); that’s why I want to keep them separate.
Chezmoi offers mechanisms for such situations: https://www.chezmoi.io/user-guide/include-files-from-elsewhere/. In particular, I use “Include a subdirectory from a git repository”: this way, Chezmoi will clone the external Git repository for my Neovim configuration on the first run and will keep it up to date (i.e., “git pull”) at some specified intervals (remember, the default interval is 0!).
You need to create the file “.chezmoiexternal.toml” in the root folder of your Chezmoi file and follow the syntax in the documentation.
For example, I want my “~/.config/nvim” directory (where Neovim configuration lives) to be populated (and kept up-to-date) with the contents of my GitHub repository “https://github.com/LorenzoBettini/starter” (as I said above, I’m using a fork of the Starter repository of Lazyvim):
INI
1
2
3
4
[".config/nvim"]
type="git-repo"
url="git@github.com:LorenzoBettini/starter.git"
refreshPeriod="1h"
Note that I specified a 1-hour refresh interval. Thus, if I issue a “chezmoi update,” it will keep that interval into consideration when deciding whether to check for updates (i.e., “pull”) in the Git repository. However, you also have this option in Chezmoi to force the Git update:
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
Cookie
Duration
Description
cookielawinfo-checkbox-analytics
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional
11 months
The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy
11 months
The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.