Installing Fedora 32 on a mid-2009 Macbook Pro - Part Two, i3wm

A series of posts documenting the installation of Fedora 32 onto a mid-2009 15" Macbook Pro. In three parts; Part One describes the initial installation of Fedora and necessary updates to detect the internal WiFi hardware, Part Two describes configuring the window manager i3wm, and Part Three details the installation of the applications that I use daily. As is usual with Linux installations, forewarned is forearmed. Prepare for the lack of internal WiFi capability in the base Fedora install. And, if you use the i3 Window Manager, there is additional work to allow the MacBook to return to active mode from standby when the lid is closed and subsequently re-opened.

Installing i3wm

I use i3wm[1], a fast and bare-bones "tiling" Window Manager.

1
$ sudo yum -y install i3 i3status dmenu feh rofi terminator i3lock st

The first time you run i3wm it will prompt to run its initial setup and to choose your mod key which i3wm then writes to ~/.config/i3/config.

Niceties in the Xfce4 installation image

i3wm requires additional utilities and applets to perform network management and configuration, bluetooth pairing, power management, and mouse/trackpad and brightness controls for screen and keyboard. Installing the Xfce[2] Fedora "Spins" Live Image — as I described in [part-one] — provides much of this functionality in a way that integrates well with i3wm.

Use the bluetooth applet to display the bluetooth icon in the i3 status bar.

Add the following to ~/.config/i3/config

1
exec --no-startup-id /usr/bin/blueberry-tray                # Bluetooth Manager

Use the Xfce the power manager applet to control screen and keyboard brightness. The power management icon is displayed in the the i3 status bar.

Add the following to .~/.config/i3/config

1
2
3
4
exec --no-startup-id /usr/bin/xfce4-power-manager           # Power Manager. For
                                                            # controlling screen
                                                            # and keyboard
                                                            # brightness, etc.

NVidia Driver Support for the Additional Display

The Nouvea drivers[3] seem to work well for screen modes up to the MacBook Pro’s native screen resolution of 1440x900. However monitors having a resolution greater than this seem to exhibit flickering and tearing. To fix this, install the correct version of the NVidia graphics drivers.[4]

Install all updates, and add the RPMFusion repo that contains the nvidia drivers.
1
2
$ sudo dnf update
$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
The Macbook Pro 2009 15" requires the oldest nvidia-340xx series drivers.
1
2
3
4
$ sudo dnf install xorg-x11-drv-nvidia-340xx akmod-nvidia-340xx

# sudo dnf install akmod-nvidia
# sudo dnf install xorg-x11-drv-nvidia-390xx akmod-nvidia-390xx
You can use lspci to list the model of graphics hardware.
1
$ lspci -vnn | grep VGA

Setting the timezone

To set a valid timezone
1
$ timedatectl set-timezone America/Los_Angeles
The timedatectl command creates a symbolic link to the actual timezone file
1
2
3
$ ls -l /etc/locatime

lrwxrwxrwx 1 root root 27 Dec  3 16:29 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC
Determine the current timezone as follows
1
2
3
4
5
6
7
8
9
$ timedatectl

                      Local time: Tue 2019-12-03 16:30:44 UTC
                  Universal time: Tue 2019-12-03 16:30:44 UTC
                        RTC time: Tue 2019-12-03 16:30:44
                       Time zone: Etc/UTC (UTC, +0000)
       System clock synchronized: no
systemd-timesyncd.service active: yes
                 RTC in local TZ: no
List all available timezones as follows
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ timedatectl list-timezone

...
America/Montserrat
America/Nassau
America/New_York
America/Nipigon
America/Nome
America/Noronha
...

Swap CAPS and Control

Log out and back into i3wm for an updated key map to take effect. Or use the HHKB[5] keyboard and skip this section.

Add the following to ~/.config/i3/config
1
2
3
4
# Swap CAPS_LOCK and R_CTRL
# To get the current key mappings
# $ xmodmap -pke
exec --no-startup-id /usr/bin/xmodmap /.Xmodmap
Create a new ~/.Xmodmap file, swapping CAPS with the right Control key
1
2
3
4
5
6
7
8
! swap Caps_Lock and Control_R
!
remove Lock = Caps_Lock
remove Control = Control_R
keysym Control_R = Caps_Lock
keysym Caps_Lock = Control_R
add Lock = Caps_Lock
add Control = Control_R

Lock the screen from a keypress

Add the following to .~/.config/i3/config

1
bindsym $mod+Control+l exec i3lock

Setting the Background Image

The following command creates a ~/.fehbg file to run at i3wm startup
1
$ feh --bg-scale <path_to_background_image>
Add the following to ~/.config/i3/config
1
2
# Set the background image
exec --no-startup-id ~/.fehbg

Font-Awesome

Fontawesome contains the glyphs referenced in my i3status config.

Install the Fontawesome font package
1
2
# Set the background image
sudo yum install fontawesome-fonts

Take note of the version of Fontawesome that is installed as new versions of Fontawesome contain additional glyphs. Also, Fontawesome is distributed as as free and pro versions, with pro containing substantially more glyphs. It’s best to look at the Fontawesome[6] website, choose the version installed and browse the available glyphs. Optionally, install the latest version of Fontawesome manually. Or take a look at NerdFonts.[7].

Using the Rofi app launcher instead of Dmenu

Add the following to .~/.config/i3/config

1
2
3
4
5
6
# start rofi (a program launcher)
bindsym $mod+d exec rofi -lines 12 -padding 18 -width 60 -location 0 \
        -show drun -sidebar-mode -columns 3 -font 'Noto Sans 8'

