diff --git a/Dockerfile b/Dockerfile
index 149f7f9..bacfcce 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,5 +17,5 @@ RUN echo "none /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0" > /etc/fstab
COPY docker/entrypoint.sh /tmp
COPY src/ /tmp
WORKDIR /tmp
-CMD bash
-# CMD /tmp/entrypoint.sh
+#CMD bash
+CMD /tmp/entrypoint.sh
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.config/sway/config b/src/recipes/default/hook/data/overlay/etc/skel/.config/sway/config
new file mode 100644
index 0000000..f8c9446
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.config/sway/config
@@ -0,0 +1,279 @@
+# Default config for sway
+#
+# Copy this to ~/.config/sway/config and edit it to your liking.
+#
+# Read `man 5 sway` for a complete reference.
+
+### Variables
+#
+# Logo key. Use Mod1 for Alt.
+set $mod Mod4
+# Home row direction keys, like vim
+set $left left
+set $down down
+set $up up
+set $right right
+# Your preferred terminal emulator
+set $term xfce4-terminal
+# Your preferred application launcher
+# Note: it's recommended that you pass the final command to sway
+#set $menu dmenu_path | dmenu | xargs swaymsg exec --
+set $menu rofi -show drun -font "Inter Bold 24" -display-drun "" -theme mnt-reform | xargs swaymsg exec --
+
+#xwayland disable
+
+### Output configuration
+#
+# Default wallpaper (more resolutions are available in @datadir@/backgrounds/sway/)
+#output * bg "#000000" fill
+exec swaybg -c "#000000"
+
+#
+# Example configuration:
+#
+# output HDMI-A-1 resolution 1920x1080 position 1920,0
+#
+# You can get the names of your outputs by running: swaymsg -t get_outputs
+
+### Idle configuration
+#
+# Example configuration:
+#
+# exec swayidle -w \
+# timeout 300 'swaylock -f -c 000000' \
+# timeout 600 'swaymsg "output * dpms off"' \
+# resume 'swaymsg "output * dpms 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.
+
+### Input configuration
+#
+# Example configuration:
+#
+# input "2:14:SynPS/2_Synaptics_TouchPad" {
+# dwt enabled
+# tap enabled
+# natural_scroll enabled
+# middle_emulation enabled
+# }
+#
+# You can get the names of your inputs by running: swaymsg -t get_inputs
+# Read `man 5 sway-input` for more information about this section.
+#
+
+default_border pixel 10
+hide_edge_borders both
+
+### Key bindings
+#
+# Basics:
+#
+ # Start a terminal
+ bindsym $mod+Return exec $term
+ bindsym $mod+Shift+s exec grim ~/Pictures/$(date +'screenshot-%Y-%m-%d-%H-%M-%S').png
+ bindsym $mod+Shift+x exec grim -g "$(slurp)" ~/Pictures/$(date +'screenshot-%Y-%m-%d-%H-%M-%S').png
+ bindsym $mod+Shift+v exec reform-pavucontrol.sh
+ bindsym $mod+Shift+l exec swaylock
+
+ # Kill focused window
+ bindsym $mod+Escape kill
+
+ # Start your launcher
+ bindsym $mod+d exec $menu
+ bindsym $mod+Tab exec $menu
+ bindsym $mod+t exec thunar
+
+ # Drag floating windows by holding down $mod and left mouse button.
+ # Resize them with right mouse button + $mod.
+ # Despite the name, also works for non-floating windows.
+ # Change normal to inverse to use left mouse button for resizing and right
+ # mouse button for dragging.
+ floating_modifier $mod normal
+
+ # Reload the configuration file
+ bindsym $mod+Shift+c reload
+
+ # Exit sway (logs you out of your Wayland session)
+ bindsym $mod+Shift+e exec swaynag -t warning -m 'You pressed the exit shortcut. Do you really want to exit sway? This will end your Wayland session.' -b 'Yes, exit sway' 'swaymsg exit'
+#
+# Moving around:
+#
+ # Move your focus around
+ bindsym $mod+$left focus left
+ bindsym $mod+$down focus down
+ bindsym $mod+$up focus up
+ bindsym $mod+$right focus right
+ # Or use $mod+[up|down|left|right]
+ #bindsym $mod+Left focus left
+ #bindsym $mod+Down focus down
+ #bindsym $mod+Up focus up
+ #bindsym $mod+Right focus right
+
+ # Move the focused window with the same, but add Shift
+ bindsym $mod+Shift+$left move left
+ bindsym $mod+Shift+$down move down
+ bindsym $mod+Shift+$up move up
+ bindsym $mod+Shift+$right move right
+ # Ditto, with arrow keys
+ #bindsym $mod+Shift+Left move left
+ #bindsym $mod+Shift+Down move down
+ #bindsym $mod+Shift+Up move up
+ #bindsym $mod+Shift+Right move right
+
+ bindsym $mod+F1 exec brightnessctl s 1-
+ bindsym $mod+F2 exec brightnessctl s +1
+ bindsym $mod+F3 exec pactl set-sink-volume @DEFAULT_SINK@ -5%
+ bindsym $mod+F4 exec pactl set-sink-volume @DEFAULT_SINK@ +5%
+ bindsym $mod+F5 exec pactl set-sink-mute @DEFAULT_SINK@ toggle
+#
+# Workspaces:
+#
+ # Switch to workspace
+ bindsym $mod+1 workspace 1
+ bindsym $mod+2 workspace 2
+ bindsym $mod+3 workspace 3
+ bindsym $mod+4 workspace 4
+ bindsym $mod+5 workspace 5
+ bindsym $mod+6 workspace 6
+ bindsym $mod+7 workspace 7
+ bindsym $mod+8 workspace 8
+ bindsym $mod+9 workspace 9
+ bindsym $mod+0 workspace 10
+ # Move focused container to workspace
+ bindsym $mod+Shift+1 move container to workspace 1
+ bindsym $mod+Shift+2 move container to workspace 2
+ bindsym $mod+Shift+3 move container to workspace 3
+ bindsym $mod+Shift+4 move container to workspace 4
+ bindsym $mod+Shift+5 move container to workspace 5
+ bindsym $mod+Shift+6 move container to workspace 6
+ bindsym $mod+Shift+7 move container to workspace 7
+ bindsym $mod+Shift+8 move container to workspace 8
+ bindsym $mod+Shift+9 move container to workspace 9
+ bindsym $mod+Shift+0 move container to workspace 10
+ # Note: workspaces can have any name you want, not just numbers.
+ # We just use 1-10 as the default.
+#
+# Layout stuff:
+#
+ # You can "split" the current object of your focus with
+ # $mod+b or $mod+v, for horizontal and vertical splits
+ # respectively.
+ bindsym $mod+h splith
+ bindsym $mod+v splitv
+
+ # Switch the current container between different layout styles
+ bindsym $mod+s layout stacking
+ bindsym $mod+w layout tabbed
+ bindsym $mod+e layout toggle split
+
+ # Make the current focus fullscreen
+ bindsym $mod+f fullscreen
+
+ # Toggle the current focus between tiling and floating mode
+ bindsym $mod+space floating toggle
+
+ # Swap focus between the tiling area and the floating area
+ bindsym $mod+Shift+space focus mode_toggle
+
+ # Move focus to the parent container
+ bindsym $mod+a focus parent
+#
+# Scratchpad:
+#
+ # Sway has a "scratchpad", which is a bag of holding for windows.
+ # You can send windows there and get them back later.
+
+ # Move the currently focused window to the scratchpad
+ bindsym $mod+Shift+minus move scratchpad
+
+ # Show the next scratchpad window or hide the focused scratchpad window.
+ # If there are multiple scratchpad windows, this command cycles through them.
+ bindsym $mod+minus scratchpad show
+#
+# Resizing containers:
+#
+mode "resize" {
+ # left will shrink the containers width
+ # right will grow the containers width
+ # up will shrink the containers height
+ # down will grow the containers height
+ bindsym $left resize shrink width 10px
+ bindsym $down resize grow height 10px
+ bindsym $up resize shrink height 10px
+ bindsym $right resize grow width 10px
+
+ # Ditto, with arrow keys
+ #bindsym Left resize shrink width 10px
+ #bindsym Down resize grow height 10px
+ #bindsym Up resize shrink height 10px
+ #bindsym Right resize grow width 10px
+
+ # Return to default mode
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+bindsym $mod+r mode "resize"
+
+# class border backgr. text indicator child_border
+client.focused #000000 #ffffff #000000 #000000 #000000
+client.focused_inactive #000000 #eeeeee #000000 #000000 #000000
+client.unfocused #000000 #222222 #888888 #000000 #000000
+client.urgent #2f343a #900000 #ffffff #900000 #900000
+client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c
+
+client.background #ffffff
+
+font pango: Inter, Icons Bold 14
+
+#
+# Status Bar:
+#
+# Read `man 5 sway-bar` for more information about this section.
+#bar {
+# position top
+#
+# # When the status_command prints a new line to stdout, swaybar updates.
+# # The default just shows the current date and time.
+# status_command while ~/bin/status; do sleep 60; done
+#
+# colors {
+# statusline #ffffff
+# background #000000
+# focused_workspace #ffffff #ffffff #000000
+# active_workspace #ffffff #888888 #000000
+# inactive_workspace #000000 #000000 #ffffff
+# }
+#
+# font pango: Inter, Icons Bold Italic 14
+#}
+
+for_window [app_id="pavucontrol"] floating enable
+for_window [app_id="connman-gtk"] floating enable
+for_window [app_id="xfce4-appfinder"] floating enable
+
+include @sysconfdir@/sway/config.d/*
+
+# waybar
+exec /usr/local/bin/waybar
+
+# autostart gnome settings daemon
+exec /usr/libexec/gsd-xsettings
+
+# uncomment to have umlauts etc. on right alt
+#input "1003:8258:MNT_Reform_Keyboard" xkb_layout us-german-umlaut
+
+# start a policykit agent
+exec lxpolkit
+
+exec gsettings set org.gnome.desktop.interface font-name 'Inter 14'
+exec gsettings set org.gnome.desktop.interface monospace-font-name 'Iosevka Term Light 14'
+exec gsettings set org.gnome.desktop.interface gtk-theme 'Arc-Dark'
+
+exec gsettings set org.gnome.gedit.preferences.editor scheme 'cobalt'
+
+# autostart a terminal
+exec xfce4-terminal -e 'bash -c "reform-desktop-help; bash"'
+
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.config/waybar/config b/src/recipes/default/hook/data/overlay/etc/skel/.config/waybar/config
new file mode 100644
index 0000000..cfb595b
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.config/waybar/config
@@ -0,0 +1,66 @@
+{
+ // "layer": "top", // Waybar at top layer
+ // "position": "bottom", // Waybar position (top|bottom|left|right)
+ "height": 34, // Waybar height (to be removed for auto height)
+ // "width": 1280, // Waybar width
+ // Choose the order of the modules
+ "modules-left": ["sway/workspaces", "sway/mode", "sway/window"],
+ "modules-center": [],
+ "modules-right": ["tray", "network", "custom/stat", "memory", "temperature", "pulseaudio", "clock"],
+ "sway/window": {
+ "on-click": "xfce4-appfinder"
+ },
+ "sway/mode": {
+ "format": "{}"
+ },
+ "tray": {
+ "icon-size": 32,
+ "spacing": 16
+ },
+ "clock": {
+ "tooltip-format": "{:%Y %B}",
+ "format-alt": "{:%Y-%m-%d}",
+ "tooltip": false
+ },
+ "cpu": {
+ "format": "CPU {usage}%",
+ "tooltip": false
+ },
+ "memory": {
+ "format": "MEM {}%",
+ "tooltip": false
+ },
+ "temperature": {
+ "thermal-zone": 0,
+ // "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
+ "critical-threshold": 80,
+ // "format-critical": "{temperatureC}°C {icon}",
+ "format": "{temperatureC}°C"
+ },
+ "network": {
+ // "interface": "wlp2*", // (Optional) To force the use of this interface
+ "format-wifi": "NET {essid} {signalStrength}%",
+ "format-ethernet": "NET {ifname}: {ipaddr}/{cidr}",
+ "format-linked": "NET {ifname} NO IP",
+ "format-disconnected": "NET ×",
+ //"format-alt": "NET {ifname}: {ipaddr}/{cidr}"
+ "on-click": "reform-connman-gtk.sh"
+ },
+ "pulseaudio": {
+ // "scroll-step": 1,
+ "format": "VOL {volume}%",
+ "format-bluetooth": "{volume}% {icon} {format_source}",
+ "format-bluetooth-muted": " {icon} {format_source}",
+ "format-muted": "MUTED {format_source}",
+ "format-source": "{volume}%",
+ "format-source-muted": "MUTE",
+ "on-click": "reform-pavucontrol.sh"
+ },
+ "custom/stat": {
+ "format": "{}",
+ "max-length": 20,
+ "interval": 0,
+ "exec": "reform-compstat.sh",
+ "on-click": "gnome-system-monitor"
+ }
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.config/waybar/style.css b/src/recipes/default/hook/data/overlay/etc/skel/.config/waybar/style.css
new file mode 100644
index 0000000..bd2cfab
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.config/waybar/style.css
@@ -0,0 +1,44 @@
+* {
+ font-size: 18px;
+ font-family: Inter;
+ font-weight: bold;
+ border-radius: 0;
+}
+
+window#waybar {
+ background: #000000;
+ color: #ffffff;
+}
+
+#sway-mode {
+ background-color: #330000;
+}
+
+widget label {
+ padding: 0px 20px;
+}
+
+#workspaces label {
+ padding: 0px 0px;
+}
+
+#workspaces button {
+ color: #ffffff;
+ font-size: 20px;
+ font-style: italic;
+}
+#workspaces button.focused {
+ background: #ffffff;
+ color: #000000;
+}
+#workspaces button:hover {
+ box-shadow: inherit;
+ text-shadow: inherit;
+}
+#workspaces button:hover {
+ background: #888888;
+}
+
+#clock {
+ padding-right: 0px;
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.config/xfce4/terminal/terminalrc b/src/recipes/default/hook/data/overlay/etc/skel/.config/xfce4/terminal/terminalrc
new file mode 100644
index 0000000..8352332
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.config/xfce4/terminal/terminalrc
@@ -0,0 +1,37 @@
+[Configuration]
+MiscAlwaysShowTabs=FALSE
+MiscBell=FALSE
+MiscBellUrgent=FALSE
+MiscBordersDefault=TRUE
+MiscCursorBlinks=TRUE
+MiscCursorShape=TERMINAL_CURSOR_SHAPE_BLOCK
+MiscDefaultGeometry=80x24
+MiscInheritGeometry=FALSE
+MiscMenubarDefault=TRUE
+MiscMouseAutohide=FALSE
+MiscMouseWheelZoom=TRUE
+MiscToolbarDefault=FALSE
+MiscConfirmClose=TRUE
+MiscCycleTabs=TRUE
+MiscTabCloseButtons=TRUE
+MiscTabCloseMiddleClick=TRUE
+MiscTabPosition=GTK_POS_TOP
+MiscHighlightUrls=TRUE
+MiscMiddleClickOpensUri=FALSE
+MiscCopyOnSelect=FALSE
+MiscShowRelaunchDialog=TRUE
+MiscRewrapOnResize=TRUE
+MiscUseShiftArrowsToScroll=FALSE
+MiscSlimTabs=FALSE
+MiscNewTabAdjacent=FALSE
+MiscSearchDialogOpacity=100
+MiscShowUnsafePasteDialog=TRUE
+FontName=Iosevka Term Light 14
+ScrollingLines=10000
+TitleMode=TERMINAL_TITLE_REPLACE
+;
+; snazzy theme: https://github.com/tunnckoCore/xfce4-terminal-snazzy
+ColorBackground=#282a36
+ColorForeground=#ecf1f3
+ColorCursor=#ecf1f3
+ColorPalette=#2E3436;#ff5c57;#5af78e;#f3f99d;#57c7ff;#ff6ac1;#9aedfe;#f1f1f0;#686868;#ff5c57;#5af78e;#f3f99d;#57c7ff;#ff6ac1;#9aedfe;#f1f1f0
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.ircrc b/src/recipes/default/hook/data/overlay/etc/skel/.ircrc
new file mode 100644
index 0000000..6c154c5
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.ircrc
@@ -0,0 +1,3 @@
+/set INPUT_ENCODING UTF-8
+/set DISPLAY_ENCODING UTF-8
+/set IRC_ENCODING UTF-8
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/bin/gnome b/src/recipes/default/hook/data/overlay/etc/skel/.local/bin/gnome
new file mode 100755
index 0000000..da5f51b
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/bin/gnome
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# enable the connman integration (shell extension to manage network interfaces)
+gnome-shell-extension-tool -e gnome-extension-connman@jaakko.hannikainen.intel.com
+
+# fix Xwayland (and anything using modifiers) graphics problems
+gsettings set org.gnome.mutter experimental-features "['kms-modifiers']"
+# disable autosuspend, because we need to suspend with reform-standby only
+gsettings set org.gnome.desktop.session idle-delay 0
+
+# launch a GNOME session using mutter's wayland compositor
+export XDG_SESSION_TYPE=wayland
+dbus-run-session gnome-session
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/bin/reform-windowmaker b/src/recipes/default/hook/data/overlay/etc/skel/.local/bin/reform-windowmaker
new file mode 100755
index 0000000..36957f8
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/bin/reform-windowmaker
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# This is a script to demonstrate cage + Xwayland as a replacement for standalone Xorg.
+# You can modify this to launch classic X window managers / DEs.
+#
+# Note that you should disable any x11 compositors. I.e. to launch xfce4:
+# xfwm4 --compositor=off &
+# exec xfce4-session
+#
+
+DNUM=:0
+
+cage -- /usr/local/bin/Xwayland $DNUM -retro -noreset &
+
+export DISPLAY=$DNUM
+
+# idea lifted from https://gist.github.com/tullmann/476cc71169295d5c3fe6
+MAX=10
+CT=0
+while ! xdpyinfo >/dev/null 2>&1; do
+ sleep 0.50s
+ CT=$(( CT + 1 ))
+ if [ "$CT" -ge "$MAX" ]; then
+ LOG "FATAL: $0: Gave up waiting for X server $DISPLAY"
+ exit 11
+ fi
+done
+
+export WAYLAND_DISPLAY=null # Hack, but works
+export GDK_BACKEND=x11
+unset SDL_VIDEODRIVER
+
+exec wmaker
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/.uuid b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/.uuid
new file mode 100644
index 0000000..2207602
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/.uuid
@@ -0,0 +1 @@
+814db1b1-f4fc-4c51-b66a-c701f568cd8d
\ No newline at end of file
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Black.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Black.otf
new file mode 100644
index 0000000..8684287
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Black.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-BlackItalic.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-BlackItalic.otf
new file mode 100644
index 0000000..7001434
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-BlackItalic.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Bold.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Bold.otf
new file mode 100644
index 0000000..502bba3
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Bold.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-BoldItalic.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-BoldItalic.otf
new file mode 100644
index 0000000..a1f7d88
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-BoldItalic.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraBold.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraBold.otf
new file mode 100644
index 0000000..7410f73
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraBold.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraBoldItalic.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraBoldItalic.otf
new file mode 100644
index 0000000..7d451cb
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraBoldItalic.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraLight-BETA.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraLight-BETA.otf
new file mode 100644
index 0000000..6e9672f
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraLight-BETA.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraLightItalic-BETA.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraLightItalic-BETA.otf
new file mode 100644
index 0000000..e7789f9
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ExtraLightItalic-BETA.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Italic.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Italic.otf
new file mode 100644
index 0000000..4e2906e
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Italic.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Light-BETA.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Light-BETA.otf
new file mode 100644
index 0000000..80ee72b
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Light-BETA.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-LightItalic-BETA.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-LightItalic-BETA.otf
new file mode 100644
index 0000000..ba2cb1b
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-LightItalic-BETA.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Medium.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Medium.otf
new file mode 100644
index 0000000..6604db3
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Medium.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-MediumItalic.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-MediumItalic.otf
new file mode 100644
index 0000000..ea66c5a
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-MediumItalic.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Regular.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Regular.otf
new file mode 100644
index 0000000..fdb121d
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Regular.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-SemiBold.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-SemiBold.otf
new file mode 100644
index 0000000..78482e6
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-SemiBold.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-SemiBoldItalic.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-SemiBoldItalic.otf
new file mode 100644
index 0000000..e74b874
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-SemiBoldItalic.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Thin-BETA.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Thin-BETA.otf
new file mode 100644
index 0000000..90def70
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-Thin-BETA.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ThinItalic-BETA.otf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ThinItalic-BETA.otf
new file mode 100644
index 0000000..cc7419c
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (OTF)/Inter-ThinItalic-BETA.otf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/.uuid b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/.uuid
new file mode 100644
index 0000000..d90eb4d
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/.uuid
@@ -0,0 +1 @@
+e783b632-fd3f-493a-ad74-ca017985efa9
\ No newline at end of file
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Black.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Black.ttf
new file mode 100644
index 0000000..5071b12
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Black.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-BlackItalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-BlackItalic.ttf
new file mode 100644
index 0000000..6a3acd1
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-BlackItalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Bold.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Bold.ttf
new file mode 100644
index 0000000..cc065b6
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Bold.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-BoldItalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-BoldItalic.ttf
new file mode 100644
index 0000000..503b9e0
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-BoldItalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraBold.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraBold.ttf
new file mode 100644
index 0000000..e244ac9
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraBold.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraBoldItalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraBoldItalic.ttf
new file mode 100644
index 0000000..1114885
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraBoldItalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraLight-BETA.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraLight-BETA.ttf
new file mode 100644
index 0000000..e49f4d9
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraLight-BETA.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraLightItalic-BETA.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraLightItalic-BETA.ttf
new file mode 100644
index 0000000..4c84fe4
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ExtraLightItalic-BETA.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Italic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Italic.ttf
new file mode 100644
index 0000000..598db24
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Italic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Light-BETA.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Light-BETA.ttf
new file mode 100644
index 0000000..81f5626
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Light-BETA.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-LightItalic-BETA.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-LightItalic-BETA.ttf
new file mode 100644
index 0000000..e5e4538
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-LightItalic-BETA.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Medium.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Medium.ttf
new file mode 100644
index 0000000..5fb476d
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Medium.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-MediumItalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-MediumItalic.ttf
new file mode 100644
index 0000000..e8a7259
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-MediumItalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Regular.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Regular.ttf
new file mode 100644
index 0000000..8c04c5b
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Regular.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-SemiBold.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-SemiBold.ttf
new file mode 100644
index 0000000..af40294
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-SemiBold.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-SemiBoldItalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-SemiBoldItalic.ttf
new file mode 100644
index 0000000..894a65f
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-SemiBoldItalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Thin-BETA.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Thin-BETA.ttf
new file mode 100644
index 0000000..b6ba236
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-Thin-BETA.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ThinItalic-BETA.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ThinItalic-BETA.ttf
new file mode 100644
index 0000000..1df838c
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Inter (TTF)/Inter-ThinItalic-BETA.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/.uuid b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/.uuid
new file mode 100644
index 0000000..e9cc423
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/.uuid
@@ -0,0 +1 @@
+3cb7a8ba-f529-40b0-b27f-20335c73b69e
\ No newline at end of file
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-bold.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-bold.ttf
new file mode 100644
index 0000000..f202882
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-bold.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-bolditalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-bolditalic.ttf
new file mode 100644
index 0000000..c6a39df
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-bolditalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-boldoblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-boldoblique.ttf
new file mode 100644
index 0000000..3e8b74f
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-boldoblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extrabold.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extrabold.ttf
new file mode 100644
index 0000000..8d75261
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extrabold.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extrabolditalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extrabolditalic.ttf
new file mode 100644
index 0000000..996dc10
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extrabolditalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extraboldoblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extraboldoblique.ttf
new file mode 100644
index 0000000..f55aef1
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extraboldoblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralight.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralight.ttf
new file mode 100644
index 0000000..2db05a1
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralight.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralightitalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralightitalic.ttf
new file mode 100644
index 0000000..a2d59d6
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralightitalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralightoblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralightoblique.ttf
new file mode 100644
index 0000000..014d8cd
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-extralightoblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavy.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavy.ttf
new file mode 100644
index 0000000..2f018c0
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavy.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavyitalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavyitalic.ttf
new file mode 100644
index 0000000..b648736
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavyitalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavyoblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavyoblique.ttf
new file mode 100644
index 0000000..0c6e153
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-heavyoblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-italic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-italic.ttf
new file mode 100644
index 0000000..f3b67b6
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-italic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-light.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-light.ttf
new file mode 100644
index 0000000..c1b4e56
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-light.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-lightitalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-lightitalic.ttf
new file mode 100644
index 0000000..7870f55
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-lightitalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-lightoblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-lightoblique.ttf
new file mode 100644
index 0000000..0b7723e
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-lightoblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-medium.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-medium.ttf
new file mode 100644
index 0000000..908b93e
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-medium.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-mediumitalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-mediumitalic.ttf
new file mode 100644
index 0000000..059110b
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-mediumitalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-mediumoblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-mediumoblique.ttf
new file mode 100644
index 0000000..80dd361
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-mediumoblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-oblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-oblique.ttf
new file mode 100644
index 0000000..298b3bc
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-oblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-regular.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-regular.ttf
new file mode 100644
index 0000000..7fe718a
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-regular.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semibold.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semibold.ttf
new file mode 100644
index 0000000..f351ec2
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semibold.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semibolditalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semibolditalic.ttf
new file mode 100644
index 0000000..f81c47c
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semibolditalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semiboldoblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semiboldoblique.ttf
new file mode 100644
index 0000000..fd87780
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-semiboldoblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thin.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thin.ttf
new file mode 100644
index 0000000..0d3a438
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thin.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thinitalic.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thinitalic.ttf
new file mode 100644
index 0000000..0397ba7
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thinitalic.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thinoblique.ttf b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thinoblique.ttf
new file mode 100644
index 0000000..40ff34c
Binary files /dev/null and b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/fonts/Iosevka-Term/iosevka-term-thinoblique.ttf differ
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/agent.js b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/agent.js
new file mode 100644
index 0000000..ea98238
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/agent.js
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ * Author: Jaakko Hannikainen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+const Lang = imports.lang;
+
+const Clutter = imports.gi.Clutter;
+const GLib = imports.gi.GLib;
+const St = imports.gi.St;
+const Pango = imports.gi.Pango;
+const GObject = imports.gi.GObject;
+
+const ModalDialog = imports.ui.modalDialog;
+const ShellEntry = imports.ui.shellEntry;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Ext = ExtensionUtils.getCurrentExtension();
+const Interface = Ext.imports.interface;
+const Logger = Ext.imports.logger;
+
+const Gettext = imports.gettext.domain('gnome-extension-connman');
+const _ = Gettext.gettext;
+
+var DialogField = class DialogField {
+
+ constructor(label) {
+ this.addLabel(label);
+ this.addEntry();
+ }
+
+ addLabel(label) {
+ this.label = new St.Label({
+ style_class: 'cm-prompt-dialog-password-label',
+ text: label,
+ x_align: Clutter.ActorAlign.START,
+ y_align: Clutter.ActorAlign.CENTER
+ });
+ this.label.clutter_text.ellipsize = Pango.EllipsizeMode.NONE;
+ }
+
+ addEntry() {
+ this.entry = new St.PasswordEntry({
+ style_class: 'cm-prompt-dialog-password-entry',
+ can_focus: true,
+ reactive: true,
+ x_expand: true
+ });
+ ShellEntry.addContextMenu(this.entry);
+ this.entry.clutter_text.set_password_char('\u25cf');
+ }
+
+ getLabel() {
+ return this.label.text;
+ }
+
+ getValue() {
+ return this.entry.get_text();
+ }
+
+ valid() {
+ return true;
+ }
+};
+
+var Dialog = GObject.registerClass(class Dialog extends ModalDialog.ModalDialog {
+
+ _init(fields, callback) {
+ super._init({
+ styleClass: 'cm-prompt-dialog'
+ });
+ this._fields = [];
+ this._callback = callback;
+ let mainContentBox = new St.BoxLayout({
+ style_class: 'cm-prompt-dialog-main-layout',
+ vertical: false
+ });
+ let icon = new St.Icon({
+ icon_name: 'dialog-password-symbolic'
+ });
+ let messageBox = new St.BoxLayout({
+ style_class: 'cm-prompt-dialog-message-layout',
+ vertical: true,
+ x_expand: true
+ });
+ let subjectLabel = new St.Label({
+ style_class: 'cm-prompt-dialog-headline headline',
+ text: _("Connection requires authentication")
+ });
+
+ icon.x_fill = true;
+ icon.y_fill = true;
+ icon.x_align = St.Align.END;
+ icon.y_align = St.Align.START;
+ messageBox.y_align = true;
+
+ mainContentBox.add_child(icon);
+ mainContentBox.add_child(messageBox);
+
+ subjectLabel.x_fill = true;
+ subjectLabel.y_fill = false;
+ subjectLabel.y_align = St.Align.START;
+
+ messageBox.add_child(subjectLabel);
+
+ mainContentBox.x_fill = true;
+ mainContentBox.y_fill = true;
+
+ this.contentLayout.add_child(mainContentBox);
+
+ let layout = new Clutter.GridLayout({
+ orientation: Clutter.Orientation.VERTICAL
+ });
+ let secretTable = new St.Widget({
+ style_class: 'cm-network-dialog-secret-table',
+ layout_manager: layout
+ });
+ layout.hookup_style(secretTable);
+ for(let i = 0; i < fields.length; i++) {
+ let field = fields[i];
+ layout.attach(field.label, 0, i, 1, 1);
+ layout.attach(field.entry, 1, i, 1, 1);
+ this._fields[i] = field;
+ }
+ messageBox.add(secretTable);
+
+ this._okButton = {
+ label: _("Connect"),
+ action: this._onOk.bind(this),
+ default: true
+ };
+ this._cancelButton = {
+ label: _("Cancel"),
+ action: this._onCancel.bind(this),
+ key: Clutter.KEY_Escape
+ };
+ this.setButtons([this._cancelButton, this._okButton]);
+ this.open();
+ }
+
+ _onOk() {
+ this.close();
+ if(!this._fields.reduce(function(a, b) {
+ return a && b.valid()
+ }, true))
+ return;
+ let values = {};
+ Object.keys(this._fields).map(function(key) {
+ values[this._fields[key].getLabel()] = this._fields[key].getValue();
+ }.bind(this));
+ this._callback(values);
+ }
+
+ _onCancel() {
+ this.close();
+ this._callback();
+ }
+});
+
+var AbstractAgent = class AbstractAgent {
+
+ constructor() {
+ }
+
+ Release() {
+ this.destroy();
+ }
+
+ ReportErrorAsync([service, error], invocation) {
+ Logger.logDebug('Service reported error: ' + error);
+ invocation.return_dbus_error(this._retryError, '');
+ }
+
+ RequestInputAsync([service, _fields], invocation) {
+ Logger.logDebug('Requested password');
+ var fields = _fields;
+ fields = Object.keys(_fields)
+ .map(function(key) {
+ fields[key] = fields[key].deep_unpack();
+ Object.keys(fields[key]).map(function(innerKey) {
+ fields[key][innerKey] = fields[key][innerKey].deep_unpack();
+ });
+ return [key, fields[key]];
+ });
+ let dialogFields = [];
+ for(let i = 0; i < fields.length; i++)
+ if(fields[i][1]['Requirement'] == 'mandatory')
+ dialogFields.push(new DialogField(fields[i][0]));
+
+ let callback = function(fields) {
+ if(!fields) {
+ invocation.return_dbus_error(this._canceledError,
+ 'User canceled password dialog');
+ return;
+ }
+ Object.keys(fields).map(function(key) {
+ fields[key] = GLib.Variant.new('s', fields[key]);
+ });
+ invocation.return_value(GLib.Variant.new('(a{sv})', [fields]));
+ }.bind(this);
+ this._dialog = new Dialog(dialogFields, callback);
+ }
+
+ Cancel(params, invocation) {
+ Logger.logDebug('Password dialog canceled');
+ this._dialog._onCancel();
+ this._dialog = null;
+ }
+
+ destroy() {
+ if(this._dialog)
+ this._dialog._onCancel();
+ this._dialog = null;
+ }
+};
+
+var Agent = class Agent extends AbstractAgent {
+
+ constructor() {
+ super();
+ this._dbusImpl = Interface.addAgentImplementation(this);
+ this._canceledError = 'net.connman.Agent.Error.Canceled';
+ this._retryError = 'net.connman.Agent.Error.Retry';
+ }
+
+ RequestBrowser(service, url) {
+ Logger.logDebug('Requested browser');
+ }
+
+ destroy() {
+ super.destroy();
+ Interface.removeAgentImplementation(this._dbusImpl);
+ }
+};
+
+var VPNAgent = class VPNAgent extends AbstractAgent {
+
+ constructor() {
+ super();
+ this._dbusImpl = Interface.addVPNAgentImplementation(this);
+ this._canceledError = 'net.connman.vpn.Agent.Error.Canceled';
+ this._retryError = 'net.connman.vpn.Agent.Error.Retry';
+ }
+
+ destroy() {
+ super.destroy();
+ Interface.removeVPNAgentImplementation(this._dbusImpl);
+ }
+};
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/applet.js b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/applet.js
new file mode 100644
index 0000000..8ff2e3a
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/applet.js
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ * Author: Jaakko Hannikainen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+const Lang = imports.lang;
+
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
+const GObject = imports.gi.GObject;
+
+const PanelMenu = imports.ui.panelMenu;
+const PopupMenu = imports.ui.popupMenu;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Ext = ExtensionUtils.getCurrentExtension();
+const Agent = Ext.imports.agent;
+const Interface = Ext.imports.interface;
+const Logger = Ext.imports.logger;
+const Service = Ext.imports.service;
+const Technology = Ext.imports.technology;
+
+/* menu with technologies and services */
+var Menu = class extends PopupMenu.PopupMenuSection {
+
+ constructor(params) {
+ super(params);
+ this._technologies = {};
+ this._serviceTypes = {};
+ }
+
+ hide() {
+ this.actor.hide();
+ }
+
+ show() {
+ this.actor.show();
+ }
+
+ _addSorted(technology) {
+ let items = this._getMenuItems();
+ for(let i = 0; i < items.length; i++) {
+ if(items[i].getValue() < technology.getValue())
+ continue;
+ this.addMenuItem(technology, i);
+ return;
+ }
+ this.addMenuItem(technology);
+ }
+
+ addTechnology(path, properties) {
+ let type = properties.Type.deep_unpack();
+ if(this._technologies[type])
+ this.removeTechnology(path);
+ let proxy = new Interface.TechnologyProxy(path);
+ for(let i in properties)
+ properties[i] = properties[i].deep_unpack();
+ try {
+ this._technologies[type] = Technology.createTechnology(type,
+ properties, proxy, this._manager);
+ } catch(error) {
+ Logger.logException(error, 'Failed to add technology');
+ return;
+ }
+ this._addSorted(this._technologies[type]);
+ }
+
+ /* FIXME: for some reason destroying an item from the menu
+ * leaves a hole, but for some reason this fixes it */
+ fixMenu() {
+ this.addMenuItem(new PopupMenu.PopupMenuItem('Connman'), 0);
+ this.firstMenuItem.destroy();
+ }
+
+ removeTechnology(path) {
+ let type = path.split('/').pop();
+ Logger.logInfo('Removing technology ' + type);
+ let technology = this._technologies[type];
+ if(!technology) {
+ Logger.logInfo('Tried to remove unknown technology ' + type);
+ return;
+ }
+ technology.destroy();
+ delete this._technologies[type];
+ this.fixMenu();
+ }
+
+ getService(path) {
+ if(!this._serviceTypes[path])
+ return null;
+ if(!this._technologies[this._serviceTypes[path]])
+ return null;
+ return this._technologies[this._serviceTypes[path]].getService(path);
+ }
+
+ addService(path, properties, indicator) {
+ if (!('Type' in properties)) return;
+ let type;
+ if(properties.Type.deep_unpack) {
+ type = properties.Type.deep_unpack();
+ if(type == 'vpn') {
+ indicator.destroy();
+ return;
+ }
+ }
+ else {
+ type = 'vpn';
+ properties.Type = {deep_unpack: function() {
+ return 'vpn';
+ }};
+ }
+ this._serviceTypes[path] = type;
+
+ let proxy;
+ if(type != 'vpn')
+ proxy = new Interface.ServiceProxy(path);
+ else
+ proxy = new Interface.ConnectionProxy(path);
+ let service = Service.createService(type, proxy, indicator);
+ service.update(properties);
+ this._technologies[type].addService(path, service);
+ }
+
+ updateService(path, properties) {
+ if(this._serviceTypes[path]) {
+ var type = this._serviceTypes[path];
+ this._technologies[type].updateService(path, properties);
+ return;
+ } else
+ this.addService(path, properties);
+ }
+
+ removeService(path) {
+ if(!this._serviceTypes[path]) {
+ log('Tried to remove unknown service ' + path);
+ return;
+ }
+ if(this._technologies[this._serviceTypes[path]]) {
+ log('Removing service ' + path);
+ this._technologies[this._serviceTypes[path]].removeService(path);
+ }
+ delete this._serviceTypes[path];
+ this.fixMenu();
+ }
+
+ clear() {
+ for(let type in this._technologies) {
+ try {
+ if(type != "vpn") {
+ this._technologies[type].destroy();
+ delete this._technologies[type];
+ }
+ } catch(error) {
+ Logger.logException(error, 'Failed to clear technology ' + type);
+ }
+ }
+ }
+
+ vpnClear() {
+ if(!this._technologies["vpn"])
+ return;
+ try {
+ this._technologies["vpn"].destroy();
+ delete this._technologies["vpn"];
+ } catch(error) {
+ Logger.logException(error, 'Failed to clear VPN connections');
+ }
+ }
+};
+
+/* main applet class handling everything */
+var Applet = GObject.registerClass(class Applet extends PanelMenu.SystemIndicator {
+
+ _init() {
+ super._init();
+
+ this._menu = new Menu();
+ this.menu.addMenuItem(this._menu);
+ this.menu.actor.show();
+
+ log('Enabling Connman applet');
+ this._watch = Gio.DBus.system.watch_name(Interface.BUS_NAME,
+ Gio.BusNameWatcherFlags.NONE,
+ this._connectEvent.bind(this),
+ this._disconnectEvent.bind(this));
+ this._vpnwatch = Gio.DBus.system.watch_name(Interface.VPN_BUS_NAME,
+ Gio.BusNameWatcherFlags.NONE,
+ this._vpnConnectEvent.bind(this),
+ this._vpnDisconnectEvent.bind(this));
+ }
+
+ _addIndicator() {
+ let indicator = super._addIndicator();
+ indicator.hide();
+ return indicator;
+ }
+
+ _updateService(path, properties) {
+ if(path.indexOf("service/vpn") != -1)
+ return;
+ if(this._menu.getService(path))
+ this._menu.updateService(path, properties);
+ else
+ this._menu.addService(path, properties, this._addIndicator());
+ }
+
+ _updateAllServices() {
+ this._manager.GetServicesRemote(function(result, exception) {
+ if(!result || exception) {
+ Logger.logError('Error fetching services: ' + exception);
+ return;
+ }
+ let services = result[0];
+ for (var o of services)
+ this._updateService(o[0], o[1]);
+
+ }.bind(this));
+ }
+
+ _updateAllTechnologies() {
+ this._menu.clear();
+ this._manager.GetTechnologiesRemote(function(result, exception) {
+ if(!result || exception) {
+ Logger.logError('Error fetching technologies: ' + exception);
+ return;
+ }
+ let technologies = result[0];
+ for (var o of technologies)
+ this._menu.addTechnology(o[0], o[1]);
+ this._updateAllServices();
+ }.bind(this));
+ }
+
+ _updateAllConnections() {
+ this._menu.vpnClear();
+
+ this._menu._technologies['vpn'] = Technology.createTechnology('vpn',
+ {Powered: true});
+ this._menu.addMenuItem(this._menu._technologies['vpn']);
+
+ this._vpnManager.GetConnectionsRemote(function(result, exception) {
+ if(!result || exception) {
+ Logger.logError('Error fetching VPN connections: ' + exception);
+ return;
+ }
+ let connections = result[0];
+ for (var o of connections) {
+ o[1]['Type'] = 'vpn';
+ this._menu.addService(o[0], o[1], this._addIndicator());
+ }
+ }.bind(this));
+ }
+
+ _updateVisibility() {
+ if(this._manager || this._vpnManager) {
+ this.menu.actor.show();
+ //this.indicators.show();
+ }
+ else {
+ this.menu.actor.hide();
+ //this.indicators.hide();
+ }
+ }
+
+ _connectEvent() {
+ Logger.logInfo('Connected to Connman');
+
+ this._manager = new Interface.ManagerProxy();
+ this._menu._manager = this._manager;
+ this._agent = new Agent.Agent();
+
+ this._manager.RegisterAgentRemote(Interface.AGENT_PATH);
+ this._asig = this._manager.connectSignal('TechnologyAdded',
+ function(proxy, sender, o) {
+ try {
+ this._menu.addTechnology(o[0], o[1]);
+ } catch(error) {
+ Logger.logException(error);
+ }
+ }.bind(this));
+ this._rsig = this._manager.connectSignal('TechnologyRemoved',
+ function(proxy, sender, [path, properties]) {
+ this._menu.removeTechnology(path);
+ }.bind(this));
+ this._psig = this._manager.connectSignal('PropertyChanged',
+ function(proxy, sender, [property, value]) {
+ Logger.logDebug('Global property ' + property +
+ ' changed: ' + value.deep_unpack());
+ }.bind(this));
+ this._ssig = this._manager.connectSignal('ServicesChanged',
+ function(proxy, sender, [changed, removed]) {
+ try {
+ for (var o of changed)
+ this._updateService(o[0], o[1]);
+ for (var path of removed)
+ this._menu.removeService(path);
+ } catch(error) {
+ Logger.logException(error);
+ }
+ }.bind(this));
+
+ this._updateAllTechnologies();
+ this._updateVisibility();
+ }
+
+ _vpnConnectEvent() {
+ this._vpnManager = new Interface.VPNManagerProxy();
+ this._vpnAgent = new Agent.VPNAgent();
+ this._vpnManager.RegisterAgentRemote(Interface.VPN_AGENT_PATH);
+ this._updateVisibility();
+
+ this._vasig = this._vpnManager.connectSignal('ConnectionAdded',
+ function(proxy, sender, [path, properties]) {
+ try {
+ properties['Type'] = 'vpn';
+ this._menu.addService(path, properties, this._addIndicator());
+ } catch(error) {
+ Logger.logException(error);
+ }
+ }.bind(this));
+ this._vrsig = this._vpnManager.connectSignal('ConnectionRemoved',
+ function(proxy, sender, [path, properties]) {
+ this._menu.removeService(path);
+ }.bind(this));
+
+ this._updateAllConnections();
+ }
+
+ _vpnDisconnectEvent() {
+ let signals = [this._vasig, this._vrsig];
+ if(this._vpnManager) {
+ Logger.logDebug('Disconnecting vpn signals');
+ for(let signalId in signals) {
+ try {
+ Logger.logDebug('Disconnecting signal ' + signals[signalId]);
+ this._vpnManager.disconnectSignal(signals[signalId]);
+ } catch(error) {
+ Logger.logException(error, 'Failed to disconnect signal');
+ }
+ }
+ }
+ try {
+ if(this._vpnManager)
+ this._vpnManager.UnregisterAgentRemote(Interface.VPN_AGENT_PATH);
+ } catch(error) {
+ Logger.logException(error, 'Failed to unregister vpn agent');
+ }
+ this._vpnManager = null;
+ if(this._vpnAgent)
+ this._vpnAgent.destroy();
+ this.vpnAgent = null;
+ this._updateVisibility();
+ }
+
+ _disconnectEvent() {
+ Logger.logInfo('Disconnected from Connman');
+ this._menu.clear();
+ this._menu._manager = null;
+ let signals = [this._asig, this._rsig, this._ssig, this._psig];
+ if(this._manager) {
+ Logger.logDebug('Disconnecting signals');
+ for(let signalId in signals) {
+ try {
+ Logger.logDebug('Disconnecting signal ' + signals[signalId]);
+ this._manager.disconnectSignal(signals[signalId]);
+ } catch(error) {
+ Logger.logException(error, 'Failed to disconnect signal');
+ }
+ }
+ }
+ try {
+ this._manager.UnregisterAgentRemote(Interface.AGENT_PATH);
+ } catch(error) {
+ }
+ this._manager = null;
+ if(this._agent)
+ this._agent.destroy();
+ this._agent = null;
+ this._updateVisibility();
+ }
+
+ destroy() {
+ Logger.logInfo('Destroying Connman applet');
+ this._disconnectEvent();
+ this._menu.clear();
+ //this.indicators.destroy();
+ this.menu.actor.destroy();
+ if(this._watch)
+ Gio.DBus.system.unwatch_name(this._watch);
+ if(this._vpnwatch)
+ Gio.DBus.system.unwatch_name(this._vpnwatch);
+ if(this._agent)
+ this._agent.destroy();
+ if(this._vpnAgent)
+ this._vpnAgent.destroy();
+ this._agent = null;
+ this._vpnAgent = null;
+ this._watch = null;
+ }
+});
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/extension.js b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/extension.js
new file mode 100644
index 0000000..35249e5
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/extension.js
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ * Author: Jaakko Hannikainen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+const Lang = imports.lang;
+
+const Main = imports.ui.main;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Ext = ExtensionUtils.getCurrentExtension();
+const Applet = Ext.imports.applet;
+
+let applet;
+let menu = Main.panel.statusArea.aggregateMenu;
+
+function init() {
+}
+
+function enable() {
+ applet = new Applet.Applet();
+ // XXX: Magic numbers
+ menu.menu.addMenuItem(applet.menu, 3);
+ menu._indicators.insert_child_at_index(applet.indicators, 3);
+}
+
+function disable() {
+ if(applet)
+ applet.destroy();
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/interface.js b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/interface.js
new file mode 100644
index 0000000..33f0f7d
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/interface.js
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ * Author: Jaakko Hannikainen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+const Gio = imports.gi.Gio;
+
+var BUS_NAME = 'net.connman';
+var VPN_BUS_NAME = 'net.connman.vpn';
+var MANAGER_PATH = '/';
+var AGENT_PATH = '/net/connman/gnome3/agent';
+var VPN_AGENT_PATH = '/net/connman/gnome3/vpn/agent';
+
+const _MANAGER_INTERFACE = '\
+\
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+\
+';
+
+const _TECHNOLOGY_INTERFACE = '\
+\
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+\
+';
+
+const _SERVICE_INTERFACE = '\
+\
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+\
+';
+
+const _AGENT_INTERFACE = '\
+\
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+\
+';
+
+const _CONNECTION_INTERFACE = '\
+\
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+\
+';
+
+
+const _VPN_MANAGER_INTERFACE = '\
+\
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+\
+';
+
+const _VPN_AGENT_INTERFACE = '\
+\
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+\
+';
+
+const _ManagerProxyWrapper = Gio.DBusProxy.makeProxyWrapper(_MANAGER_INTERFACE);
+const _TechnologyProxyWrapper = Gio.DBusProxy.makeProxyWrapper(_TECHNOLOGY_INTERFACE);
+const _ServiceProxyWrapper = Gio.DBusProxy.makeProxyWrapper(_SERVICE_INTERFACE);
+const _ConnectionProxyWrapper = Gio.DBusProxy.makeProxyWrapper(_CONNECTION_INTERFACE);
+const _VPNManagerProxyWrapper = Gio.DBusProxy.makeProxyWrapper(_VPN_MANAGER_INTERFACE);
+
+function ManagerProxy() {
+ return new _ManagerProxyWrapper(Gio.DBus.system, BUS_NAME, MANAGER_PATH);
+}
+
+function VPNManagerProxy() {
+ return new _VPNManagerProxyWrapper(Gio.DBus.system, VPN_BUS_NAME, MANAGER_PATH);
+}
+
+function TechnologyProxy(path) {
+ return new _TechnologyProxyWrapper(Gio.DBus.system, BUS_NAME, path);
+}
+
+function ServiceProxy(path) {
+ return new _ServiceProxyWrapper(Gio.DBus.system, BUS_NAME, path);
+}
+
+function ConnectionProxy(path) {
+ return new _ConnectionProxyWrapper(Gio.DBus.system, VPN_BUS_NAME, path);
+}
+
+function addAgentImplementation(agent) {
+ let dbusImpl = Gio.DBusExportedObject.wrapJSObject(_AGENT_INTERFACE, agent);
+ dbusImpl.export(Gio.DBus.system, AGENT_PATH);
+ return dbusImpl;
+}
+
+function removeAgentImplementation(dbusImpl) {
+ dbusImpl.unexport(Gio.DBus.system, AGENT_PATH);
+}
+
+function addVPNAgentImplementation(agent) {
+ let dbusImpl = Gio.DBusExportedObject.wrapJSObject(_VPN_AGENT_INTERFACE, agent);
+ dbusImpl.export(Gio.DBus.system, VPN_AGENT_PATH);
+ return dbusImpl;
+}
+
+function removeVPNAgentImplementation(dbusImpl) {
+ dbusImpl.unexport(Gio.DBus.system, VPN_AGENT_PATH);
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/logger.js b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/logger.js
new file mode 100644
index 0000000..1261d31
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/logger.js
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ * Author: Jaakko Hannikainen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+const Lang = imports.lang;
+
+var enabled = true;
+var logLevel = 2;
+var infoEnabled = true;
+
+function logMessage(msg) {
+ log('Connman-applet: ' + msg);
+}
+
+function logError(error) {
+ logMessage('ERROR: ' + error);
+}
+
+function logException(exception, msg) {
+ if(msg)
+ logMessage('Exception: ' + msg);
+ logMessage('Exception: ' + exception + ': ' + exception.stack);
+}
+
+function logWarning(error) {
+ if(loglevel > 1)
+ logMessage('WARNING: ' + error);
+}
+
+function logInfo(msg) {
+ if(logLevel > 2)
+ logMessage('INFO: ' + msg);
+}
+
+function logDebug(msg) {
+ if(logLevel > 3)
+ logMessage('DEBUG: ' + msg);
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/metadata.json b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/metadata.json
new file mode 100644
index 0000000..f9488cc
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/metadata.json
@@ -0,0 +1,7 @@
+{
+ "uuid": "gnome-extension-connman@jaakko.hannikainen.intel.com",
+ "name": "ConnMan Extension",
+ "description": "Gnome-Shell ConnMan extension",
+ "shell-version": ["3.14", "3.16", "3.18", "3.20"],
+ "url": "https://github.com/mntmn/gnome-extension-connman"
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/service.js b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/service.js
new file mode 100644
index 0000000..682f530
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/service.js
@@ -0,0 +1,582 @@
+/*
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ * Author: Jaakko Hannikainen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+const Lang = imports.lang;
+const Mainloop = imports.mainloop;
+const Signals = imports.signals;
+
+const Clutter = imports.gi.Clutter;
+const Gtk = imports.gi.Gtk;
+const St = imports.gi.St;
+const GObject = imports.gi.GObject;
+
+const Util = imports.misc.util;
+
+const PopupMenu = imports.ui.popupMenu;
+const ModalDialog = imports.ui.modalDialog;
+const Dialog = imports.ui.dialog;
+
+const Gettext = imports.gettext.domain('gnome-extension-connman');
+const _ = Gettext.gettext;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Ext = ExtensionUtils.getCurrentExtension();
+const Version = Ext.imports.version;
+const version = Version.version();
+
+const Logger = Ext.imports.logger;
+
+const DialogServiceItem = class DialogServiceItem {
+
+ constructor(service, callback) {
+ let name = service.name || service.label.text;
+ if(!name)
+ return;
+ let icon = service.getIcon();
+ let securityIcon = service.securityIcon ? service.securityIcon() : '';
+ this.service = service;
+ this.actor = new St.BoxLayout({
+ style_class: 'cm-dialog-item',
+ can_focus: true,
+ reactive: true
+ });
+ this.actor.connect('key-focus-in', function() {
+ callback(this);
+ }.bind(this));
+ let action = new Clutter.ClickAction();
+ action.connect('clicked', function() {
+ this.actor.grab_key_focus();
+ }.bind(this));
+ this.actor.add_action(action);
+
+ this._label = new St.Label({
+ text: name
+ });
+ this.actor.label_actor = this._label;
+ this._icons = new St.BoxLayout({
+ style_class: 'cm-dialog-icons'
+ });
+ this._icon = new St.Icon({
+ style_class: 'cm-dialog-icon'
+ });
+ this._securityIcon = new St.Icon({
+ style_class: 'cm-dialog-icon'
+ });
+ this._icon.icon_name = icon;
+ this._securityIcon.icon_name = securityIcon;
+ if(service._properties['Favorite']) {
+ let icon = new St.Icon({
+ style_class: 'cm-dialog-icon',
+ icon_name: 'object-select-symbolic'
+ });
+ icon.add_style_pseudo_class('favourite');
+ this.actor.add_style_pseudo_class('favourite');
+ this.actor.add(icon);
+ }
+ this._icons.add_actor(this._securityIcon);
+ this._icons.add_actor(this._icon);
+ this._label.x_align = St.Align.START;
+ this.actor.add_child(this._label);
+ this._icons.expand = true;
+ this._icons.x_fill = true;
+ this._icons.x_align = St.Align.END;
+ this.actor.add_child(this._icons);
+ }
+
+ enable() {
+ this.actor.can_focus = true;
+ this.actor.reactive = true;
+ this.actor.remove_style_pseudo_class('passive');
+ }
+
+ disable() {
+ this.actor.can_focus = false;
+ this.actor.reactive = false;
+ this.actor.add_style_pseudo_class('passive');
+ }
+};
+
+var ServiceChooser = GObject.registerClass(class ServiceChooser extends ModalDialog.ModalDialog {
+
+ _init(proxy, services, callback) {
+ super._init({});
+ this._proxy = proxy;
+ this._services = {};
+
+ let content = new Dialog.MessageDialogContent({ title: _('Select Wireless Network') });
+ this.contentLayout.add_actor(content);
+
+ this._stack = new St.Widget({
+ layout_manager: new Clutter.BinLayout()
+ });
+ this._itemBox = new St.BoxLayout({
+ vertical: true,
+ style_class: 'cm-dialog-box'
+ });
+ this._boxes = {};
+ this._scrollView = new St.ScrollView({
+ style_class: 'cm-dialog-scroll-view'
+ });
+ this._scrollView.set_x_expand(true);
+ this._scrollView.set_y_expand(true);
+ this._scrollView.set_policy(Gtk.PolicyType.NEVER,
+ Gtk.PolicyType.AUTOMATIC);
+ this._scrollView.add_actor(this._itemBox);
+ this._stack.add_child(this._scrollView);
+
+ this.contentLayout.x_expand = true;
+ this.contentLayout.add_child(this._stack);
+
+ for(let id in services)
+ this.addService(services[id]);
+ this.scanRemote();
+ this._closed = false;
+ this._timeout = Mainloop.timeout_add_seconds(15, function() {
+ this.scanRemote();
+ return !this._closed;
+ }.bind(this));
+
+ this._cancelButton = this.addButton({
+ action: this.cancel.bind(this),
+ label: _("Cancel"),
+ key: Clutter.Escape
+ });
+
+ this._connectButton = this.addButton({
+ action: this.buttonEvent.bind(this),
+ label: _("Connect"),
+ key: Clutter.Enter
+ });
+ this._connectButton.reactive = true;
+ this._connectButton.can_focus = true;
+
+ this._callback = callback;
+
+ this.open();
+ }
+
+ scanRemote() {
+ this._proxy.ScanRemote();
+ }
+
+ selectedEvent(service) {
+ if(this._selected)
+ this._selected.actor.remove_style_pseudo_class('selected');
+ Util.ensureActorVisibleInScrollView(this._scrollView, service.actor);
+ this._selected = service;
+ this._selected.actor.add_style_pseudo_class('selected');
+ this._connectButton.reactive = true;
+ this._connectButton.can_focus = true;
+ }
+
+ close() {
+ super.close();
+ this._closed = true;
+ Mainloop.source_remove(this._timeout);
+ this.destroy();
+ }
+
+ buttonEvent() {
+ this.close();
+ this._callback(this._selected && this._selected.service);
+ }
+
+ cancel() {
+ this._callback();
+ this.close();
+ }
+
+ addService(service) {
+ if(this._services[service[0].id]) {
+ this._services[service[0].id].enable();
+ return;
+ }
+ let item = new DialogServiceItem(service[0], this.selectedEvent.bind(this));
+ if(!item.actor)
+ return;
+ let intf = service[1];
+ if(!this._boxes[intf]) {
+ if(Object.keys(this._boxes).length == 1)
+ this._boxes[Object.keys(this._boxes)[0]]['label'].show();
+ let label = new St.Label({
+ text: intf,
+ style_class: 'cm-dialog-interface',
+ });
+ let box = new St.BoxLayout({
+ vertical: true,
+ style_class: 'cm-dialog-box'
+ });
+ this._boxes[intf] = {};
+ this._boxes[intf]['label'] = label;
+ this._boxes[intf]['box'] = box;
+ label.hide();
+ if(Object.keys(this._boxes).length > 1)
+ label.show();
+ this._itemBox.add_child(label);
+ this._itemBox.add_child(box);
+ }
+ this._boxes[intf]['box'].add_child(item.actor);
+ this._services[service[0].id] = item;
+ }
+
+ updateService(service) {
+ if(this._closed)
+ return;
+ if(!this._services[service[0].id])
+ this.addService(service);
+ else
+ this._services[service[0].id]._label.text = service[0].name || service[0].label.text;
+ }
+
+ removeService(id) {
+ if(this._services[id])
+ this._services[id].disable();
+ }
+});
+
+var Service = GObject.registerClass(class Service extends PopupMenu.PopupSubMenuMenuItem {
+
+ _init(type, proxy, indicator) {
+ super._init('', true);
+
+ this.type = type;
+
+ this._properties = {};
+
+ this._proxy = proxy;
+
+ this._connected = true;
+ this._connectionSwitch = new PopupMenu.PopupMenuItem(_("Connect"));
+ this._connectionSwitch.connect('activate', this.buttonEvent.bind(this));
+
+ this._sig = this._proxy.connectSignal('PropertyChanged',
+ function(proxy, sender, [name, value]) {
+ let obj = {};
+ obj[name] = value;
+ this.update(obj);
+ }.bind(this));
+
+ this.state = 'idle'
+ this.hidden = true;
+
+ this._icons = {
+ 'ok': 'network-transmit-receive-symbolic',
+ 'acquiring': 'network-no-route-symbolic',
+ 'offline': 'network-offline-symbolic',
+ 'error': 'network-error-symbolic'
+ };
+
+ this._indicator = indicator;
+ this.label.text = '';
+
+ this._settings = new PopupMenu.PopupMenuItem(_("Settings"));
+ this._settings.connect('activate', this.openSettings.bind(this));
+
+ if(version < 318)
+ this.status.text = this.state;
+ else
+ this.label.text = this.state;
+
+ this.menu.addMenuItem(this._connectionSwitch);
+ this.menu.addMenuItem(this._settings);
+ this.show();
+ }
+
+ openSettings() {
+ Util.spawnApp(['connman-gtk', '--page', this.type]);
+ }
+
+ buttonEvent() {
+ if(this.state == 'idle' || this.state == 'failure' || this.state == 'disconnect')
+ this._proxy.ConnectRemote();
+ else
+ this._proxy.DisconnectRemote();
+ }
+
+ update(properties) {
+ for(let key in properties) {
+ let newProperty = properties[key].deep_unpack();
+ if(newProperty instanceof Object && !(newProperty instanceof Array)) {
+ if(!this._properties[key])
+ this._properties[key] = {};
+ for(let innerKey in newProperty) {
+ this._properties[key][innerKey] =
+ newProperty[innerKey].deep_unpack();
+ }
+ } else {
+ this._properties[key] = newProperty;
+ }
+ }
+ if(properties.State)
+ this.state = properties.State.deep_unpack();
+ if(this.state == 'idle' || this.state == 'disconnect')
+ this._connectionSwitch.label.text = _("Connect");
+ else if(this.state == 'failure')
+ this._connectionSwitch.label.text = _("Reconnect");
+ else
+ this._connectionSwitch.label.text = _("Disconnect");
+ if(this._properties['Name']) {
+ this.name = this._properties['Name'];
+ this.hidden = false;
+ }
+ if(this.state == 'idle' || this.state == 'disconnect' ||
+ this.state == 'failure')
+ this._indicator.hide();
+ else
+ this._indicator.show();
+ if(version < 318)
+ this.status.text = this.getStateString();
+ else
+ this.label.text = this.name + " - " + this.getStateString();
+ this.setIcon(this.getStatusIcon());
+ }
+
+ signalToIcon() {
+ let value = this._properties['Strength'];
+ if(value > 80)
+ return 'excellent';
+ if(value > 55)
+ return 'good';
+ if(value > 30)
+ return 'ok';
+ if(value > 5)
+ return 'weak';
+ return 'none';
+ }
+
+ getStateString() {
+ let states = {
+ idle: _("Idle"),
+ failure: _("Failure"),
+ association: _("Association"),
+ configuration: _("Configuration"),
+ ready: _("Ready"),
+ disconnect: _("Disconnected"),
+ online: _("Online") };
+ return states[this.state] || this.state;
+ }
+
+ setIcon(iconName) {
+ this._indicator.icon_name = iconName;
+ this.icon.icon_name = iconName;
+ }
+
+ destroy() {
+ this._indicator.destroy();
+ try {
+ this._proxy.disconnectSignal(this._sig);
+ } catch(error) {
+ Logger.logException(error, 'Failed to disconnect service proxy');
+ }
+ super.destroy();
+ }
+
+ getIcon() {
+ return this._icons['ok'];
+ }
+
+ getAcquiringIcon() {
+ return this._icons['acquiring'];
+ }
+
+ getOfflineIcon() {
+ return this._icons['offline'];
+ }
+
+ getErrorIcon() {
+ return this._icons['error'];
+ }
+
+ getStatusIcon() {
+ let iconGetters = {
+ online: this.getIcon,
+ ready: this.getIcon,
+ configuration: this.getAcquiringIcon,
+ association: this.getAcquiringIcon,
+ disconnect: this.getOfflineIcon,
+ idle: this.getOfflineIcon,
+ };
+ if(iconGetters[this.state])
+ return iconGetters[this.state].bind(this)();
+ return this.getErrorIcon();
+ }
+
+ show() {
+ //this.actor.show();
+ this._indicator.show();
+ }
+
+ hide() {
+ //this.actor.hide();
+ this._indicator.hide();
+ }
+});
+
+var EthernetService = GObject.registerClass(class EthernetService extends Service {
+
+ _init(proxy, indicator) {
+ super._init('ethernet', proxy, indicator);
+ this.name = _("Wired");
+ this.label.text = this.name;
+ this._settings.label.text = _("Wired Settings");
+ this._icons = {
+ 'ok': 'network-wired-symbolic',
+ 'acquiring': 'network-wired-acquiring-symbolic',
+ 'offline': 'network-wired-offline-symbolic',
+ 'error': 'network-error-symbolic'
+ };
+
+ this.show();
+ }
+
+ update(properties) {
+ super.update(properties);
+ if(version < 318 && this._properties['Name'] == 'Wired') {
+ /* ensure translated name */
+ this._properties['Name'] = _("Wired");
+ this.label.text = _("Wired");
+ }
+ }
+});
+
+var WirelessService = GObject.registerClass(class WirelessService extends Service {
+
+ _init(proxy, indicator) {
+ super._init('wifi', proxy, indicator);
+ this.name = _("Hidden");
+ this._settings.label.text = _("Wireless Settings");
+ this._icons = {
+ 'ok': 'network-wireless-connected-symbolic',
+ 'acquiring': 'network-wireless-acquiring-symbolic',
+ 'offline': 'network-wireless-offline-symbolic',
+ 'error': 'network-error-symbolic'
+ };
+ }
+
+ securityIcon() {
+ let security = this._properties['Security'][0];
+ if(!security || security == 'none')
+ return '';
+ let icons = {
+ ieee8021x: 'security-high-symbolic',
+ wep: 'security-low-symbolic',
+ };
+ return icons[security] || 'security-medium-symbolic';
+ }
+
+ getIcon() {
+ return 'network-wireless-signal-' + this.signalToIcon() + '-symbolic';
+ }
+
+ update(properties) {
+ super.update(properties);
+
+ if(this.state == 'idle' || this.state == 'disconnect' ||
+ this.state == 'failure')
+ this.hide();
+ else
+ this.show();
+
+ if(this.hidden) {
+ let security = this._properties['Security'][0];
+ if(!security)
+ security = 'none';
+ let names = {
+ ieee8021x: _("Hidden ieee8021x secured network"),
+ psk: _("Hidden WPA secured network"),
+ wep: _("Hidden WEP secured network"),
+ wps: _("Hidden WPS secured network"),
+ none: _("Hidden unsecured network")
+ };
+ this.name = names[security] || _("Hidden network");
+ }
+ }
+});
+
+var BluetoothService = GObject.registerClass(class BluetoothService extends Service {
+
+ _init(proxy, indicator) {
+ super._init('bluetooth', proxy, indicator);
+ this._settings.label.text = _("Bluetooth Settings");
+ this._icons = {
+ 'ok': 'bluetooth-active-symbolic',
+ 'acquiring': 'bluetooth-active-symbolic',
+ 'offline': 'bluetooth-disabled-symbolic',
+ 'error': 'network-error-symbolic'
+ };
+
+ this.show();
+ }
+});
+
+var CellularService = GObject.registerClass(class CellularService extends Service {
+
+ _init(proxy, indicator) {
+ super._init('cellular', proxy, indicator);
+ this._settings.label.text = _("Cellular Settings");
+ this._icons = {
+ 'ok': 'network-cellular-connected-symbolic',
+ 'acquiring': 'network-cellular-acquiring-symbolic',
+ 'offline': 'network-cellular-offline-symbolic',
+ 'error': 'network-error-symbolic'
+ };
+
+ this.show();
+ }
+
+ getIcon() {
+ return 'network-cellular-signal-' + this.signalToIcon() + '-symbolic';
+ }
+});
+
+var VPNService = GObject.registerClass(class VPNService extends Service {
+
+ _init(proxy, indicator) {
+ super._init('vpn', proxy, indicator);
+ this._settings.label.text = _("VPN Settings");
+ this._icons = {
+ 'ok': 'network-vpn-symbolic',
+ 'acquiring': 'network-vpn-acquiring-symbolic',
+ 'offline': 'network-offline-symbolic',
+ 'error': 'network-error-symbolic',
+ };
+
+ this.show();
+ }
+
+ getAcquiringIcon() {
+ return 'network-vpn-acquiring-symbolic';
+ }
+
+ getIcon() {
+ return 'network-vpn-symbolic';
+ }
+});
+
+function createService(type, proxy, indicator) {
+ let services = {
+ ethernet: EthernetService,
+ wifi: WirelessService,
+ bluetooth: BluetoothService,
+ cellular: CellularService,
+ vpn: VPNService
+ };
+ if (services[type])
+ return new services[type](proxy, indicator);
+ return new Service('other', proxy, indicator);
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/stylesheet.css b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/stylesheet.css
new file mode 100644
index 0000000..ebd26dc
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/stylesheet.css
@@ -0,0 +1,97 @@
+/* Password or Authentication Dialog */
+.cm-prompt-dialog {
+ width: 500px;
+ border: 3px solid rgba(238, 238, 236, 0.2); }
+
+.cm-prompt-dialog-main-layout {
+ spacing: 24px;
+ padding: 10px; }
+
+.cm-prompt-dialog-message-layout {
+ spacing: 16px; }
+
+.cm-prompt-dialog-headline {
+ font-weight: bold;
+ color: #b2b2a9; }
+
+.cm-prompt-dialog-description:rtl {
+ text-align: right; }
+
+.cm-prompt-dialog-password-box {
+ spacing: 1em;
+ padding-bottom: 1em; }
+
+.cm-prompt-dialog-error-label {
+ font-size: 10pt;
+ color: #cc0000;
+ padding-bottom: 8px; }
+
+.cm-prompt-dialog-info-label {
+ font-size: 10pt;
+ padding-bottom: 8px; }
+
+.cm-hidden {
+ color: transparent; }
+
+.cm-prompt-dialog-null-label {
+ font-size: 10pt;
+ padding-bottom: 8px; }
+
+/* NETWORK DIALOGS */
+.cm-dialog {
+ max-height: 500px;
+ min-height: 450px;
+ min-width: 470px; }
+
+.cm-dialog-content {
+ spacing: 20px; }
+
+.cm-dialog-interface {
+ color: #606060;
+ padding: 15px; }
+
+.cm-dialog-header-hbox {
+ spacing: 10px; }
+
+.cm-dialog-header-icon {
+ icon-size: 32px; }
+
+.cm-dialog-scroll-view {
+ border: 2px solid #1c1f1f; }
+
+.cm-dialog-header {
+ font-weight: bold; }
+
+.cm-dialog-item {
+ font-size: 110%;
+ border-bottom: 1px solid #1c1f1f;
+ padding: 12px 12px 12px 36px; }
+
+.cm-dialog-item:favourite {
+ padding: 12px 12px 12px 0px; }
+
+.cm-dialog-item:selected {
+ background-color: #215d9c;
+ color: #ffffff; }
+
+.cm-dialog-item:passive {
+ color: #606060; }
+
+.cm-dialog-icons {
+ spacing: .5em; }
+
+.cm-dialog-icon {
+ icon-size: 16px;
+ padding-left: 5px; }
+
+.cm-dialog-icon:favourite {
+ padding: 0px 10px 0px 10px;}
+
+/* Network Agent Dialog */
+.cm-network-dialog-secret-table {
+ spacing-rows: 15px;
+ spacing-columns: 1em; }
+
+.cm-keyring-dialog-control-table {
+ spacing-rows: 15px;
+ spacing-columns: 1em; }
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/technology.js b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/technology.js
new file mode 100644
index 0000000..cb964a9
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/technology.js
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ * Author: Jaakko Hannikainen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+const Lang = imports.lang;
+const Util = imports.misc.util;
+
+const PopupMenu = imports.ui.popupMenu;
+const GObject = imports.gi.GObject;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Ext = ExtensionUtils.getCurrentExtension();
+const Service = Ext.imports.service;
+const Logger = Ext.imports.logger;
+
+const Gettext = imports.gettext.domain('gnome-extension-connman');
+const _ = Gettext.gettext;
+
+const Version = Ext.imports.version;
+const version = Version.version();
+
+var Technology = class extends PopupMenu.PopupMenuSection {
+
+ constructor(properties, type, proxy) {
+ super();
+ this._type = type;
+ this._services = {}
+ this._dialog = null;
+ this._properties = properties;
+
+ this._proxy = proxy;
+ if (this._proxy)
+ this._sig = this._proxy.connectSignal('PropertyChanged',
+ function(proxy, sender, [name, value]) {
+ this.propertyChanged(name, value.deep_unpack());
+ }.bind(this));
+ if (this._properties['Powered'])
+ this.show();
+ else
+ this.hide();
+ }
+
+ getValue() {
+ let values = ["ethernet", "wifi", "bluetooth",
+ "p2p", "cellular", "vpn", "other"];
+ return values.indexOf(this._type);
+ }
+
+ propertyChanged(name, value) {
+ if(name == 'Powered') {
+ if(value)
+ this.show();
+ else
+ this.hide();
+ }
+ }
+
+ addService(id, service) {
+ if(this._services[id])
+ this._services[id].destroy();
+ this._services[id] = service;
+ service.id = id;
+ this.addMenuItem(service);
+ this.serviceUpdated(id);
+ this.updateIcon();
+ }
+
+ getService(id) {
+ return this._services[id];
+ }
+
+ updateService(id, properties) {
+ if(!this._services[id])
+ return false;
+ this._services[id].update(properties);
+ this.serviceUpdated(id);
+ this.updateIcon();
+ return true;
+ }
+
+ removeService(id) {
+ if(!this._services[id])
+ return false;
+ this._services[id].destroy();
+ delete this._services[id];
+ this.serviceUpdated(id);
+ this.updateIcon();
+ return true;
+ }
+
+ destroy() {
+ for(let path in this._services) {
+ try {
+ this.removeService(path);
+ } catch(error) {}
+ }
+ try {
+ if(this._proxy)
+ this._proxy.disconnectSignal(this._sig);
+ } catch(error) {
+ Logger.logException(error, 'Failed to disconnect service proxy');
+ }
+ super.destroy();
+ }
+
+ serviceUpdated(id) {}
+
+ updateIcon() {
+ if(Object.keys(this._services)) {
+ this._indicator = this._services[Object.keys(this._services)[0]];
+ for(let path in this._services) {
+ let state = this._services[path]._properties['State'];
+ if(state != 'idle')
+ this._indicator = this._services[path]._indicator;
+ }
+ for(let path in this._services) {
+ let state = this._services[path]._properties['State'];
+ if(state != 'idle' && state != 'failure')
+ this._indicator = this._services[path]._indicator;
+ }
+ }
+ }
+
+ show() {
+ this.actor.show();
+ if(this._indicator)
+ this._indicator.show();
+ }
+
+ hide() {
+ this.actor.hide();
+ if(this._indicator)
+ this._indicator.hide();
+ }
+};
+
+var EthernetTechnology = class extends Technology {
+
+ constructor(properties, proxy) {
+ super(properties, 'ethernet', proxy);
+ }
+};
+
+var WirelessTechnology = class extends Technology {
+
+ constructor(properties, proxy, manager) {
+ super(properties, 'wifi', proxy);
+
+ this._menu = new PopupMenu.PopupSubMenuMenuItem('', true);
+
+ this._settings = new PopupMenu.PopupMenuItem(_("Wireless Settings"));
+ this._settings.connect('activate', this.openSettings.bind(this));
+
+ if (version < 318) {
+ this._menu.label.text = _("Wireless");
+ this._menu.status.text = _("Idle");
+ } else {
+ this._menu.label.text = _("Wireless") + " - " + _("Idle");
+ }
+ this._menu.icon.icon_name = 'network-wireless-signal-none-symbolic';
+ this._manager = manager;
+ this.addMenuItem(this._menu);
+ this._menu.menu.addMenuItem(this._createConnectionMenuItem());
+ this._menu.menu.addMenuItem(this._settings);
+ this._connected = {};
+ this._connectedCount = 0;
+ this.show();
+ }
+
+ openSettings() {
+ Util.spawnApp(['connman-gtk', '--page', 'wifi']);
+ }
+
+ _createConnectionMenuItem() {
+ let connectionItem = new PopupMenu.PopupMenuItem(
+ _("Select wireless network"));
+ connectionItem.connect('activate', this.selectWifi.bind(this));
+ return connectionItem;
+ }
+
+ selectWifi() {
+ let serviceList = [];
+ let result = this._manager.GetServicesSync();
+ let services = result[0];
+ for(let i = 0; i < services.length; i++) {
+ let service = this._services[services[i][0]];
+ if(service && service._properties['Name'])
+ serviceList.push([service, service._properties['Ethernet']['Interface']]);
+ }
+ let callback = function(service) {
+ this._dialog = null;
+ if(service)
+ service.buttonEvent();
+ else
+ Logger.logInfo('User canceled wifi dialog');
+ }.bind(this);
+ this._dialog = new Service.ServiceChooser(this._proxy,
+ serviceList, callback);
+ }
+
+ addService(id, service) {
+ super.addService(id, service);
+ service.menu.addMenuItem(this._createConnectionMenuItem(), 1);
+ let state = this._services[id].state;
+ if(state != 'idle' && state != 'disconnect' && state != 'failure') {
+ this._connected[id] = true;
+ this._menu.actor.hide();
+ this._connectedCount++;
+ }
+ if(this._dialog)
+ this._dialog.addService([service, service._properties['Ethernet']['Interface']]);
+ }
+
+ updateService(id, properties) {
+ super.updateService(id, properties);
+ let state = this._services[id]._properties['State'];
+ if(state != 'idle' && state != 'disconnect' && state != 'failure') {
+ if(!this._connected[id]) {
+ this._connected[id] = true;
+ this._connectedCount++;
+ this._menu.actor.hide();
+ }
+ }
+ else {
+ if(this._connected[id]) {
+ this._connected[id] = false;
+ this._connectedCount--;
+ if(!this._connectedCount)
+ this._menu.actor.show();
+ }
+ }
+ if(this._dialog)
+ this._dialog.updateService([this._services[id],
+ this._services[id]._properties['Ethernet']['Interface']]);
+ }
+
+ removeService(id) {
+ let state = this._services[id]._properties['State'];
+ if(state != 'idle' && state != 'disconnect' && state != 'failure') {
+ this._services[id].hide();
+ if(this._connected[id]) {
+ this._connected[id] = false;
+ this._connectedCount--;
+ if(!this._connectedCount)
+ this._menu.actor.show();
+ }
+ }
+ super.removeService(id);
+ this.serviceUpdated(id);
+ this.updateIcon();
+ if(this._dialog)
+ this._dialog.removeService(id);
+ }
+
+ destroy() {
+ this._proxy = null;
+ super.destroy();
+ }
+};
+
+var BluetoothTechnology = class extends Technology {
+
+ constructor(properties, proxy) {
+ super(properties, 'bluetooth', proxy);
+ }
+};
+
+var P2PTechnology = class extends Technology {
+
+ constructor(properties, proxy) {
+ super(properties, 'p2p', proxy);
+ }
+};
+
+var CellularTechnology = class extends Technology {
+
+ constructor(properties, proxy) {
+ super(properties, 'cellular', proxy);
+ }
+};
+
+class VPNTechnology extends Technology {
+
+ constructor(properties, proxy) {
+ super(properties, 'vpn', proxy);
+ }
+};
+
+function createTechnology(type, properties, proxy, manager) {
+ let technologies = {
+ ethernet: EthernetTechnology,
+ wifi: WirelessTechnology,
+ bluetooth: BluetoothTechnology,
+ p2p: P2PTechnology,
+ cellular: CellularTechnology,
+ vpn: VPNTechnology
+ };
+ if(technologies[type])
+ return new technologies[type](properties, proxy, manager);
+ return new Technology(properties, 'other', proxy);
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/version.js b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/version.js
new file mode 100644
index 0000000..06c9b3a
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/gnome-shell/extensions/gnome-extension-connman@jaakko.hannikainen.intel.com/version.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ * Author: Jaakko Hannikainen
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Config = imports.misc.config;
+
+function version() {
+ var split = Config.PACKAGE_VERSION.split('.');
+ return parseInt(split[0])*100 + parseInt(split[1]);
+}
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.local/share/rofi/themes/mnt-reform.rasi b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/rofi/themes/mnt-reform.rasi
new file mode 100644
index 0000000..5602d38
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.local/share/rofi/themes/mnt-reform.rasi
@@ -0,0 +1,28 @@
+//! ------------------------------------------------------------------------------
+//! ROFI MNT Reform Color theme
+//! User: MNT Research GmbH
+//! ------------------------------------------------------------------------------
+
+* {
+ background-color: #000000;
+ text-color: #ffffff;
+}
+
+prompt {
+ text-color: #000000;
+ font-size: 0;
+}
+
+window {
+ padding: 32px;
+}
+
+element normal {
+ text-color: #ffffff;
+}
+
+element selected {
+ background-color: #ffffff;
+ text-color: #000000;
+}
+
diff --git a/src/recipes/default/hook/data/overlay/etc/skel/.profile b/src/recipes/default/hook/data/overlay/etc/skel/.profile
new file mode 100644
index 0000000..4efa2fb
--- /dev/null
+++ b/src/recipes/default/hook/data/overlay/etc/skel/.profile
@@ -0,0 +1,50 @@
+# ~/.profile: executed by the command interpreter for login shells.
+# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
+# exists.
+# see /usr/share/doc/bash/examples/startup-files for examples.
+# the files are located in the bash-doc package.
+
+# the default umask is set in /etc/profile; for setting the umask
+# for ssh logins, install and configure the libpam-umask package.
+#umask 022
+
+# if running bash
+if [ -n "$BASH_VERSION" ]; then
+ # include .bashrc if it exists
+ if [ -f "$HOME/.bashrc" ]; then
+ . "$HOME/.bashrc"
+ fi
+fi
+
+# set PATH so it includes user's private bin if it exists
+if [ -d "$HOME/bin" ] ; then
+ PATH="$HOME/bin:$PATH"
+fi
+
+# set PATH so it includes user's private bin if it exists
+if [ -d "$HOME/.local/bin" ] ; then
+ PATH="$HOME/.local/bin:$PATH"
+fi
+
+
+# Defaults for MNT Reform
+
+# enable NIR shader path in mesa. without this,
+# some Xwayland applications will be blank
+export ETNA_MESA_DEBUG=nir
+
+# set GTK2 theme
+export GTK2_RC_FILES=/usr/share/themes/Arc-Dark/gtk-2.0/gtkrc
+
+unicode_start
+
+if [ $(whoami) == "root" ]
+then
+ cat /etc/reform-root-help
+elif [ ! -z $WAYLAND_DISPLAY ]
+then
+ # do nothing
+ true
+else
+ cat /etc/reform-help
+fi
diff --git a/src/recipes/default/packages/packages.list b/src/recipes/default/packages/packages.list
index 907157f..c98b1b7 100644
--- a/src/recipes/default/packages/packages.list
+++ b/src/recipes/default/packages/packages.list
@@ -5,6 +5,7 @@ breeze-icon-theme
brightness-udev
brightnessctl
bsdmainutils
+busybox
ca-certificates
connman-gtk
console-data