Files
OrionOS/wm/include/wm.h
T
nmemmertandClaude Sonnet 4.6 9089c14a19 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>
2026-07-23 13:11:37 -04:00

196 lines
6.5 KiB
C

#ifndef WM_H
#define WM_H
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <X11/Xft/Xft.h>
#include <X11/cursorfont.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/* ── palette (modern dark) ───────────────────────────────────────────── */
#define COLOR_TITLE_ACTIVE 0x1E4D78 /* deep blue active title bar */
#define COLOR_TITLE_INACTIVE 0x252830 /* dark grey inactive */
#define COLOR_TITLE_TEXT_ACT 0xE8EEF8 /* near-white active text */
#define COLOR_TITLE_TEXT_INACT 0x5C6070 /* dimmed inactive text */
#define COLOR_BORDER_LIGHT 0x3A6898 /* blue-grey highlight */
#define COLOR_BORDER_DARK 0x0C1018 /* near-black shadow */
#define COLOR_CLOSE_BTN 0xCC3333 /* red close */
#define COLOR_MAXIMIZE_BTN 0x2E8B44 /* green maximize */
#define COLOR_MINIMIZE_BTN 0xBB8820 /* amber minimize */
#define COLOR_CLOSE_BTN_HOV 0xFF5050
#define COLOR_MAXIMIZE_BTN_HOV 0x44CC66
#define COLOR_MINIMIZE_BTN_HOV 0xFFBB30
#define COLOR_BG 0x1A2840 /* desktop background */
#define COLOR_SNAP_OVERLAY 0x3A6898 /* snap highlight (unused, placeholder) */
/* ── geometry ────────────────────────────────────────────────────────── */
#define TITLE_HEIGHT 28 /* taller for modern look */
#define TITLE_TAB_W 200
#define BORDER_W 3
#define BTN_SIZE 14
#define BTN_MARGIN 5
#define RESIZE_GRIP 12
#define MIN_WIN_W 120
#define MIN_WIN_H 60
#define SNAP_DIST 24 /* px from edge to trigger snap */
#define DBL_CLICK_MS 400 /* double-click threshold */
/*
* Three buttons on right side (left to right): minimize, maximize, close
* close = fw - BTN_SIZE - BTN_MARGIN - BORDER_W
* max = close - BTN_SIZE - BTN_MARGIN - 2
* min = max - BTN_SIZE - BTN_MARGIN - 2
*/
#define BTN_CLOSE_X(fw) ((fw) - BTN_SIZE - BTN_MARGIN - BORDER_W)
#define BTN_MAX_X(fw) ((fw) - BTN_SIZE*2 - BTN_MARGIN*2 - BORDER_W - 2)
#define BTN_MIN_X(fw) ((fw) - BTN_SIZE*3 - BTN_MARGIN*3 - BORDER_W - 4)
#define BTN_Y (((TITLE_HEIGHT) - BTN_SIZE) / 2)
/* ── fonts ───────────────────────────────────────────────────────────── */
#define FONT_TITLE "Sans:size=9:weight=bold"
#define FONT_MENU "Sans:size=10"
/* ── drag mode ───────────────────────────────────────────────────────── */
typedef enum { DRAG_NONE, DRAG_MOVE, DRAG_RESIZE } DragMode;
/* WM_STATE values (ICCCM) */
#define WM_STATE_NORMAL 1
#define WM_STATE_ICONIC 3
#define WM_STATE_WITHDRAWN 0
typedef struct Client {
Window win;
Window frame;
int x, y;
unsigned int w, h;
int focused;
int minimized;
int maximized;
int saved_x, saved_y; /* pre-maximize position */
unsigned saved_w, saved_h; /* pre-maximize size */
Time last_click_time; /* for double-click detection */
char title[256];
struct Client *next;
} Client;
typedef struct MenuItem {
const char *label;
const char *cmd;
} MenuItem;
typedef struct WM {
Display *dpy;
int screen;
Window root;
GC gc;
Colormap cmap;
Visual *visual;
int depth;
XftFont *font_title;
XftFont *font_menu;
Cursor cur_normal;
Cursor cur_move;
Cursor cur_resize;
Client *clients;
Client *focused;
Atom wm_delete_window;
Atom wm_protocols;
Atom wm_state;
Atom net_wm_name;
Atom net_wm_state;
Atom net_wm_state_hidden;
Atom net_wm_state_maximized_vert;
Atom net_wm_state_maximized_horz;
DragMode drag_mode;
int drag_start_x, drag_start_y;
int drag_win_x, drag_win_y;
unsigned drag_win_w, drag_win_h;
Window drag_frame;
Window menu_win;
int menu_visible;
int menu_x, menu_y;
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;
/* core */
void wm_init(WM *wm);
void wm_run(WM *wm);
void wm_cleanup(WM *wm);
/* client */
Client *client_add(WM *wm, Window win);
void client_remove(WM *wm, Window win);
Client *client_find_by_frame(WM *wm, Window frame);
Client *client_find_by_win(WM *wm, Window win);
void client_focus(WM *wm, Client *c);
void client_raise(WM *wm, Client *c);
void client_minimize(WM *wm, Client *c);
void client_restore(WM *wm, Client *c);
void client_maximize(WM *wm, Client *c);
void client_unmaximize(WM *wm, Client *c);
void client_toggle_maximize(WM *wm, Client *c);
void client_snap_left(WM *wm, Client *c);
void client_snap_right(WM *wm, Client *c);
void client_set_wm_state(WM *wm, Client *c, long state);
/* drawing */
void frame_draw(WM *wm, Client *c);
void frame_draw_buttons(WM *wm, Client *c);
unsigned long color_alloc(WM *wm, unsigned long rgb);
void xft_color(WM *wm, unsigned long rgb, XftColor *out);
/* hit testing */
int frame_hit_resize(Client *c, int x, int y);
int frame_hit_close(Client *c, int x, int y);
int frame_hit_minimize(Client *c, int x, int y);
int frame_hit_maximize(Client *c, int x, int y);
/* menu */
void menu_show(WM *wm, int x, int y);
void menu_hide(WM *wm);
void menu_draw(WM *wm);
void menu_click(WM *wm, int px, 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 */
void on_map_request(WM *wm, XMapRequestEvent *e);
void on_unmap_notify(WM *wm, XUnmapEvent *e);
void on_destroy_notify(WM *wm, XDestroyWindowEvent *e);
void on_expose(WM *wm, XExposeEvent *e);
void on_button_press(WM *wm, XButtonEvent *e);
void on_button_release(WM *wm, XButtonEvent *e);
void on_motion_notify(WM *wm, XMotionEvent *e);
void on_configure_request(WM *wm, XConfigureRequestEvent *e);
void on_key_press(WM *wm, XKeyEvent *e);
void on_enter_notify(WM *wm, XCrossingEvent *e);
void on_client_message(WM *wm, XClientMessageEvent *e);
void on_property_notify(WM *wm, XPropertyEvent *e);
void on_key_release(WM *wm, XKeyEvent *e);
#endif