diff options
| author | crecher <crecher@crecher.net> | 2026-02-25 23:50:56 +0100 |
|---|---|---|
| committer | crecher <crecher@crecher.net> | 2026-02-26 02:28:50 +0100 |
| commit | d1e558b408bc31f17a84b3bede0c18e9df51aeda (patch) | |
| tree | 645438fea656969dd1cc5d1f97973752e2b3a5f7 | |
| parent | 000a3abf8173eacb86e6053fdc8cc03e1872ddc6 (diff) | |
| download | wm-d1e558b408bc31f17a84b3bede0c18e9df51aeda.tar.gz wm-d1e558b408bc31f17a84b3bede0c18e9df51aeda.zip | |
initial commit
| -rw-r--r-- | a.out | 0 | ||||
| -rw-r--r-- | go.mod | 5 | ||||
| -rw-r--r-- | go.sum | 2 | ||||
| -rw-r--r-- | keysym/keysim.go | 234 | ||||
| -rw-r--r-- | main.go | 255 | ||||
| -rwxr-xr-x | wm | bin | 0 -> 4218392 bytes | |||
| -rwxr-xr-x | xneststart | 2 |
7 files changed, 498 insertions, 0 deletions
@@ -0,0 +1,5 @@ +module github.com/crecheer/wm + +go 1.25.0 + +require github.com/BurntSushi/xgb v0.0.0-20210121224620-deaf085860bc // indirect @@ -0,0 +1,2 @@ +github.com/BurntSushi/xgb v0.0.0-20210121224620-deaf085860bc h1:7D+Bh06CRPCJO3gr2F7h1sriovOZ8BMhca2Rg85c2nk= +github.com/BurntSushi/xgb v0.0.0-20210121224620-deaf085860bc/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= diff --git a/keysym/keysim.go b/keysym/keysim.go new file mode 100644 index 0000000..831ee4e --- /dev/null +++ b/keysym/keysim.go @@ -0,0 +1,234 @@ +package keysym + +// copied from https://github.com/driusan/dewm/blob/master/keysym/keysym.go + +// Known KeySyms from /usr/include/X11/keysymdef.h +const ( + // TTY function keys, cleverly chosen to map to ASCII, for convenience of + // programming, but could have been arbitrary (at the cost of lookup + // tables in client code). + XK_BackSpace = 0xff08 // Back space, back char + XK_Tab = 0xff09 + XK_Linefeed = 0xff0a // Linefeed, LF + XK_Clear = 0xff0b + XK_Return = 0xff0d // Return, enter + XK_Pause = 0xff13 // Pause, hold + XK_Scroll_Lock = 0xff14 + XK_Sys_Req = 0xff15 + XK_Escape = 0xff1b + XK_Delete = 0xffff // Delete, rubout + // Latin 1 + // (ISO/IEC 8859-1 = Unicode U+0020..U+00FF) + // Byte 3 = 0 + XK_space = 0x0020 // U+0020 SPACE + XK_exclam = 0x0021 // U+0021 EXCLAMATION MARK + XK_quotedbl = 0x0022 // U+0022 QUOTATION MARK + XK_numbersign = 0x0023 // U+0023 NUMBER SIGN + XK_dollar = 0x0024 // U+0024 DOLLAR SIGN + XK_percent = 0x0025 // U+0025 PERCENT SIGN + XK_ampersand = 0x0026 // U+0026 AMPERSAND + XK_apostrophe = 0x0027 // U+0027 APOSTROPHE + XK_quoteright = 0x0027 // deprecated + XK_parenleft = 0x0028 // U+0028 LEFT PARENTHESIS + XK_parenright = 0x0029 // U+0029 RIGHT PARENTHESIS + XK_asterisk = 0x002a // U+002A ASTERISK + XK_plus = 0x002b // U+002B PLUS SIGN + XK_comma = 0x002c // U+002C COMMA + XK_minus = 0x002d // U+002D HYPHEN-MINUS + XK_period = 0x002e // U+002E FULL STOP + XK_slash = 0x002f // U+002F SOLIDUS + XK_0 = 0x0030 // U+0030 DIGIT ZERO + XK_1 = 0x0031 // U+0031 DIGIT ONE + XK_2 = 0x0032 // U+0032 DIGIT TWO + XK_3 = 0x0033 // U+0033 DIGIT THREE + XK_4 = 0x0034 // U+0034 DIGIT FOUR + XK_5 = 0x0035 // U+0035 DIGIT FIVE + XK_6 = 0x0036 // U+0036 DIGIT SIX + XK_7 = 0x0037 // U+0037 DIGIT SEVEN + XK_8 = 0x0038 // U+0038 DIGIT EIGHT + XK_9 = 0x0039 // U+0039 DIGIT NINE + XK_colon = 0x003a // U+003A COLON + XK_semicolon = 0x003b // U+003B SEMICOLON + XK_less = 0x003c // U+003C LESS-THAN SIGN + XK_equal = 0x003d // U+003D EQUALS SIGN + XK_greater = 0x003e // U+003E GREATER-THAN SIGN + XK_question = 0x003f // U+003F QUESTION MARK + XK_at = 0x0040 // U+0040 COMMERCIAL AT + XK_A = 0x0041 // U+0041 LATIN CAPITAL LETTER A + XK_B = 0x0042 // U+0042 LATIN CAPITAL LETTER B + XK_C = 0x0043 // U+0043 LATIN CAPITAL LETTER C + XK_D = 0x0044 // U+0044 LATIN CAPITAL LETTER D + XK_E = 0x0045 // U+0045 LATIN CAPITAL LETTER E + XK_F = 0x0046 // U+0046 LATIN CAPITAL LETTER F + XK_G = 0x0047 // U+0047 LATIN CAPITAL LETTER G + XK_H = 0x0048 // U+0048 LATIN CAPITAL LETTER H + XK_I = 0x0049 // U+0049 LATIN CAPITAL LETTER I + XK_J = 0x004a // U+004A LATIN CAPITAL LETTER J + XK_K = 0x004b // U+004B LATIN CAPITAL LETTER K + XK_L = 0x004c // U+004C LATIN CAPITAL LETTER L + XK_M = 0x004d // U+004D LATIN CAPITAL LETTER M + XK_N = 0x004e // U+004E LATIN CAPITAL LETTER N + XK_O = 0x004f // U+004F LATIN CAPITAL LETTER O + XK_P = 0x0050 // U+0050 LATIN CAPITAL LETTER P + XK_Q = 0x0051 // U+0051 LATIN CAPITAL LETTER Q + XK_R = 0x0052 // U+0052 LATIN CAPITAL LETTER R + XK_S = 0x0053 // U+0053 LATIN CAPITAL LETTER S + XK_T = 0x0054 // U+0054 LATIN CAPITAL LETTER T + XK_U = 0x0055 // U+0055 LATIN CAPITAL LETTER U + XK_V = 0x0056 // U+0056 LATIN CAPITAL LETTER V + XK_W = 0x0057 // U+0057 LATIN CAPITAL LETTER W + XK_X = 0x0058 // U+0058 LATIN CAPITAL LETTER X + XK_Y = 0x0059 // U+0059 LATIN CAPITAL LETTER Y + XK_Z = 0x005a // U+005A LATIN CAPITAL LETTER Z + XK_bracketleft = 0x005b // U+005B LEFT SQUARE BRACKET + XK_backslash = 0x005c // U+005C REVERSE SOLIDUS + XK_bracketright = 0x005d // U+005D RIGHT SQUARE BRACKET + XK_asciicircum = 0x005e // U+005E CIRCUMFLEX ACCENT + XK_underscore = 0x005f // U+005F LOW LINE + XK_grave = 0x0060 // U+0060 GRAVE ACCENT + XK_quoteleft = 0x0060 // deprecated + XK_a = 0x0061 // U+0061 LATIN SMALL LETTER A + XK_b = 0x0062 // U+0062 LATIN SMALL LETTER B + XK_c = 0x0063 // U+0063 LATIN SMALL LETTER C + XK_d = 0x0064 // U+0064 LATIN SMALL LETTER D + XK_e = 0x0065 // U+0065 LATIN SMALL LETTER E + XK_f = 0x0066 // U+0066 LATIN SMALL LETTER F + XK_g = 0x0067 // U+0067 LATIN SMALL LETTER G + XK_h = 0x0068 // U+0068 LATIN SMALL LETTER H + XK_i = 0x0069 // U+0069 LATIN SMALL LETTER I + XK_j = 0x006a // U+006A LATIN SMALL LETTER J + XK_k = 0x006b // U+006B LATIN SMALL LETTER K + XK_l = 0x006c // U+006C LATIN SMALL LETTER L + XK_m = 0x006d // U+006D LATIN SMALL LETTER M + XK_n = 0x006e // U+006E LATIN SMALL LETTER N + XK_o = 0x006f // U+006F LATIN SMALL LETTER O + XK_p = 0x0070 // U+0070 LATIN SMALL LETTER P + XK_q = 0x0071 // U+0071 LATIN SMALL LETTER Q + XK_r = 0x0072 // U+0072 LATIN SMALL LETTER R + XK_s = 0x0073 // U+0073 LATIN SMALL LETTER S + XK_t = 0x0074 // U+0074 LATIN SMALL LETTER T + XK_u = 0x0075 // U+0075 LATIN SMALL LETTER U + XK_v = 0x0076 // U+0076 LATIN SMALL LETTER V + XK_w = 0x0077 // U+0077 LATIN SMALL LETTER W + XK_x = 0x0078 // U+0078 LATIN SMALL LETTER X + XK_y = 0x0079 // U+0079 LATIN SMALL LETTER Y + XK_z = 0x007a // U+007A LATIN SMALL LETTER Z + XK_braceleft = 0x007b // U+007B LEFT CURLY BRACKET + XK_bar = 0x007c // U+007C VERTICAL LINE + XK_braceright = 0x007d // U+007D RIGHT CURLY BRACKET + XK_asciitilde = 0x007e // U+007E TILDE + + XK_nobreakspace = 0x00a0 // U+00A0 NO-BREAK SPACE + XK_exclamdown = 0x00a1 // U+00A1 INVERTED EXCLAMATION MARK + XK_cent = 0x00a2 // U+00A2 CENT SIGN + XK_sterling = 0x00a3 // U+00A3 POUND SIGN + XK_currency = 0x00a4 // U+00A4 CURRENCY SIGN + XK_yen = 0x00a5 // U+00A5 YEN SIGN + XK_brokenbar = 0x00a6 // U+00A6 BROKEN BAR + XK_section = 0x00a7 // U+00A7 SECTION SIGN + XK_diaeresis = 0x00a8 // U+00A8 DIAERESIS + XK_copyright = 0x00a9 // U+00A9 COPYRIGHT SIGN + XK_ordfeminine = 0x00aa // U+00AA FEMININE ORDINAL INDICATOR + XK_guillemotleft = 0x00ab // U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + XK_notsign = 0x00ac // U+00AC NOT SIGN + XK_hyphen = 0x00ad // U+00AD SOFT HYPHEN + XK_registered = 0x00ae // U+00AE REGISTERED SIGN + XK_macron = 0x00af // U+00AF MACRON + XK_degree = 0x00b0 // U+00B0 DEGREE SIGN + XK_plusminus = 0x00b1 // U+00B1 PLUS-MINUS SIGN + XK_twosuperior = 0x00b2 // U+00B2 SUPERSCRIPT TWO + XK_threesuperior = 0x00b3 // U+00B3 SUPERSCRIPT THREE + XK_acute = 0x00b4 // U+00B4 ACUTE ACCENT + XK_mu = 0x00b5 // U+00B5 MICRO SIGN + XK_paragraph = 0x00b6 // U+00B6 PILCROW SIGN + XK_periodcentered = 0x00b7 // U+00B7 MIDDLE DOT + XK_cedilla = 0x00b8 // U+00B8 CEDILLA + XK_onesuperior = 0x00b9 // U+00B9 SUPERSCRIPT ONE + XK_masculine = 0x00ba // U+00BA MASCULINE ORDINAL INDICATOR + XK_guillemotright = 0x00bb // U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + XK_onequarter = 0x00bc // U+00BC VULGAR FRACTION ONE QUARTER + XK_onehalf = 0x00bd // U+00BD VULGAR FRACTION ONE HALF + XK_threequarters = 0x00be // U+00BE VULGAR FRACTION THREE QUARTERS + XK_questiondown = 0x00bf // U+00BF INVERTED QUESTION MARK + XK_Agrave = 0x00c0 // U+00C0 LATIN CAPITAL LETTER A WITH GRAVE + XK_Aacute = 0x00c1 // U+00C1 LATIN CAPITAL LETTER A WITH ACUTE + XK_Acircumflex = 0x00c2 // U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX + XK_Atilde = 0x00c3 // U+00C3 LATIN CAPITAL LETTER A WITH TILDE + XK_Adiaeresis = 0x00c4 // U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS + XK_Aring = 0x00c5 // U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE + XK_AE = 0x00c6 // U+00C6 LATIN CAPITAL LETTER AE + XK_Ccedilla = 0x00c7 // U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA + XK_Egrave = 0x00c8 // U+00C8 LATIN CAPITAL LETTER E WITH GRAVE + XK_Eacute = 0x00c9 // U+00C9 LATIN CAPITAL LETTER E WITH ACUTE + XK_Ecircumflex = 0x00ca // U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX + XK_Ediaeresis = 0x00cb // U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS + XK_Igrave = 0x00cc // U+00CC LATIN CAPITAL LETTER I WITH GRAVE + XK_Iacute = 0x00cd // U+00CD LATIN CAPITAL LETTER I WITH ACUTE + XK_Icircumflex = 0x00ce // U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX + XK_Idiaeresis = 0x00cf // U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS + XK_ETH = 0x00d0 // U+00D0 LATIN CAPITAL LETTER ETH + XK_Eth = 0x00d0 // deprecated + XK_Ntilde = 0x00d1 // U+00D1 LATIN CAPITAL LETTER N WITH TILDE + XK_Ograve = 0x00d2 // U+00D2 LATIN CAPITAL LETTER O WITH GRAVE + XK_Oacute = 0x00d3 // U+00D3 LATIN CAPITAL LETTER O WITH ACUTE + XK_Ocircumflex = 0x00d4 // U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX + XK_Otilde = 0x00d5 // U+00D5 LATIN CAPITAL LETTER O WITH TILDE + XK_Odiaeresis = 0x00d6 // U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS + XK_multiply = 0x00d7 // U+00D7 MULTIPLICATION SIGN + XK_Oslash = 0x00d8 // U+00D8 LATIN CAPITAL LETTER O WITH STROKE + XK_Ooblique = 0x00d8 // U+00D8 LATIN CAPITAL LETTER O WITH STROKE + XK_Ugrave = 0x00d9 // U+00D9 LATIN CAPITAL LETTER U WITH GRAVE + XK_Uacute = 0x00da // U+00DA LATIN CAPITAL LETTER U WITH ACUTE + XK_Ucircumflex = 0x00db // U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX + XK_Udiaeresis = 0x00dc // U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS + XK_Yacute = 0x00dd // U+00DD LATIN CAPITAL LETTER Y WITH ACUTE + XK_THORN = 0x00de // U+00DE LATIN CAPITAL LETTER THORN + XK_Thorn = 0x00de // deprecated + XK_ssharp = 0x00df // U+00DF LATIN SMALL LETTER SHARP S + XK_agrave = 0x00e0 // U+00E0 LATIN SMALL LETTER A WITH GRAVE + XK_aacute = 0x00e1 // U+00E1 LATIN SMALL LETTER A WITH ACUTE + XK_acircumflex = 0x00e2 // U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX + XK_atilde = 0x00e3 // U+00E3 LATIN SMALL LETTER A WITH TILDE + XK_adiaeresis = 0x00e4 // U+00E4 LATIN SMALL LETTER A WITH DIAERESIS + XK_aring = 0x00e5 // U+00E5 LATIN SMALL LETTER A WITH RING ABOVE + XK_ae = 0x00e6 // U+00E6 LATIN SMALL LETTER AE + XK_ccedilla = 0x00e7 // U+00E7 LATIN SMALL LETTER C WITH CEDILLA + XK_egrave = 0x00e8 // U+00E8 LATIN SMALL LETTER E WITH GRAVE + XK_eacute = 0x00e9 // U+00E9 LATIN SMALL LETTER E WITH ACUTE + XK_ecircumflex = 0x00ea // U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX + XK_ediaeresis = 0x00eb // U+00EB LATIN SMALL LETTER E WITH DIAERESIS + XK_igrave = 0x00ec // U+00EC LATIN SMALL LETTER I WITH GRAVE + XK_iacute = 0x00ed // U+00ED LATIN SMALL LETTER I WITH ACUTE + XK_icircumflex = 0x00ee // U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX + XK_idiaeresis = 0x00ef // U+00EF LATIN SMALL LETTER I WITH DIAERESIS + XK_eth = 0x00f0 // U+00F0 LATIN SMALL LETTER ETH + XK_ntilde = 0x00f1 // U+00F1 LATIN SMALL LETTER N WITH TILDE + XK_ograve = 0x00f2 // U+00F2 LATIN SMALL LETTER O WITH GRAVE + XK_oacute = 0x00f3 // U+00F3 LATIN SMALL LETTER O WITH ACUTE + XK_ocircumflex = 0x00f4 // U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX + XK_otilde = 0x00f5 // U+00F5 LATIN SMALL LETTER O WITH TILDE + XK_odiaeresis = 0x00f6 // U+00F6 LATIN SMALL LETTER O WITH DIAERESIS + XK_division = 0x00f7 // U+00F7 DIVISION SIGN + XK_oslash = 0x00f8 // U+00F8 LATIN SMALL LETTER O WITH STROKE + XK_ooblique = 0x00f8 // U+00F8 LATIN SMALL LETTER O WITH STROKE + XK_ugrave = 0x00f9 // U+00F9 LATIN SMALL LETTER U WITH GRAVE + XK_uacute = 0x00fa // U+00FA LATIN SMALL LETTER U WITH ACUTE + XK_ucircumflex = 0x00fb // U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX + XK_udiaeresis = 0x00fc // U+00FC LATIN SMALL LETTER U WITH DIAERESIS + XK_yacute = 0x00fd // U+00FD LATIN SMALL LETTER Y WITH ACUTE + XK_thorn = 0x00fe // U+00FE LATIN SMALL LETTER THORN + XK_ydiaeresis = 0x00ff // U+00FF LATIN SMALL LETTER Y WITH DIAERESIS + + // Cursor control & motion + XK_Home = 0xff50 + XK_Left = 0xff51 // Move left, left arrow + XK_Up = 0xff52 // Move up, up arrow + XK_Right = 0xff53 // Move right, right arrow + XK_Down = 0xff54 // Move down, down arrow + XK_Prior = 0xff55 // Prior, previous + XK_Page_Up = 0xff55 + XK_Next = 0xff56 // Next + XK_Page_Down = 0xff56 + XK_End = 0xff57 // EOL + XK_Begin = 0xff58 // BOL +)
\ No newline at end of file @@ -0,0 +1,255 @@ +package main + +import ( + "log" + "os" + "os/exec" + + "github.com/BurntSushi/xgb" + "github.com/BurntSushi/xgb/xproto" + + "github.com/crecheer/wm/keysym" +) + +// structs + +type Key struct { + Mod uint16 + Sym uint32 + Fn func(*xgb.Conn) +} + +type Client struct { + Win xproto.Window + X int16 + Y int16 + Width uint16 + Height uint16 + Floating bool +} + +var keys []Key +var clients = make(map[xproto.Window]*Client) + +func main() { + conn, err := xgb.NewConn() + if err != nil { + log.Fatal(err) + } + + setup(conn) + + for { + log.Println("test") + ev, err := conn.WaitForEvent() + if err != nil { + log.Fatal(err) + } + + switch e := ev.(type) { + case xproto.KeyPressEvent: + handleKeyPress(conn, e) + + case xproto.MapRequestEvent: + manageWindow(conn, e.Window) + + case xproto.DestroyNotifyEvent: + unmanageWindow(conn, e.Window) + + case xproto.UnmapNotifyEvent: + unmanageWindow(conn, e.Window) + + default: + log.Println("event: ", e) + } + + } +} + +func setup(conn *xgb.Conn) { + root := xproto.Setup(conn).DefaultScreen(conn).Root + + err := xproto.ChangeWindowAttributesChecked( + conn, + root, + xproto.CwEventMask, + []uint32{ + xproto.EventMaskSubstructureRedirect | + xproto.EventMaskSubstructureNotify, + }, + ).Check() + + if err != nil { + log.Fatal(err) + } + + setupKeys(conn) +} + +func spawn(cmd string, args ...string) { + c := exec.Command(cmd, args...) + c.Stdout = nil + c.Stderr = nil + c.Stdin = nil + if err := c.Start(); err != nil { + log.Println("failed to spawn", cmd, ":", err) + } +} + +func setupKeys(conn *xgb.Conn) { + mod := uint16(xproto.ModMask1) // Alt + + keys = []Key{ + { + Mod: mod, + Sym: keysym.XK_Return, + Fn: func(c *xgb.Conn) { + spawn("st") + }, + }, + { + Mod: mod, + Sym: keysym.XK_Q, + Fn: func(c *xgb.Conn) { + os.Exit(0) + }, + }, + } + + grabKeys(conn) +} + +func grabKeys(conn *xgb.Conn) { + root := xproto.Setup(conn).DefaultScreen(conn).Root + + for _, k := range keys { + keycode := keysymToKeycode(conn, k.Sym) + if keycode == 0 { + continue + } + + xproto.GrabKey(conn, + true, + root, + k.Mod, + keycode, + xproto.GrabModeAsync, + xproto.GrabModeAsync, + ) + } +} + +func keysymToKeycode(conn *xgb.Conn, sym uint32) xproto.Keycode { + setup := xproto.Setup(conn) + min := setup.MinKeycode + max := setup.MaxKeycode + + reply, err := xproto.GetKeyboardMapping(conn, min, byte(max-min+1)).Reply() + if err != nil { + return 0 + } + + keysymsPerKeycode := int(reply.KeysymsPerKeycode) + + for kc := min; kc <= max; kc++ { + for i := 0; i < keysymsPerKeycode; i++ { + idx := int(kc-min)*keysymsPerKeycode + i + if uint32(reply.Keysyms[idx]) == sym { + return kc + } + } + } + + return 0 +} + +func handleKeyPress(conn *xgb.Conn, e xproto.KeyPressEvent) { + log.Println("key pressed") + reply, err := xproto.GetKeyboardMapping(conn, e.Detail, 1).Reply() + if err != nil || len(reply.Keysyms) == 0 { + return + } + + + + sym := reply.Keysyms[0] + + for _, k := range keys { + if uint32(sym) == k.Sym && (e.State&k.Mod) == k.Mod { + k.Fn(conn) + } + } +} + +func manageWindow(conn *xgb.Conn, win xproto.Window) { + geom, err := xproto.GetGeometry(conn, xproto.Drawable(win)).Reply() + if err != nil { + return + } + + client := &Client{ + Win: win, + X: geom.X, + Y: geom.Y, + Width: geom.Width, + Height: geom.Height, + Floating: false, + } + + clients[win] = client + log.Println("managing window:", win) + + // listen for events on this window + xproto.ChangeWindowAttributes(conn, win, + xproto.CwEventMask, + []uint32{ + xproto.EventMaskEnterWindow | + xproto.EventMaskFocusChange | + xproto.EventMaskPropertyChange, + }) + + // map (show) window + xproto.MapWindow(conn, win) + + // tile all windows + tile(conn) +} + +func unmanageWindow(conn *xgb.Conn, win xproto.Window) { + if _, ok := clients[win]; ok { + log.Println("unmanaging window:", win) + delete(clients, win) + tile(conn) + } +} + +func tile(conn *xgb.Conn) { + log.Println("tile") + screen := xproto.Setup(conn).DefaultScreen(conn) + screenWidth := int(screen.WidthInPixels) + screenHeight := int(screen.HeightInPixels) + + n := len(clients) + if n == 0 { + return + } + + i := 0 + for _, c := range clients { + height := screenHeight / n + + xproto.ConfigureWindow(conn, c.Win, + xproto.ConfigWindowX| + xproto.ConfigWindowY| + xproto.ConfigWindowWidth| + xproto.ConfigWindowHeight, + []uint32{ + 0, + uint32(i * height), + uint32(screenWidth), + uint32(height), + }) + + i++ + } +} Binary files differdiff --git a/xneststart b/xneststart new file mode 100755 index 0000000..6d91d3d --- /dev/null +++ b/xneststart @@ -0,0 +1,2 @@ +Xnest :2 -geometry 1280x800 & +DISPLAY=:2 ./wm
\ No newline at end of file |