Phase 1: Alt+Tab switcher, dark GTK theme, alacritty terminal
- Alt+Tab now shows a centered visual switcher overlay with window cards; cycling with Tab, committing on Alt release, cancelling with Escape - GTK3 and GTK2 themes rewritten in dark navy palette matching skywm/ skydeskbar color constants (was an off-brand tan/BeOS palette) - Add alacritty to ISO packages with pre-configured dark color scheme; update all menu Terminal entries to launch alacritty instead of xterm - Add KeyReleaseMask to WM root event selection to detect Alt release Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
e641720a3c
commit
9089c14a19
10 files changed
+378
-101
No files matched your search
@@ -453,7 +453,7 @@ static const char *S0_LBL[] = {
|
|||||||
"Media Player","Image Viewer","OnlyOffice","PDF Viewer"
|
"Media Player","Image Viewer","OnlyOffice","PDF Viewer"
|
||||||
};
|
};
|
||||||
static const char *S0_CMD[] = {
|
static const char *S0_CMD[] = {
|
||||||
"firefox &","xterm &","thunar &","mousepad &",
|
"firefox &","alacritty &","thunar &","mousepad &",
|
||||||
"mpv --player-operation-mode=pseudo-gui &","viewnior &",
|
"mpv --player-operation-mode=pseudo-gui &","viewnior &",
|
||||||
"onlyoffice-desktopeditors &","evince &"
|
"onlyoffice-desktopeditors &","evince &"
|
||||||
};
|
};
|
||||||
@@ -471,12 +471,12 @@ static const char *S1_CMD[] = {
|
|||||||
#define NS1 5
|
#define NS1 5
|
||||||
|
|
||||||
static const MI MENU[] = {
|
static const MI MENU[] = {
|
||||||
{ "Install SkyOS...", "xterm -e 'sudo skyinstall; exec bash' &", 0, 0,-1 },
|
{ "Install SkyOS...", "alacritty -e bash -c 'sudo skyinstall; exec bash' &", 0, 0,-1 },
|
||||||
{ NULL, NULL, 1, 0,-1 },
|
{ NULL, NULL, 1, 0,-1 },
|
||||||
{ "Applications", NULL, 0, 1, 0 },
|
{ "Applications", NULL, 0, 1, 0 },
|
||||||
{ "Settings", NULL, 0, 1, 1 },
|
{ "Settings", NULL, 0, 1, 1 },
|
||||||
{ NULL, NULL, 1, 0,-1 },
|
{ NULL, NULL, 1, 0,-1 },
|
||||||
{ "About SkyOS", "xterm -e 'fastfetch; read' &", 0, 0,-1 },
|
{ "About SkyOS", "alacritty -e bash -c 'fastfetch; read' &", 0, 0,-1 },
|
||||||
{ "Lock Screen", "xscreensaver-command -lock &", 0, 0,-1 },
|
{ "Lock Screen", "xscreensaver-command -lock &", 0, 0,-1 },
|
||||||
{ NULL, NULL, 1, 0,-1 },
|
{ NULL, NULL, 1, 0,-1 },
|
||||||
{ "Restart", "systemctl reboot", 0, 0,-1 },
|
{ "Restart", "systemctl reboot", 0, 0,-1 },
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ xorg-xrandr
|
|||||||
xorg-xset
|
xorg-xset
|
||||||
xorg-xsetroot
|
xorg-xsetroot
|
||||||
xterm
|
xterm
|
||||||
|
alacritty
|
||||||
ttf-dejavu
|
ttf-dejavu
|
||||||
ttf-liberation
|
ttf-liberation
|
||||||
noto-fonts
|
noto-fonts
|
||||||
@@ -420,6 +421,59 @@ URxvt*background: #0E1520
|
|||||||
URxvt*foreground: #C8D4E8
|
URxvt*foreground: #C8D4E8
|
||||||
XRES
|
XRES
|
||||||
|
|
||||||
|
mkdir -p "$SKEL/.config/alacritty"
|
||||||
|
cat > "$SKEL/.config/alacritty/alacritty.toml" <<'ALACRITTY'
|
||||||
|
[window]
|
||||||
|
padding = { x = 10, y = 8 }
|
||||||
|
decorations = "none"
|
||||||
|
opacity = 0.96
|
||||||
|
title = "Terminal"
|
||||||
|
|
||||||
|
[font]
|
||||||
|
normal = { family = "DejaVu Sans Mono", style = "Regular" }
|
||||||
|
bold = { family = "DejaVu Sans Mono", style = "Bold" }
|
||||||
|
size = 11.0
|
||||||
|
|
||||||
|
[colors.primary]
|
||||||
|
background = "#0E1520"
|
||||||
|
foreground = "#C8D4E8"
|
||||||
|
|
||||||
|
[colors.cursor]
|
||||||
|
text = "#0E1520"
|
||||||
|
cursor = "#4A90D9"
|
||||||
|
|
||||||
|
[colors.normal]
|
||||||
|
black = "#1A1E2A"
|
||||||
|
red = "#CC4444"
|
||||||
|
green = "#44AA66"
|
||||||
|
yellow = "#BBAA22"
|
||||||
|
blue = "#4488CC"
|
||||||
|
magenta = "#8844CC"
|
||||||
|
cyan = "#44AACC"
|
||||||
|
white = "#C8D4E8"
|
||||||
|
|
||||||
|
[colors.bright]
|
||||||
|
black = "#3A4050"
|
||||||
|
red = "#FF6666"
|
||||||
|
green = "#66CC88"
|
||||||
|
yellow = "#DDCC44"
|
||||||
|
blue = "#66AAFF"
|
||||||
|
magenta = "#AA66FF"
|
||||||
|
cyan = "#66CCEE"
|
||||||
|
white = "#EEF4FF"
|
||||||
|
|
||||||
|
[colors.selection]
|
||||||
|
background = "#2060A0"
|
||||||
|
text = "#F0F4FF"
|
||||||
|
|
||||||
|
[scrolling]
|
||||||
|
history = 10000
|
||||||
|
|
||||||
|
[cursor]
|
||||||
|
style = { shape = "Block", blinking = "On" }
|
||||||
|
blink_interval = 500
|
||||||
|
ALACRITTY
|
||||||
|
|
||||||
mkdir -p "$SKEL/.config/dunst"
|
mkdir -p "$SKEL/.config/dunst"
|
||||||
cat > "$SKEL/.config/dunst/dunstrc" <<'DUNST'
|
cat > "$SKEL/.config/dunst/dunstrc" <<'DUNST'
|
||||||
[global]
|
[global]
|
||||||
|
|||||||
+24
-24
@@ -1,32 +1,31 @@
|
|||||||
# SkyOS GTK2 Theme — BeOS/SkyOS tan palette
|
# SkyOS GTK2 Theme — dark navy palette (legacy GTK2 apps)
|
||||||
# Covers legacy GTK2 apps (GIMP, older system tools)
|
|
||||||
|
|
||||||
gtk-color-scheme = "bg_color:#D8CEAA\nfg_color:#100800\nbase_color:#F5F0E0\ntext_color:#100800\nselected_bg_color:#4A6888\nselected_fg_color:#FFFFFF\ntooltip_bg_color:#FFFCE0\ntooltip_fg_color:#100800"
|
gtk-color-scheme = "bg_color:#1E2436\nfg_color:#D8E4F4\nbase_color:#0E1424\ntext_color:#D8E4F4\nselected_bg_color:#1E4D78\nselected_fg_color:#F0F6FF\ntooltip_bg_color:#0C1020\ntooltip_fg_color:#D8E4F4"
|
||||||
|
|
||||||
style "default" {
|
style "default" {
|
||||||
bg[NORMAL] = @bg_color
|
bg[NORMAL] = @bg_color
|
||||||
bg[PRELIGHT] = "#E8DEC0"
|
bg[PRELIGHT] = "#283650"
|
||||||
bg[ACTIVE] = "#B0A888"
|
bg[ACTIVE] = "#181E2E"
|
||||||
bg[SELECTED] = @selected_bg_color
|
bg[SELECTED] = @selected_bg_color
|
||||||
bg[INSENSITIVE] = @bg_color
|
bg[INSENSITIVE] = "#161C2A"
|
||||||
|
|
||||||
fg[NORMAL] = @fg_color
|
fg[NORMAL] = @fg_color
|
||||||
fg[PRELIGHT] = @fg_color
|
fg[PRELIGHT] = @fg_color
|
||||||
fg[ACTIVE] = @fg_color
|
fg[ACTIVE] = @fg_color
|
||||||
fg[SELECTED] = @selected_fg_color
|
fg[SELECTED] = @selected_fg_color
|
||||||
fg[INSENSITIVE] = "#7A7060"
|
fg[INSENSITIVE] = "#48587A"
|
||||||
|
|
||||||
base[NORMAL] = @base_color
|
base[NORMAL] = @base_color
|
||||||
base[PRELIGHT] = @base_color
|
base[PRELIGHT] = "#141C2A"
|
||||||
base[ACTIVE] = "#D0C8A8"
|
base[ACTIVE] = "#0A101E"
|
||||||
base[SELECTED] = @selected_bg_color
|
base[SELECTED] = @selected_bg_color
|
||||||
base[INSENSITIVE] = @bg_color
|
base[INSENSITIVE] = "#161C2A"
|
||||||
|
|
||||||
text[NORMAL] = @text_color
|
text[NORMAL] = @text_color
|
||||||
text[PRELIGHT] = @text_color
|
text[PRELIGHT] = @text_color
|
||||||
text[ACTIVE] = @text_color
|
text[ACTIVE] = @text_color
|
||||||
text[SELECTED] = @selected_fg_color
|
text[SELECTED] = @selected_fg_color
|
||||||
text[INSENSITIVE] = "#7A7060"
|
text[INSENSITIVE] = "#48587A"
|
||||||
|
|
||||||
GtkWidget::focus-line-width = 1
|
GtkWidget::focus-line-width = 1
|
||||||
GtkButton::default-border = { 1, 1, 1, 1 }
|
GtkButton::default-border = { 1, 1, 1, 1 }
|
||||||
@@ -35,17 +34,17 @@ style "default" {
|
|||||||
class "GtkWidget" style "default"
|
class "GtkWidget" style "default"
|
||||||
|
|
||||||
style "menubar" {
|
style "menubar" {
|
||||||
bg[NORMAL] = "#C8BE9A"
|
bg[NORMAL] = "#161C2A"
|
||||||
bg[PRELIGHT] = "#4A6888"
|
bg[PRELIGHT] = "#1E4D78"
|
||||||
fg[PRELIGHT] = "#FFFFFF"
|
fg[PRELIGHT] = "#F0F6FF"
|
||||||
}
|
}
|
||||||
class "GtkMenuBar" style "menubar"
|
class "GtkMenuBar" style "menubar"
|
||||||
|
|
||||||
style "menu" {
|
style "menu" {
|
||||||
bg[NORMAL] = "#D8CEAA"
|
bg[NORMAL] = "#161C2A"
|
||||||
bg[PRELIGHT] = "#4A6888"
|
bg[PRELIGHT] = "#1E4D78"
|
||||||
fg[NORMAL] = "#100800"
|
fg[NORMAL] = "#D8E4F4"
|
||||||
fg[PRELIGHT] = "#FFFFFF"
|
fg[PRELIGHT] = "#F0F6FF"
|
||||||
}
|
}
|
||||||
class "GtkMenu" style "menu"
|
class "GtkMenu" style "menu"
|
||||||
class "GtkMenuItem" style "menu"
|
class "GtkMenuItem" style "menu"
|
||||||
@@ -60,13 +59,14 @@ style "entry" {
|
|||||||
bg[NORMAL] = @base_color
|
bg[NORMAL] = @base_color
|
||||||
bg[SELECTED] = @selected_bg_color
|
bg[SELECTED] = @selected_bg_color
|
||||||
fg[NORMAL] = @text_color
|
fg[NORMAL] = @text_color
|
||||||
|
text[NORMAL] = @text_color
|
||||||
}
|
}
|
||||||
class "GtkEntry" style "entry"
|
class "GtkEntry" style "entry"
|
||||||
|
|
||||||
gtk-theme-name = "SkyOS"
|
gtk-theme-name = "SkyOS"
|
||||||
gtk-icon-theme-name = "Adwaita"
|
gtk-icon-theme-name = "Adwaita"
|
||||||
gtk-font-name = "Sans 10"
|
gtk-font-name = "Sans 10"
|
||||||
gtk-cursor-theme-name = "DMZ-White"
|
gtk-cursor-theme-name = "DMZ-White"
|
||||||
gtk-button-images = 0
|
gtk-button-images = 0
|
||||||
gtk-menu-images = 0
|
gtk-menu-images = 0
|
||||||
gtk-toolbar-style = GTK_TOOLBAR_ICONS
|
gtk-toolbar-style = GTK_TOOLBAR_ICONS
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
/* SkyOS GTK3 Theme — BeOS/SkyOS tan palette */
|
/* SkyOS GTK3 Theme — dark navy palette matching skywm/skydeskbar */
|
||||||
|
|
||||||
/* ── variables ───────────────────────────────────────────────────────── */
|
@define-color bg_color #1E2436;
|
||||||
@define-color bg_color #D8CEAA;
|
@define-color bg_dark #161C2A;
|
||||||
@define-color bg_dark #C8BE9A;
|
@define-color bg_darker #0E1220;
|
||||||
@define-color bg_darker #B0A888;
|
@define-color bg_light #262E42;
|
||||||
@define-color bg_light #E8DEC0;
|
@define-color border_light #3A6898;
|
||||||
@define-color border_light #F0E8D0;
|
@define-color border_dark #080C18;
|
||||||
@define-color border_dark #6B5F50;
|
@define-color text_color #D8E4F4;
|
||||||
@define-color text_color #100800;
|
@define-color text_disabled #48587A;
|
||||||
@define-color text_disabled #7A7060;
|
@define-color selected_bg #1E4D78;
|
||||||
@define-color selected_bg #4A6888;
|
@define-color selected_fg #F0F6FF;
|
||||||
@define-color selected_fg #FFFFFF;
|
@define-color accent #3A6898;
|
||||||
@define-color accent #4A6888;
|
@define-color button_bg #202A3C;
|
||||||
@define-color button_bg #C8BE9A;
|
@define-color button_hover #283650;
|
||||||
@define-color button_hover #D8D0B8;
|
@define-color button_active #181E2E;
|
||||||
@define-color button_active #A89E88;
|
@define-color entry_bg #0E1424;
|
||||||
@define-color entry_bg #F5F0E0;
|
@define-color tooltip_bg #0C1020;
|
||||||
@define-color tooltip_bg #FFFCE0;
|
@define-color link_color #5088CC;
|
||||||
@define-color link_color #2244AA;
|
|
||||||
|
|
||||||
/* ── window / base ───────────────────────────────────────────────────── */
|
/* ── base ─────────────────────────────────────────────────────────── */
|
||||||
* {
|
* {
|
||||||
font-family: "Sans";
|
font-family: "Sans";
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
@@ -33,7 +32,7 @@ window, .background {
|
|||||||
color: @text_color;
|
color: @text_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── header bars ─────────────────────────────────────────────────────── */
|
/* ── header bars ─────────────────────────────────────────────────── */
|
||||||
headerbar, .titlebar {
|
headerbar, .titlebar {
|
||||||
background: linear-gradient(to bottom, @bg_light, @bg_dark);
|
background: linear-gradient(to bottom, @bg_light, @bg_dark);
|
||||||
border-bottom: 1px solid @border_dark;
|
border-bottom: 1px solid @border_dark;
|
||||||
@@ -43,41 +42,42 @@ headerbar, .titlebar {
|
|||||||
}
|
}
|
||||||
headerbar .title { font-weight: bold; }
|
headerbar .title { font-weight: bold; }
|
||||||
|
|
||||||
/* ── buttons ─────────────────────────────────────────────────────────── */
|
/* ── buttons ─────────────────────────────────────────────────────── */
|
||||||
button {
|
button {
|
||||||
background: linear-gradient(to bottom, @border_light, @button_bg);
|
background: linear-gradient(to bottom, @bg_light, @button_bg);
|
||||||
border: 1px solid @border_dark;
|
border: 1px solid @border_dark;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
color: @text_color;
|
color: @text_color;
|
||||||
box-shadow: inset 1px 1px 0 @border_light, inset -1px -1px 0 @border_dark;
|
box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), inset 0 -1px 0 rgba(0,0,0,0.3);
|
||||||
}
|
}
|
||||||
button:hover {
|
button:hover {
|
||||||
background: linear-gradient(to bottom, #F8F0D8, @button_hover);
|
background: linear-gradient(to bottom, @button_hover, @bg_light);
|
||||||
|
border-color: @border_light;
|
||||||
}
|
}
|
||||||
button:active, button:checked {
|
button:active, button:checked {
|
||||||
background: linear-gradient(to bottom, @button_active, @bg_darker);
|
background: linear-gradient(to bottom, @button_active, @bg_dark);
|
||||||
box-shadow: inset 1px 1px 0 @border_dark, inset -1px -1px 0 @border_light;
|
box-shadow: inset 0 1px 0 rgba(0,0,0,0.3);
|
||||||
}
|
}
|
||||||
button:disabled {
|
button:disabled {
|
||||||
color: @text_disabled;
|
color: @text_disabled;
|
||||||
background: @bg_color;
|
background: @bg_color;
|
||||||
}
|
}
|
||||||
button.suggested-action {
|
button.suggested-action {
|
||||||
background: linear-gradient(to bottom, #5A7898, @accent);
|
background: linear-gradient(to bottom, #2A5E88, @selected_bg);
|
||||||
color: white;
|
color: @selected_fg;
|
||||||
border-color: #3A5878;
|
border-color: #1A3E58;
|
||||||
}
|
}
|
||||||
button.destructive-action {
|
button.destructive-action {
|
||||||
background: linear-gradient(to bottom, #DD5555, #BB3333);
|
background: linear-gradient(to bottom, #CC4444, #AA2222);
|
||||||
color: white;
|
color: white;
|
||||||
border-color: #993333;
|
border-color: #882222;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── menus ───────────────────────────────────────────────────────────── */
|
/* ── menus ───────────────────────────────────────────────────────── */
|
||||||
menu, .menu, .context-menu {
|
menu, .menu, .context-menu {
|
||||||
background-color: @bg_color;
|
background-color: @bg_dark;
|
||||||
border: 1px solid @border_dark;
|
border: 1px solid @border_light;
|
||||||
padding: 2px 0;
|
padding: 2px 0;
|
||||||
}
|
}
|
||||||
menuitem {
|
menuitem {
|
||||||
@@ -96,22 +96,22 @@ separator, menuitem > separator {
|
|||||||
margin: 3px 6px;
|
margin: 3px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── entries (text input) ────────────────────────────────────────────── */
|
/* ── text inputs ─────────────────────────────────────────────────── */
|
||||||
entry {
|
entry {
|
||||||
background-color: @entry_bg;
|
background-color: @entry_bg;
|
||||||
border: 1px solid @border_dark;
|
border: 1px solid @border_dark;
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
padding: 3px 6px;
|
padding: 3px 6px;
|
||||||
color: @text_color;
|
color: @text_color;
|
||||||
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.12);
|
box-shadow: inset 0 1px 2px rgba(0,0,0,0.4);
|
||||||
}
|
}
|
||||||
entry:focus {
|
entry:focus {
|
||||||
border-color: @accent;
|
border-color: @accent;
|
||||||
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.12), 0 0 0 2px rgba(74,104,136,0.25);
|
box-shadow: inset 0 1px 2px rgba(0,0,0,0.4), 0 0 0 2px rgba(58,104,152,0.35);
|
||||||
}
|
}
|
||||||
entry:disabled { background-color: @bg_color; color: @text_disabled; }
|
entry:disabled { background-color: @bg_darker; color: @text_disabled; }
|
||||||
|
|
||||||
/* ── lists & trees ───────────────────────────────────────────────────── */
|
/* ── lists & trees ───────────────────────────────────────────────── */
|
||||||
treeview, listview, .view {
|
treeview, listview, .view {
|
||||||
background-color: @entry_bg;
|
background-color: @entry_bg;
|
||||||
color: @text_color;
|
color: @text_color;
|
||||||
@@ -127,8 +127,9 @@ treeview header button {
|
|||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
treeview.odd-row { background-color: @bg_darker; }
|
||||||
|
|
||||||
/* ── notebooks (tabs) ────────────────────────────────────────────────── */
|
/* ── notebooks (tabs) ────────────────────────────────────────────── */
|
||||||
notebook > header {
|
notebook > header {
|
||||||
background-color: @bg_darker;
|
background-color: @bg_darker;
|
||||||
border-bottom: 1px solid @border_dark;
|
border-bottom: 1px solid @border_dark;
|
||||||
@@ -140,15 +141,17 @@ notebook > header tab {
|
|||||||
padding: 4px 12px;
|
padding: 4px 12px;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
border-radius: 2px 2px 0 0;
|
border-radius: 2px 2px 0 0;
|
||||||
|
color: @text_disabled;
|
||||||
}
|
}
|
||||||
notebook > header tab:checked {
|
notebook > header tab:checked {
|
||||||
background-color: @bg_color;
|
background-color: @bg_color;
|
||||||
border-bottom: 1px solid @bg_color;
|
border-bottom: 1px solid @bg_color;
|
||||||
margin-bottom: -1px;
|
margin-bottom: -1px;
|
||||||
|
color: @text_color;
|
||||||
}
|
}
|
||||||
notebook > stack { background-color: @bg_color; }
|
notebook > stack { background-color: @bg_color; }
|
||||||
|
|
||||||
/* ── scrollbars ──────────────────────────────────────────────────────── */
|
/* ── scrollbars ──────────────────────────────────────────────────── */
|
||||||
scrollbar {
|
scrollbar {
|
||||||
background-color: @bg_darker;
|
background-color: @bg_darker;
|
||||||
border: 1px solid @border_dark;
|
border: 1px solid @border_dark;
|
||||||
@@ -160,45 +163,46 @@ scrollbar slider {
|
|||||||
min-width: 12px;
|
min-width: 12px;
|
||||||
min-height: 12px;
|
min-height: 12px;
|
||||||
}
|
}
|
||||||
scrollbar slider:hover { background-color: @button_hover; }
|
scrollbar slider:hover { background-color: @button_hover; border-color: @border_light; }
|
||||||
scrollbar button { background-color: @bg_dark; }
|
scrollbar button { background-color: @bg_dark; color: @text_color; }
|
||||||
|
|
||||||
/* ── toolbars ────────────────────────────────────────────────────────── */
|
/* ── toolbars ────────────────────────────────────────────────────── */
|
||||||
toolbar, .toolbar {
|
toolbar, .toolbar {
|
||||||
background: linear-gradient(to bottom, @bg_light, @bg_dark);
|
background: linear-gradient(to bottom, @bg_light, @bg_dark);
|
||||||
border-bottom: 1px solid @border_dark;
|
border-bottom: 1px solid @border_dark;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── statusbar ───────────────────────────────────────────────────────── */
|
/* ── statusbar ───────────────────────────────────────────────────── */
|
||||||
statusbar {
|
statusbar {
|
||||||
background-color: @bg_darker;
|
background-color: @bg_darker;
|
||||||
border-top: 1px solid @border_dark;
|
border-top: 1px solid @border_dark;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
font-size: 9pt;
|
font-size: 9pt;
|
||||||
|
color: @text_disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── tooltips ────────────────────────────────────────────────────────── */
|
/* ── tooltips ────────────────────────────────────────────────────── */
|
||||||
tooltip {
|
tooltip {
|
||||||
background-color: @tooltip_bg;
|
background-color: @tooltip_bg;
|
||||||
border: 1px solid @border_dark;
|
border: 1px solid @border_light;
|
||||||
color: @text_color;
|
color: @text_color;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── progress bars ───────────────────────────────────────────────────── */
|
/* ── progress bars ───────────────────────────────────────────────── */
|
||||||
progressbar trough {
|
progressbar trough {
|
||||||
background-color: @bg_darker;
|
background-color: @bg_darker;
|
||||||
border: 1px solid @border_dark;
|
border: 1px solid @border_dark;
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
}
|
}
|
||||||
progressbar progress {
|
progressbar progress {
|
||||||
background-color: @accent;
|
background: linear-gradient(to right, @selected_bg, @accent);
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── checkboxes & radio buttons ──────────────────────────────────────── */
|
/* ── checkboxes & radio buttons ──────────────────────────────────── */
|
||||||
checkbutton check, radiobutton radio {
|
checkbutton check, radiobutton radio {
|
||||||
background-color: @entry_bg;
|
background-color: @entry_bg;
|
||||||
border: 1px solid @border_dark;
|
border: 1px solid @border_dark;
|
||||||
@@ -206,24 +210,32 @@ checkbutton check, radiobutton radio {
|
|||||||
min-height: 14px;
|
min-height: 14px;
|
||||||
}
|
}
|
||||||
checkbutton check:checked {
|
checkbutton check:checked {
|
||||||
background-color: @accent;
|
background-color: @selected_bg;
|
||||||
color: white;
|
border-color: @accent;
|
||||||
|
color: @selected_fg;
|
||||||
}
|
}
|
||||||
radiobutton radio:checked { background-color: @accent; }
|
radiobutton radio:checked { background-color: @selected_bg; border-color: @accent; }
|
||||||
|
|
||||||
/* ── spin buttons ────────────────────────────────────────────────────── */
|
/* ── spin buttons ────────────────────────────────────────────────── */
|
||||||
spinbutton { background-color: @entry_bg; border: 1px solid @border_dark; }
|
spinbutton { background-color: @entry_bg; border: 1px solid @border_dark; }
|
||||||
spinbutton button { border-radius: 0; padding: 0 4px; }
|
spinbutton button { border-radius: 0; padding: 0 4px; background: @bg_dark; }
|
||||||
|
|
||||||
/* ── combo boxes ─────────────────────────────────────────────────────── */
|
/* ── combo boxes ─────────────────────────────────────────────────── */
|
||||||
combobox button {
|
combobox button {
|
||||||
background: linear-gradient(to bottom, @border_light, @button_bg);
|
background: linear-gradient(to bottom, @bg_light, @button_bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── file chooser ────────────────────────────────────────────────────── */
|
/* ── sidebar (file chooser) ──────────────────────────────────────── */
|
||||||
.sidebar { background-color: @bg_darker; }
|
.sidebar { background-color: @bg_darker; border-right: 1px solid @border_dark; }
|
||||||
|
.sidebar row { color: @text_color; }
|
||||||
.sidebar row:selected { background-color: @selected_bg; color: @selected_fg; }
|
.sidebar row:selected { background-color: @selected_bg; color: @selected_fg; }
|
||||||
|
|
||||||
/* ── links ───────────────────────────────────────────────────────────── */
|
/* ── links ───────────────────────────────────────────────────────── */
|
||||||
*:link { color: @link_color; }
|
*:link { color: @link_color; }
|
||||||
*:visited { color: #6644AA; }
|
*:visited { color: #8860CC; }
|
||||||
|
|
||||||
|
/* ── infobar / message bar ───────────────────────────────────────── */
|
||||||
|
infobar { background-color: @bg_light; border-bottom: 1px solid @border_dark; }
|
||||||
|
|
||||||
|
/* ── Thunar-specific tweaks ──────────────────────────────────────── */
|
||||||
|
.thunar .pathbar button { border-radius: 2px; margin: 1px; }
|
||||||
+1
-1
@@ -14,7 +14,7 @@ endif
|
|||||||
CFLAGS = -Wall -Wextra -O2 -Iinclude $(PKG_XFT_C)
|
CFLAGS = -Wall -Wextra -O2 -Iinclude $(PKG_XFT_C)
|
||||||
LDFLAGS = $(PKG_XFT_L)
|
LDFLAGS = $(PKG_XFT_L)
|
||||||
|
|
||||||
SRC = src/wm.c src/client.c src/events.c src/draw.c src/color.c src/menu.c
|
SRC = src/wm.c src/client.c src/events.c src/draw.c src/color.c src/menu.c src/switcher.c
|
||||||
OBJ = $(SRC:.c=.o)
|
OBJ = $(SRC:.c=.o)
|
||||||
BIN = skywm
|
BIN = skywm
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,14 @@ typedef struct WM {
|
|||||||
int menu_visible;
|
int menu_visible;
|
||||||
int menu_x, menu_y;
|
int menu_x, menu_y;
|
||||||
int menu_hovered;
|
int menu_hovered;
|
||||||
|
|
||||||
|
/* Alt+Tab visual switcher */
|
||||||
|
Window swl_win;
|
||||||
|
int swl_visible;
|
||||||
|
int swl_idx;
|
||||||
|
int swl_count;
|
||||||
|
Window swl_wins[64];
|
||||||
|
char swl_titles[64][128];
|
||||||
} WM;
|
} WM;
|
||||||
|
|
||||||
/* core */
|
/* core */
|
||||||
@@ -163,6 +171,12 @@ void menu_draw(WM *wm);
|
|||||||
void menu_click(WM *wm, int px, int py);
|
void menu_click(WM *wm, int px, int py);
|
||||||
int menu_item_at(int py);
|
int menu_item_at(int py);
|
||||||
|
|
||||||
|
/* switcher */
|
||||||
|
void switcher_show(WM *wm);
|
||||||
|
void switcher_next(WM *wm);
|
||||||
|
void switcher_hide(WM *wm, int commit);
|
||||||
|
void switcher_draw(WM *wm);
|
||||||
|
|
||||||
/* events */
|
/* events */
|
||||||
void on_map_request(WM *wm, XMapRequestEvent *e);
|
void on_map_request(WM *wm, XMapRequestEvent *e);
|
||||||
void on_unmap_notify(WM *wm, XUnmapEvent *e);
|
void on_unmap_notify(WM *wm, XUnmapEvent *e);
|
||||||
@@ -176,5 +190,6 @@ void on_key_press(WM *wm, XKeyEvent *e);
|
|||||||
void on_enter_notify(WM *wm, XCrossingEvent *e);
|
void on_enter_notify(WM *wm, XCrossingEvent *e);
|
||||||
void on_client_message(WM *wm, XClientMessageEvent *e);
|
void on_client_message(WM *wm, XClientMessageEvent *e);
|
||||||
void on_property_notify(WM *wm, XPropertyEvent *e);
|
void on_property_notify(WM *wm, XPropertyEvent *e);
|
||||||
|
void on_key_release(WM *wm, XKeyEvent *e);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+23
-7
@@ -66,6 +66,10 @@ void on_expose(WM *wm, XExposeEvent *e) {
|
|||||||
menu_draw(wm);
|
menu_draw(wm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (wm->swl_visible && e->window == wm->swl_win) {
|
||||||
|
switcher_draw(wm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Client *c = client_find_by_frame(wm, e->window);
|
Client *c = client_find_by_frame(wm, e->window);
|
||||||
if (c && !c->minimized) frame_draw(wm, c);
|
if (c && !c->minimized) frame_draw(wm, c);
|
||||||
}
|
}
|
||||||
@@ -259,13 +263,17 @@ void on_key_press(WM *wm, XKeyEvent *e) {
|
|||||||
if ((e->state & Mod1Mask) && sym == XK_F4 && wm->focused)
|
if ((e->state & Mod1Mask) && sym == XK_F4 && wm->focused)
|
||||||
send_delete(wm, wm->focused->win);
|
send_delete(wm, wm->focused->win);
|
||||||
|
|
||||||
/* Alt+Tab — cycle windows */
|
/* Alt+Tab — visual switcher */
|
||||||
if ((e->state & Mod1Mask) && sym == XK_Tab && wm->clients) {
|
if ((e->state & Mod1Mask) && sym == XK_Tab) {
|
||||||
Client *start = wm->focused ? wm->focused->next : wm->clients;
|
if (wm->swl_visible) switcher_next(wm);
|
||||||
Client *n = start;
|
else if (wm->clients) switcher_show(wm);
|
||||||
while (n && n->minimized) n = n->next;
|
return;
|
||||||
if (!n) { n = wm->clients; while (n && n->minimized) n = n->next; }
|
}
|
||||||
if (n && n != wm->focused) client_focus(wm, n);
|
|
||||||
|
/* While switcher is visible, eat all other keys until Alt released */
|
||||||
|
if (wm->swl_visible) {
|
||||||
|
if (sym == XK_Escape) switcher_hide(wm, 0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alt+F9 — minimize */
|
/* Alt+F9 — minimize */
|
||||||
@@ -300,3 +308,11 @@ void on_key_press(WM *wm, XKeyEvent *e) {
|
|||||||
if (sym == XK_Escape && wm->menu_visible)
|
if (sym == XK_Escape && wm->menu_visible)
|
||||||
menu_hide(wm);
|
menu_hide(wm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void on_key_release(WM *wm, XKeyEvent *e) {
|
||||||
|
if (!wm->swl_visible) return;
|
||||||
|
KeySym sym = XLookupKeysym(e, 0);
|
||||||
|
if (sym == XK_Alt_L || sym == XK_Alt_R ||
|
||||||
|
sym == XK_Meta_L || sym == XK_Meta_R)
|
||||||
|
switcher_hide(wm, 1);
|
||||||
|
}
|
||||||
+2
-2
@@ -6,12 +6,12 @@
|
|||||||
|
|
||||||
static const MenuItem MENU_ITEMS[] = {
|
static const MenuItem MENU_ITEMS[] = {
|
||||||
{ "App Launcher", "skylauncher &" },
|
{ "App Launcher", "skylauncher &" },
|
||||||
{ "Terminal", "xterm &" },
|
{ "Terminal", "alacritty &" },
|
||||||
{ "File Manager", "thunar &" },
|
{ "File Manager", "thunar &" },
|
||||||
{ "Text Editor", "mousepad &" },
|
{ "Text Editor", "mousepad &" },
|
||||||
{ "──────────────────", NULL },
|
{ "──────────────────", NULL },
|
||||||
{ "Web Browser", "firefox &" },
|
{ "Web Browser", "firefox &" },
|
||||||
{ "System Monitor", "xterm -T 'System Monitor' -e htop &" },
|
{ "System Monitor", "alacritty -T 'System Monitor' -e htop &" },
|
||||||
{ "Volume Control", "pavucontrol &" },
|
{ "Volume Control", "pavucontrol &" },
|
||||||
{ "Display Settings", "arandr &" },
|
{ "Display Settings", "arandr &" },
|
||||||
{ "──────────────────", NULL },
|
{ "──────────────────", NULL },
|
||||||
|
|||||||
@@ -0,0 +1,179 @@
|
|||||||
|
#include "wm.h"
|
||||||
|
|
||||||
|
#define SWL_ITEM_W 130
|
||||||
|
#define SWL_ITEM_H 68
|
||||||
|
#define SWL_ICON_SZ 34
|
||||||
|
#define SWL_PAD 12
|
||||||
|
#define SWL_MAX_VIS 8
|
||||||
|
|
||||||
|
static void swl_populate(WM *wm) {
|
||||||
|
wm->swl_count = 0;
|
||||||
|
/* current focused window goes first */
|
||||||
|
if (wm->focused && !wm->focused->minimized) {
|
||||||
|
wm->swl_wins[0] = wm->focused->win;
|
||||||
|
strncpy(wm->swl_titles[0], wm->focused->title, 127);
|
||||||
|
wm->swl_titles[0][127] = '\0';
|
||||||
|
wm->swl_count = 1;
|
||||||
|
}
|
||||||
|
for (Client *c = wm->clients; c && wm->swl_count < 64; c = c->next) {
|
||||||
|
if (c->minimized) continue;
|
||||||
|
if (wm->focused && c == wm->focused) continue;
|
||||||
|
wm->swl_wins[wm->swl_count] = c->win;
|
||||||
|
strncpy(wm->swl_titles[wm->swl_count], c->title, 127);
|
||||||
|
wm->swl_titles[wm->swl_count][127] = '\0';
|
||||||
|
wm->swl_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int swl_vis(WM *wm) {
|
||||||
|
return wm->swl_count < SWL_MAX_VIS ? wm->swl_count : SWL_MAX_VIS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scroll window that keeps the selected item centered */
|
||||||
|
static int swl_view_start(WM *wm) {
|
||||||
|
int vis = swl_vis(wm);
|
||||||
|
if (wm->swl_count <= SWL_MAX_VIS) return 0;
|
||||||
|
int start = wm->swl_idx - vis / 2;
|
||||||
|
if (start < 0) start = 0;
|
||||||
|
if (start + vis > wm->swl_count) start = wm->swl_count - vis;
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void switcher_draw(WM *wm) {
|
||||||
|
if (!wm->swl_visible || !wm->swl_win) return;
|
||||||
|
|
||||||
|
int vis = swl_vis(wm);
|
||||||
|
int vstart = swl_view_start(wm);
|
||||||
|
int tw = vis * SWL_ITEM_W + (vis + 1) * SWL_PAD;
|
||||||
|
int th = SWL_ITEM_H + SWL_PAD * 2;
|
||||||
|
|
||||||
|
XSetForeground(wm->dpy, wm->gc, color_alloc(wm, 0x141A28));
|
||||||
|
XFillRectangle(wm->dpy, wm->swl_win, wm->gc, 0, 0, tw, th);
|
||||||
|
|
||||||
|
XSetForeground(wm->dpy, wm->gc, color_alloc(wm, COLOR_BORDER_LIGHT));
|
||||||
|
XDrawRectangle(wm->dpy, wm->swl_win, wm->gc, 0, 0, tw - 1, th - 1);
|
||||||
|
XSetForeground(wm->dpy, wm->gc, color_alloc(wm, COLOR_BORDER_DARK));
|
||||||
|
XDrawRectangle(wm->dpy, wm->swl_win, wm->gc, 1, 1, tw - 3, th - 3);
|
||||||
|
|
||||||
|
XftDraw *xd = XftDrawCreate(wm->dpy, wm->swl_win, wm->visual, wm->cmap);
|
||||||
|
if (!xd) return;
|
||||||
|
|
||||||
|
for (int vi = 0; vi < vis; vi++) {
|
||||||
|
int i = vstart + vi;
|
||||||
|
int selected = (i == wm->swl_idx);
|
||||||
|
int ix = SWL_PAD + vi * (SWL_ITEM_W + SWL_PAD);
|
||||||
|
int iy = SWL_PAD;
|
||||||
|
|
||||||
|
unsigned long card_bg = color_alloc(wm, selected ? COLOR_TITLE_ACTIVE : 0x1C2338);
|
||||||
|
XSetForeground(wm->dpy, wm->gc, card_bg);
|
||||||
|
XFillRectangle(wm->dpy, wm->swl_win, wm->gc, ix, iy, SWL_ITEM_W, SWL_ITEM_H);
|
||||||
|
|
||||||
|
XSetForeground(wm->dpy, wm->gc,
|
||||||
|
color_alloc(wm, selected ? COLOR_BORDER_LIGHT : 0x242C3E));
|
||||||
|
XDrawRectangle(wm->dpy, wm->swl_win, wm->gc, ix, iy, SWL_ITEM_W - 1, SWL_ITEM_H - 1);
|
||||||
|
|
||||||
|
/* letter icon */
|
||||||
|
int icon_x = ix + (SWL_ITEM_W - SWL_ICON_SZ) / 2;
|
||||||
|
int icon_y = iy + 8;
|
||||||
|
XSetForeground(wm->dpy, wm->gc,
|
||||||
|
color_alloc(wm, selected ? 0x285898 : 0x182538));
|
||||||
|
XFillRectangle(wm->dpy, wm->swl_win, wm->gc, icon_x, icon_y, SWL_ICON_SZ, SWL_ICON_SZ);
|
||||||
|
|
||||||
|
char letter[2] = { wm->swl_titles[i][0] ? wm->swl_titles[i][0] : '?', '\0' };
|
||||||
|
if (letter[0] >= 'a' && letter[0] <= 'z') letter[0] -= 32;
|
||||||
|
|
||||||
|
XftColor icon_col;
|
||||||
|
xft_color(wm, selected ? COLOR_TITLE_TEXT_ACT : COLOR_TITLE_TEXT_INACT, &icon_col);
|
||||||
|
XGlyphInfo ext;
|
||||||
|
XftTextExtentsUtf8(wm->dpy, wm->font_title, (const FcChar8 *)letter, 1, &ext);
|
||||||
|
int lx = icon_x + (SWL_ICON_SZ - (int)ext.width) / 2;
|
||||||
|
int ly = icon_y + (SWL_ICON_SZ + (int)ext.height) / 2 - ext.y;
|
||||||
|
XftDrawStringUtf8(xd, &icon_col, wm->font_title, lx, ly, (const FcChar8 *)letter, 1);
|
||||||
|
XftColorFree(wm->dpy, wm->visual, wm->cmap, &icon_col);
|
||||||
|
|
||||||
|
/* title below icon */
|
||||||
|
const char *title = wm->swl_titles[i];
|
||||||
|
XftColor title_col;
|
||||||
|
xft_color(wm, selected ? COLOR_TITLE_TEXT_ACT : COLOR_TITLE_TEXT_INACT, &title_col);
|
||||||
|
XGlyphInfo text_ext;
|
||||||
|
XftTextExtentsUtf8(wm->dpy, wm->font_title,
|
||||||
|
(const FcChar8 *)title, strlen(title), &text_ext);
|
||||||
|
int tx = ix + (SWL_ITEM_W - (int)text_ext.width) / 2;
|
||||||
|
if (tx < ix + 4) tx = ix + 4;
|
||||||
|
int ty = icon_y + SWL_ICON_SZ + 4 + (int)text_ext.height - text_ext.y;
|
||||||
|
XRectangle clip = { (short)(ix + 2), (short)(icon_y + SWL_ICON_SZ + 4),
|
||||||
|
(unsigned short)(SWL_ITEM_W - 4), 14 };
|
||||||
|
XftDrawSetClipRectangles(xd, 0, 0, &clip, 1);
|
||||||
|
XftDrawStringUtf8(xd, &title_col, wm->font_title, tx, ty,
|
||||||
|
(const FcChar8 *)title, strlen(title));
|
||||||
|
XftDrawSetClip(xd, None);
|
||||||
|
XftColorFree(wm->dpy, wm->visual, wm->cmap, &title_col);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* scroll arrows when more windows than fit */
|
||||||
|
if (wm->swl_count > SWL_MAX_VIS) {
|
||||||
|
XftColor arrow;
|
||||||
|
xft_color(wm, 0x5878A0, &arrow);
|
||||||
|
if (vstart > 0)
|
||||||
|
XftDrawStringUtf8(xd, &arrow, wm->font_title, 3, th / 2 + 4,
|
||||||
|
(const FcChar8 *)"\xe2\x97\x80", 3);
|
||||||
|
if (vstart + SWL_MAX_VIS < wm->swl_count)
|
||||||
|
XftDrawStringUtf8(xd, &arrow, wm->font_title, tw - 11, th / 2 + 4,
|
||||||
|
(const FcChar8 *)"\xe2\x96\xb6", 3);
|
||||||
|
XftColorFree(wm->dpy, wm->visual, wm->cmap, &arrow);
|
||||||
|
}
|
||||||
|
|
||||||
|
XftDrawDestroy(xd);
|
||||||
|
XFlush(wm->dpy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void switcher_show(WM *wm) {
|
||||||
|
swl_populate(wm);
|
||||||
|
if (wm->swl_count < 2) return;
|
||||||
|
|
||||||
|
wm->swl_idx = 1;
|
||||||
|
wm->swl_visible = 1;
|
||||||
|
|
||||||
|
int vis = swl_vis(wm);
|
||||||
|
int tw = vis * SWL_ITEM_W + (vis + 1) * SWL_PAD;
|
||||||
|
int th = SWL_ITEM_H + SWL_PAD * 2;
|
||||||
|
int sw = DisplayWidth(wm->dpy, wm->screen);
|
||||||
|
int sh = DisplayHeight(wm->dpy, wm->screen);
|
||||||
|
|
||||||
|
XSetWindowAttributes swa;
|
||||||
|
swa.override_redirect = True;
|
||||||
|
swa.background_pixel = color_alloc(wm, 0x141A28);
|
||||||
|
swa.event_mask = ExposureMask;
|
||||||
|
wm->swl_win = XCreateWindow(
|
||||||
|
wm->dpy, wm->root,
|
||||||
|
(sw - tw) / 2, (sh - th) / 2, tw, th, 2,
|
||||||
|
CopyFromParent, InputOutput, CopyFromParent,
|
||||||
|
CWOverrideRedirect | CWBackPixel | CWEventMask, &swa
|
||||||
|
);
|
||||||
|
XSetWindowBorder(wm->dpy, wm->swl_win, color_alloc(wm, COLOR_BORDER_LIGHT));
|
||||||
|
XMapRaised(wm->dpy, wm->swl_win);
|
||||||
|
switcher_draw(wm);
|
||||||
|
|
||||||
|
XGrabKeyboard(wm->dpy, wm->root, False, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void switcher_next(WM *wm) {
|
||||||
|
if (!wm->swl_visible) return;
|
||||||
|
wm->swl_idx = (wm->swl_idx + 1) % wm->swl_count;
|
||||||
|
switcher_draw(wm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void switcher_hide(WM *wm, int commit) {
|
||||||
|
if (!wm->swl_visible) return;
|
||||||
|
XUngrabKeyboard(wm->dpy, CurrentTime);
|
||||||
|
if (wm->swl_win) { XDestroyWindow(wm->dpy, wm->swl_win); wm->swl_win = 0; }
|
||||||
|
wm->swl_visible = 0;
|
||||||
|
|
||||||
|
if (commit && wm->swl_count > 0) {
|
||||||
|
Client *c = client_find_by_win(wm, wm->swl_wins[wm->swl_idx]);
|
||||||
|
if (c) {
|
||||||
|
if (c->minimized) client_restore(wm, c);
|
||||||
|
else client_focus(wm, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -79,7 +79,7 @@ void wm_init(WM *wm) {
|
|||||||
XSetErrorHandler(x_error_start);
|
XSetErrorHandler(x_error_start);
|
||||||
XSelectInput(wm->dpy, wm->root,
|
XSelectInput(wm->dpy, wm->root,
|
||||||
SubstructureRedirectMask | SubstructureNotifyMask |
|
SubstructureRedirectMask | SubstructureNotifyMask |
|
||||||
KeyPressMask | ButtonPressMask);
|
KeyPressMask | KeyReleaseMask | ButtonPressMask);
|
||||||
XSync(wm->dpy, False);
|
XSync(wm->dpy, False);
|
||||||
XSetErrorHandler(x_error_handler);
|
XSetErrorHandler(x_error_handler);
|
||||||
|
|
||||||
@@ -138,6 +138,7 @@ void wm_run(WM *wm) {
|
|||||||
case ButtonRelease: on_button_release(wm, &e.xbutton); break;
|
case ButtonRelease: on_button_release(wm, &e.xbutton); break;
|
||||||
case MotionNotify: on_motion_notify(wm, &e.xmotion); break;
|
case MotionNotify: on_motion_notify(wm, &e.xmotion); break;
|
||||||
case KeyPress: on_key_press(wm, &e.xkey); break;
|
case KeyPress: on_key_press(wm, &e.xkey); break;
|
||||||
|
case KeyRelease: on_key_release(wm, &e.xkey); break;
|
||||||
case EnterNotify: on_enter_notify(wm, &e.xcrossing); break;
|
case EnterNotify: on_enter_notify(wm, &e.xcrossing); break;
|
||||||
case ClientMessage: on_client_message(wm, &e.xclient); break;
|
case ClientMessage: on_client_message(wm, &e.xclient); break;
|
||||||
case PropertyNotify: on_property_notify(wm, &e.xproperty); break;
|
case PropertyNotify: on_property_notify(wm, &e.xproperty); break;
|
||||||
|
|||||||
Reference in new issue
Block a user