Skip to content

Commit

Permalink
Add autohide option
Browse files Browse the repository at this point in the history
  • Loading branch information
Will committed May 16, 2022
1 parent 41525da commit 63facbf
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 59 deletions.
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ Use `Ctrl+Shift+C` and `Ctrl+Shift+V` to access the clipboard.
```bash
$ pip install terminalle

# Optional: enable auto-start (starts the server automatically on login and restarts automatically if exited).
# Optional: Enable auto-start.
# Starts the server automatically (window hidden) on login
# and restarts automatically (also hidden) if exited.
$ terminalle auto

# Optional: disable auto-start (if enabled, it should be disabled prior to uninstalling).
# Optional: Disable auto-start.
# If enabled, it should be disabled prior to uninstalling.
$ terminalle no-auto
```

Expand All @@ -57,8 +60,8 @@ In GNOME, you can either do that in the GNOME Control Center (a.k.a "Settings"),
or with `gsettings`:

```bash
# WARNING: Running this verbatim will disable any other custom keybindings.
# It is merely provided as an example.
# WARNING: Running this verbatim will disable any existing custom keybindings.
# It's an example.
$ gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']"

# WARNING: This will overwrite any existing custom keybinding called 'custom0'.
Expand All @@ -70,13 +73,13 @@ $ gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/
If you use multiple monitors,
consider hooking up shortcuts for the aforementioned movement methods as well.

[KDE][6] can configure shortcuts to call D-Bus methods directly.
[KDE can][6] configure shortcuts to call D-Bus methods directly.

## Configuration

See an [example configuration][7]. See the defaults in [`settings.py`][8].
Defaults can be selectively overridden in `${XDG_CONFIG_HOME}/terminalle.yaml`
(typically, `${HOME}/.config/terminalle.yaml`).
Defaults can be selectively overridden in
`${XDG_CONFIG_HOME:-${HOME}/.config}/terminalle.yaml`.

## TMUX MODE

Expand All @@ -87,13 +90,13 @@ since terminal emulators typically cannot handle these key combinations.
Generally replacing the tmux prefix with a simple `Ctrl` modifier,
it cuts the number of keystrokes in half
without requiring you to memorize new shortcuts.
If you're a tmux power-user, this will **change** things for you.
If you're a tmux power-user, this will *change* things for you.
Turn it on by setting `tmux: true` in `terminalle.yaml` (see [configuration][9]).

The following shortcuts are enabled in tmux mode:

| tmux default | tmux mode | Command |
| -----------: | --------: | :------------------------------------------------------------------ |
| -----------: | --------: | :-------------------------------------------------------------------- |
| `<Prefix> !` | `Ctrl+!` | `break-pane` |
| `<Prefix> "` | `Ctrl+"` | `split-window` |
| `<Prefix> #` | `Ctrl+#` | `list-buffers` |
Expand Down
3 changes: 3 additions & 0 deletions terminalle.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# This is just an example configuation. Values are not necessarily the default.
# See the defaults in `terminalle/settings.py`.
shell: '/bin/sh'
home: '/home/user'
font: 'Source Code Pro 13'
Expand All @@ -20,5 +21,7 @@ colors:
- '#93a1a1' # bright cyan
- '#fdf6e3' # bright white
opacity: 0.75
# Automatically hide the window when it loses keyboard focus.
autohide: true
# See the readme for an explanation of the `tmux` option.
tmux: true
89 changes: 42 additions & 47 deletions terminalle/settings.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,33 @@
""" Loading and validating settings configurations.
- shell : str
* path to shell binary e.g. '$HOME/bash'
* default: getenv('SHELL', '/bin/sh')
- home : str
* initial home directory e.g. '/tmp' or '$HOME'
* default: current working directory of caller
- font : str | Pango.FontDescription
* must be valid input for Pango.font_description_from_string()
* default: 'Source Code Pro 13'
- colors : [str | [int | float] | Gdk.RGBA]
* must have length either 8, 16, 232, or 256:
> first 8 are the main colors
> next 8 are the bright colors
> next 216 are the 6x6x6 color cube
> next 24 are grayscale
* each color is either:
> a valid string for Gdk.RGBA().parse()
> a list of 1 (R=G=B, A=1), 3 (A=1), or 4 number values,
each being either:
- an integer between 0 and 255
- a float between 0.0 and 1.0
* default: solarized dark with pure black background
- opacity : float | int
* window opacity beween 0.0 and 1.0 or 0 and 100
* default: 0.75
- tmux : bool
* whether to enable recommended hardwired tmux shortcuts
* default: false
"""
""" Loading and validating settings configurations. """

from os import getenv, getcwd
from os.path import expandvars

from yaml import safe_load
from gi.repository import Gdk, Pango