# start dmenu (a program launcher)
bindsym $mod+Shift+d exec dmenu_run

Use an alternate terminal emulator

Add the following to .~/.config/i3/config

1
2
# start a terminal
bindsym $mod+Return exec st # terminator # i3-sensible-terminal

Configure Workspaces

Add the following to .~/.config/i3/config

 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
29
30
31
32
33
34
35
36
37
# Cycle back and forth between the two most recently used containers
bindsym $mod+Shift+b workspace back_and_forth
workspace_auto_back_and_forth yes

# Define workspace names
set $ws1 "1: main"
set $ws2 "2: www"
set $ws3 "3: irc"
set $ws3 "4: mail"
# ...
set $ws10 "10: Spotify"

# switch to workspace
bindsym $mod+1 workspace $ws1
bindsym $mod+2 workspace $ws2
bindsym $mod+3 workspace $ws3
bindsym $mod+3 workspace $ws4

# move focused container to workspace
bindsym $mod+Shift+1 move container to workspace $ws1
bindsym $mod+Shift+2 move container to workspace $ws2
bindsym $mod+Shift+3 move container to workspace $ws3
bindsym $mod+Shift+3 move container to workspace $ws4
# ...
bindsym $mod+Shift+0 move container to workspace $ws10

# Create a specific workspace for Spotify
for_window [class="Spotify"] move --no-auto-back-and-forth to workspace $ws10

# Create a specific workspace for Zoom
# assign [class="Zoom"] $ws5

# Lock the screen
# bindsym $mod+Control+l exec i3lock

# Jump to the Urgent window
# bindsym $mod+x [urgent=latest] focus

Configure the i3status bar

See the full list of i3status options.[8]

Add the following to ~/.config/i3/config
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
bar {
    colors {
        background #2f343f
        statusline #2f343f
        separator #4b5262

        # colour of border, background, and text
        focused_workspace       #2f343f #bf616a #d8dee8
        active_workspace        #2f343f #2f343f #d8dee8
        inactive_workspace      #2f343f #2f343f #d8dee8
        urgent_workspacei       #2f343f #ebcb8b #2f343f
    }
    status_command i3status
    # i3bar_command i3bar --transparency
}

Add the following to .~/.config/i3status/config

 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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
general {
        output_format = "i3bar"
        colors = false
        markup = pango
        interval = 5
        color_good = '#2f343f'
        color_degraded = '#ebcb8b'
        color_bad = '#ba5e57'
}

order += "load"
order += "cpu_temperature 0"
# order += "disk /"
order += "disk /home"
order += "wireless wlp4s0" # Enter the following to return the list of network
                           # devices
                           # $ iwconfig
# order += "ethernet enp1s0"
order += "volume master"
order += "battery 0"
order += "tztime local"

load {
        format = "<span background='#f59335'>  %1min %5min %15min Load </span>"
}

cpu_temperature 0 {
        format = "<span background='#bf616a'>  %degrees °C </span>"
        path = "/sys/class/thermal/thermal_zone0/temp"
}

disk "/" {
        format = "<span background='#fec7cd'>  %free Free </span>"
}

disk "/home" {
        format = "<span background='#a1d569'>  %free Free </span>"
}

ethernet enp1s0 {
        format_up = "<span background='#88c0d0'>  %ip </span>"
        format_down = "<span background='#88c0d0'>  Disconnected </span>"
}

wireless wlp4s0 {
        format_up = "<span background='#b48ead'>  %essid </span>"
        format_down = "<span background='#b48ead'>  Disconnected </span>"
}

volume master {
        format = "<span background='#ebcb8b'>  %volume </span>"
        format_muted = "<span background='#ebcb8b'>  Muted </span>"
        device = "default"
        mixer = "Master"
        mixer_idx = 0
}

battery 0 {
	last_full_capacity = true
        format = "<span background='#a3be8c'>  %status %percentage </span>"
        format_down = "No Battery"
        status_chr = "Charging"
        status_bat = "Battery"
        status_unk = "Unknown"
        status_full = "Charged"
        path = "/sys/class/power_supply/BAT%d/uevent"
        low_threshold = 10
}

tztime local {
		format = "<span background='#81a1c1'> %time </span>"
		format_time = " %a %-d %b %H:%M"
}

Edit ~/.config/i3status/config, replacing the string wlp4s0 with the correct WiFi device name returned from iwconfig below.

List all networking devices
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ iwconfig

lo        no wireless extensions.

enp0s10   no wireless extensions.

wlp4s0    IEEE 802.11  ESSID:"xxxxxxxxxxx"
          Mode:Managed  Frequency:5.765 GHz  Access Point: xx:xx:xx:xx:xx:xx
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Power Management:off

Setup periodic TRIM for SSDs

Set up a periodic TRIM[9] to run for mounted SSDs.

1
sudo systemctl enable fstrim.timer

Enable "Tap to Click" on the Touchpad

The touchpad can be configured by creating[10][11][12] /etc/X11/xorg.conf.d/30-touchpad.conf file as follows;

/etc/X11/xorg.conf.d/30-touchpad.conf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Section "InputClass"
    Identifier "touchpad"
    Driver "libinput"
    MatchIsTouchpad "on"
    Option "Tapping" "off"
    Option "NaturalScrolling" "true"
    Option "HorizontalScrolling" "false"
    Option "ScrollMethod" "twofinger"
    Option "TappingButtonMap" "lmr"
EndSection