Categorygithub.com/muesli/deckmaster
modulepackage
0.9.0
Repository: https://github.com/muesli/deckmaster.git
Documentation: pkg.go.dev

# README

deckmaster

Latest Release Go Doc Software License Build Status Go ReportCard

An application to control your Elgato Stream Deck on Linux

Features

  • Multiple pages & navigation between decks
  • Buttons (icons & text)
  • Background images
  • Brightness control
  • Supports different actions for short & long presses
  • Comes with a collection of widgets:
    • Buttons
    • Time (with formatting)
    • CPU/Mem usage
    • Weather
    • Command output
    • Recently used windows (X11-only)
  • Lets you trigger several actions:
    • Run commands
    • Emulate a key-press
    • Paste to clipboard
    • Trigger a dbus call

Installation

Packages

From source

Make sure you have a working Go environment (Go 1.17 or higher is required). See the install instructions.

To install deckmaster, simply run:

git clone https://github.com/muesli/deckmaster.git
cd deckmaster
go build

System Setup

On Linux you need to set up some udev rules to be able to access the device as a regular user. Edit /etc/udev/rules.d/99-streamdeck.rules and add these lines:

SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE:="666", GROUP="plugdev", SYMLINK+="streamdeck"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE:="666", GROUP="plugdev", SYMLINK+="streamdeck"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE:="666", GROUP="plugdev", SYMLINK+="streamdeck"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE:="666", GROUP="plugdev", SYMLINK+="streamdeck-mini"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", MODE:="666", GROUP="plugdev", SYMLINK+="streamdeck-xl"

Make sure your user is part of the plugdev group and reload the rules with sudo udevadm control --reload-rules. Unplug and re-plug the device, and you should be good to go.

Starting deckmaster automatically

If you want deckmaster to be started automatically upon device plugin, you can use systemd path activation, adding streamdeck.path and streamdeck.service files to $HOME/.config/systemd/user.

streamdeck.path contents:

[Unit]
Description="Stream Deck Device Path"

[Path]
# the device name will be different if you use streamdeck-mini or streamdeck-xl
PathExists=/dev/streamdeck
Unit=streamdeck.service

[Install]
WantedBy=multi-user.target

streamdeck.service contents:

[Unit]
Description=Deckmaster Service

[Service]
# adjust the path to deckmaster and .deck file to suit your needs
ExecStart=/usr/local/bin/deckmaster --deck path-to/some.deck
Restart=on-failure
ExecReload=kill -HUP $MAINPID

[Install]
WantedBy=default.target

Then enable and start the streamdeck.path unit:

systemctl --user enable streamdeck.path
systemctl --user start streamdeck.path

Usage

Start deckmaster with the initial deck configuration you want to load:

deckmaster -deck deck/main.deck

You can control the brightness, in percent:

deckmaster -brightness 50

Control a specific streamdeck:

deckmaster -device [serial number]

Set a sleep timeout after which the screen gets turned off:

deckmaster -sleep 10m

Configuration

You can find a few example configurations in the decks directory. Edit them to your needs!

Widgets

Any widget is build up the following way:

[[keys]]
  index = 0

index needs to be present in every widget and describes the position of the widget on the streamdeck. index is 0-indexed and counted from top to bottom and left to right.

Update interval for widgets

Optionally, you can configure an update interval for each widget:

[keys.widget]
  id = "button"
  interval = 500 # optional

The attribute interval defines the time in ms between two consecutive updates of a widget.

Button

A simple button that can display an image and/or a label.

[keys.widget]
  id = "button"
  [keys.widget.config]
    icon = "/some/image.png" # optional
    label = "My Button" # optional
    fontsize = 10.0 # optional
    color = "#fefefe" # optional
    flatten = true # optional

If flatten is true all opaque pixels of the icon will have the color color.

Recent Window (requires X11)

Displays the icon of a recently used window/application. Pressing the button activates the window.

[keys.widget]
  id = "recentWindow"
  [keys.widget.config]
    window = 1
    showTitle = true # optional

If showTitle is true, the title of the window will be displayed below the window icon.

Time

A flexible widget that can display the current time or date.

[keys.widget]
  id = "time"
  [keys.widget.config]
    format = "%H;%i;%s"
    font = "bold;regular;thin" # optional
    color = "#fefefe" # optional
    layout = "0x0+72x24;0x24+72x24;0x48+72x24" # optional

With layout custom layouts can be definded in the format [posX]x[posY]+[width]x[height].

Values for format are:

%gets replaced with
%YA full numeric representation of a year, 4 digits
%yA two digit representation of a year
%FA full textual representation of a month, such as January or March
%MA short textual representation of a month, three letters
%mNumeric representation of a month, with leading zeros
%lA full textual representation of the day of the week
%DA textual representation of a day, three letters
%dDay of the month, 2 digits with leading zeros
%h12-hour format of an hour with leading zeros
%H24-hour format of an hour with leading zeros
%iMinutes with leading zeros
%sSeconds with leading zeros
%aLowercase Ante meridiem and Post meridiem
%tTimezone abbreviation