def load(path:str):
""" Return normalized settings loaded from a YAML file. """
try:
with open(path) as f:
attrs = safe_load(f)
assert isinstance(attrs, dict)
except:
return _normalize()
# change hyphenated-keys to underscored_keys
return _normalize(**{key.replace('-', '_'): value
for key, value in attrs.items()})

_defaults = {
# (shell: string) path to shell binary e.g. `${HOME}/bash`
# default: `${SHELL:-/bin/sh}`
'shell': getenv('SHELL', '/bin/sh'),
# (home: string) initial home directory e.g. `${HOME}` or `/tmp`
# default: current working directory of caller
'home': getcwd(),
# (font: string) must be valid input for `Pango.font_description_from_string()`
# default: 'Source Code Pro 13'
'font': 'Source Code Pro 13',
# just solarized-dark with deeper black
# (colors: array) must have length either 8, 16, 232, or 256:
# first 8 are the main colors
# next 8 are the bright colors
# next 216 are the 6x6x6 color cube
# next 24 are grayscale
# each color is either:
# a valid string for Gdk.RGBA().parse()
# a list of 1 (R=G=B, A=1), 3 (A=1), or 4 number values,
# each number being either:
# an integer between 0 and 255
# a float between 0.0 and 1.0
# default: solarized dark with pure black background
'colors': [
# black red green yellow
'#000000', '#dc322f', '#859900', '#b58900',
Expand All @@ -62,21 +37,41 @@ def load(path:str):
'#002b36', '#cb4b16', '#586e75', '#657b83',
'#839496', '#6c71c4', '#93a1a1', '#fdf6e3',
],
# (opacity: number) window opacity beween 0.0 and 1.0 or 0 and 100
# default: 0.75
'opacity': 0.75,
# (autohide: bool) whether to automatically hide the window when it loses keyboard focus
# default: true
'autohide': True,
# (tmux: bool) whether to enable recommended hardwired tmux shortcuts
# default: false
'tmux': False,
}
_valid_colors_lengths = {8, 16, 232, 256}

def load(path:str):
""" Return normalized settings loaded from a YAML file. """
try:
with open(path) as f:
attrs = safe_load(f)
assert isinstance(attrs, dict)
except:
return _normalize()
# change hyphenated-keys to underscored_keys
return _normalize(**{key.replace('-', '_'): value
for key, value in attrs.items()})

def _normalize(shell: str = _defaults['shell'],
home: str = _defaults['home'],
font: str = _defaults['font'],
colors: list = _defaults['colors'],
opacity: float = _defaults['opacity'],
autohide: bool = _defaults['autohide'],
tmux: bool = _defaults['tmux'],
**kwargs):
"""
Return a normalized version of the settings configuration.
Raise InvalidSettingsError if the settings are invalid.
Raise `InvalidSettingsError` if the settings are invalid.
"""
if len(kwargs) > 0:
raise InvalidSettingsError(f'unexpected attributes {kwargs}')
Expand All @@ -93,6 +88,7 @@ def _normalize(shell: str = _defaults['shell'],
'font': _normalize_font(font),
'colors': [_normalize_color(c) for c in colors],
'opacity': _opacity,
'autohide': _normalize_bool(autohide, 'autohide'),
'tmux': _normalize_bool(tmux, 'tmux'),
}

Expand Down Expand Up @@ -129,12 +125,11 @@ def _normalize_color(color):
f'color ({color}) must be a string or list of RGBA values')

def _normalize_number(number, intmax):
""" Return 0.0 <= number <= 1.0 or None if the number is invalid. """
if isinstance(number, float) and 0.0 <= number <= 1.0:
return number
elif isinstance(number, int) and 0 <= number <= intmax:
return number / intmax
return None
return None # the number is invalid

def _normalize_bool(value, name):
if isinstance(value, bool):
Expand Down
7 changes: 4 additions & 3 deletions terminalle/terminalle.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ def __init__(self, settings: Dict[str, object], show: bool):
# For some reason the top-level window opacity must not be 1
# in order to enable any kind of child widget transparency.
window.set_opacity(.99)
window.set_events(Gdk.EventType.FOCUS_CHANGE)
window.connect('focus-out-event', self._focus_out)
if settings['autohide']:
window.set_events(Gdk.EventType.FOCUS_CHANGE)
window.connect('focus-out-event', self._autohide)

terminal = Vte.Terminal()
terminal.set_font(font_desc=settings['font'])
Expand Down Expand Up @@ -195,7 +196,7 @@ def _copy_clipboard(self, window: Gtk.Window):
def _paste_clipboard(self, window: Gtk.Window):
self.terminal.paste_clipboard()

def _focus_out(self, window: Gtk.Window, event: Gdk.EventFocus):
def _autohide(self, window: Gtk.Window, event: Gdk.EventFocus):
GLib.idle_add(self.window.hide)

def _term_exited(self, terminal: Vte.Terminal, status: int):
Expand Down

0 comments on commit 63facbf

Please sign in to comment.