Top

This widget shows the current CPU or memory utilization as a bar graph.

[keys.widget]
  id = "top"
  [keys.widget.config]
    mode = "cpu"
    color = "#fefefe" # optional
    fillColor = "#d497de" # optional

There are two values for mode: cpu and memory.

Command

A widget that displays the output of commands.

[keys.widget]
  id = "command"
  [keys.widget.config]
    command = "echo 'Files:'; ls -a ~ | wc -l"
    font = "regular;bold" # optional
    color = "#fefefe" # optional
    layout = "0x0+72x20;0x20+72x52" # optional

Weather

A widget that displays the weather condition and temperature.

[keys.widget]
  id = "weather"
  [keys.widget.config]
    location = "MyCity" # optional
    unit = "celsius" # optional
    color = "#fefefe" # optional
    flatten = true # optional
    theme = "openmoji" # optional

The supported location types can be found here. The unit has to be either celsius or fahrenheit. If flatten is true all opaque pixels of the condition icon will have the color color. In case theme is set corresponding icons with correct names need to be placed in ~/.local/share/deckmaster/themes/[theme]. The default icons with their respective names can be found here.

Actions

You can hook up any key with several actions. A regular keypress will trigger the widget's configured keys.action, while holding the key will trigger keys.action_hold.

Switch deck

[keys.action]
  deck = "relative/path/to/another.deck"

Run a command

[keys.action]
  exec = "some_command --with-parameters"

Emulate key-presses

[keys.action]
  keycode = "Leftctrl-C"

Emulate a series of key-presses with delay in between:

[keys.action]
  keycode = "Leftctrl-X+500 / Leftctrl-V / Num1"

A list of available keycodes can be found here: keycodes

Paste to clipboard

[keys.action]
  paste = "some text"

Trigger a dbus call

[keys.action]
  [dbus]
    object = "object"
    path = "path"
    method = "method"
    value = "value"

Device actions

Increase the brightness. If no value is specified, it will be increased by 10%:

[keys.action]
  device = "brightness+5"

Decrease the brightness. If no value is specified, it will be decreased by 10%:

[keys.action]
  device = "brightness-5"

Set the brightness to a specific value between 0 and 100:

[keys.action]
  device = "brightness=50"

Put the device into sleep mode, blanking the screen until the next key gets pressed:

[keys.action]
  device = "sleep"

Background Image

You can configure each deck to display an individual wallpaper behind its widgets:

background = "/some/image.png"

Re-using another deck's configuration

If you specify a parent inside a deck's configuration, it will inherit all of the parent's settings that are not overwritten by the deck's own settings. This even works recursively:

parent = "another.deck"

More Decks!

deckmaster-emojis, an Emoji keyboard deck

Made your own useful decks? Submit a pull request!

Feedback

Got some feedback or suggestions? Please open an issue or drop me a note!

# Functions

ConfigValue tries to convert an interface{} to the desired type.
Connect establishes a connection with an Xorg display.
LoadConfig loads config from filename.
LoadConfigFromFile loads a DeckConfig from a file while checking for circular dependencies.
LoadDeck loads a deck configuration.
MergeDeckConfig merges key configuration from multiple configs.
NewBaseWidget returns a new BaseWidget.
NewButtonWidget returns a new ButtonWidget.
NewCommandWidget returns a new CommandWidget.
NewLayout returns a new Layout with the accoriding size.
NewRecentWindowWidget returns a new RecentWindowWidget.
NewTimeWidget returns a new TimeWidget.
NewTopWidget returns a new TopWidget.
NewWeatherWidget returns a new WeatherWidget.
NewWidget initializes a widget.

# Variables

CommitSHA contains the SHA of the commit that this application was built against.
DefaultColor is the standard color for text rendering.
Version contains the application version number.

# Structs

ActionConfig describes an action that can be triggered.
ActiveWindowChangedEvent gets emitted when the active window changes.
BaseWidget provides common functionality required by all widgets.
ButtonWidget is a simple widget displaying an icon and/or label.
CommandWidget is a widget displaying the output of command(s).
DBusConfig describes a dbus action.
Deck is a set of widgets.
DeckConfig is the central configuration struct.
KeyConfig holds the entire configuration for a single key.
Layout contains the data to represent the layout of the widget.
RecentWindowWidget is a widget displaying a recently activated window.
TimeWidget is a widget displaying the current time/date.
TopWidget is a widget displaying the current CPU/MEM usage as a bar.
WeatherData handles fetches and parsing weather data.
WeatherWidget is a widget displaying the current weather.
WidgetConfig describes configuration data for widgets.
Window describes an X11 window.
WindowClosedEvent gets emitted when a window gets closed.
Xorg provides an interface to an X11 session.

# Interfaces

Widget is an interface implemented by all available widgets.

# Type aliases

Keys is a slice of keys.