From e0e6b6e04d8fcb6014028c70a52ff08ce8206d2f Mon Sep 17 00:00:00 2001 From: kitty piapiac Date: Wed, 29 Jul 2020 05:24:02 -0700 Subject: =?UTF-8?q?(=EF=BD=A5=CF=89=EF=BD=A5)b=20key=20handlers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO | 4 +- src/config.nim | 16 +++---- src/kauw.nim | 10 ++++- src/logger.nim | 9 +++- src/types.nim | 8 ++-- src/windowmanager.nim | 121 ++++++++++++++++++++++++++++++++++++++------------ 6 files changed, 124 insertions(+), 44 deletions(-) diff --git a/TODO b/TODO index 545d667..2ce1ecf 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,6 @@ Todo: [ ] Better config files [ ] Literally everything!! - [ ] Support for multiple modifiers on keybinding \ No newline at end of file + [ ] Support for multiple modifiers on keybinding + [ ] Optional title bars? + [ ] Documentation \ No newline at end of file diff --git a/src/config.nim b/src/config.nim index bd7d6ae..64ea31e 100644 --- a/src/config.nim +++ b/src/config.nim @@ -1,9 +1,6 @@ -import - types, - x11/[x, keysym] +import types, x11/x # settings, or something along those lines -# currently unused const # default mod key, run xmodmap to see what the mod keys are on your current keyboard layout # Mod1 is alt and Mod4 is super @@ -14,18 +11,21 @@ const focused: 0xFBFDFF, unfocused: 0x9BCDFF, background: 0x232323) + + # in pixels + frameWidth* = 2 # store keybindings here keybindings*: seq[Key] = @[ closeWindow.initKey( - key = XK_c, - mods = modifier), + key = "c", + mods = modifier or ShiftMask), # TODO: seq here instaed of x or y # currently XMask or YMask or ZMask nextWindow.initKey( - key = XK_Tab, + key = "Tab", mods = modifier), spawnCustom.initKey( - key = XK_Return, + key = "Return", mods = modifier, command = "st")] \ No newline at end of file diff --git a/src/kauw.nim b/src/kauw.nim index c1b0d4c..feda7fb 100644 --- a/src/kauw.nim +++ b/src/kauw.nim @@ -1,14 +1,22 @@ import + os, /windowmanager, logging, /logger +const version = "0.0.1" + proc main() = + if paramCount() > 0: + if paramStr(1) == "-v": + echo "kauw version " & version + quit QuitSuccess + let wm = createWindowManager() if wm == nil: consoleLog.log(lvlError, "failed to initialize window manager") quit QuitFailure - + wm.run() quit QuitSuccess diff --git a/src/logger.nim b/src/logger.nim index 8e0c36f..bf878b0 100644 --- a/src/logger.nim +++ b/src/logger.nim @@ -1,3 +1,10 @@ import logging -var consoleLog* = newConsoleLogger(fmtStr="kauw/ $time/ $levelname: ") \ No newline at end of file +const debug = false # set this to true to get debug messags + +var consoleLog* = newConsoleLogger(fmtStr="kauw/ $time/ $levelname: ") + +proc log* (lvl: Level, str: string) = + if lvl == lvlDebug: + if not debug: return + consoleLog.log(lvl, str) \ No newline at end of file diff --git a/src/types.nim b/src/types.nim index 3eb6fc0..bfe79aa 100644 --- a/src/types.nim +++ b/src/types.nim @@ -1,5 +1,3 @@ -import x11/[x] - type KeyFunc* = enum closeWindow, @@ -7,12 +5,12 @@ type spawnCustom Key* = object - mods*: int - key*: KeySym + mods*: cuint + key*: string keyfunc*: KeyFunc command*: string -proc initKey* (keyfunc: KeyFunc, mods: int, key: KeySym, command = ""): Key = +proc initKey* (keyfunc: KeyFunc, mods: cuint, key: string, command = ""): Key = return Key( mods: mods, key: key, diff --git a/src/windowmanager.nim b/src/windowmanager.nim index d371442..18fede3 100644 --- a/src/windowmanager.nim +++ b/src/windowmanager.nim @@ -1,15 +1,27 @@ import x11/[x, xlib], config, /types, - logging, /logger + logging, /logger, + tables type WindowManager* = ref object display: PDisplay + screen: PScreen + colormap: Colormap root: Window + keyhandlers: Table[cuint, proc (wm: WindowManager)] + # Initialiazation stuff -proc initShortcutKeys (wm: WindowManager) +proc initKeybindings (wm: WindowManager) +proc initButtons (wm: WindowManager) + +# KeyFunc Handlers +proc procFromFunc (wm: WindowManager, keyfunc: KeyFunc): proc (wm: WindowManager) +proc funcCloseWindow (wm: WindowManager) +proc funcNextWindow (wm: WindowManager) +proc funcSpawnCustom (wm: WindowManager) # Error Handlers proc onWMDetected (display: PDisplay, e: PXErrorEvent): cint{.cdecl.} @@ -30,9 +42,30 @@ proc onMotionNotify (wm: WindowManager, e: PXMotionEvent) proc onKeyPress (wm: WindowManager, e: PXKeyEvent) proc onKeyRelease (wm: WindowManager, e: PXKeyEvent) +# Create a window manager +proc createWindowManager*: WindowManager = + var display = XOpenDisplay nil + + if display == nil: + lvlError.log("failed to open X display " & $XDisplayName nil) + quit QuitFailure + + var + screen = display.DefaultScreenOfDisplay() + keyhandlers = initTable[cuint, proc (wm: WindowManager)](1) + + return WindowManager( + display: display, + screen: screen, + colormap: screen.DefaultColormapOfScreen(), + root: display.DefaultRootWindow(), + + keyhandlers: keyhandlers) + # Run window manager proc run* (wm: WindowManager) = - initShortcutKeys wm + initKeybindings wm + initButtons wm discard XSetErrorHandler onWMDetected # Temporary error handler if there is another window manager running @@ -42,8 +75,8 @@ proc run* (wm: WindowManager) = discard XSetErrorHandler onXError while true: - var e: PXEvent - discard wm.display.XNextEvent e + var e: XEvent + discard wm.display.XNextEvent(addr e) case e.theType: of CreateNotify: wm.onCreateNotify addr e.xcreatewindow @@ -59,34 +92,62 @@ proc run* (wm: WindowManager) = of MotionNotify: wm.onMotionNotify addr e.xmotion of KeyPress: wm.onKeyPress addr e.xkey of KeyRelease: wm.onKeyRelease addr e.xkey - else: consoleLog.log(lvlWarn, "ignored event") - -proc createWindowManager*: WindowManager = - var display = XOpenDisplay nil - - if display == nil: - consoleLog.log(lvlError, "failed to open X display " & $XDisplayName nil) - quit QuitFailure - - return WindowManager( - display: display, - root: display.DefaultRootWindow()) + else: lvlWarn.log("ignored event") # Initialization Stuff -proc initShortcutKeys (wm: WindowManager) = +proc initKeybindings (wm: WindowManager) = + discard wm.display.XUngrabKey(AnyKey, AnyModifier, wm.root) + for key in config.keybindings: + var + keysym = XStringToKeysym key.key + keycode = wm.display.XKeysymToKeycode keysym + keyfunc = wm.procFromFunc key.keyfunc + + wm.keyhandlers[cuint keycode] = keyfunc + echo typeof wm.keyhandlers[cuint keycode] + discard wm.display.XGrabKey( - cint wm.display.XKeysymToKeycode(key.key), - cuint key.mods, - wm.root, + cint keycode, + key.mods, + wm.root, XBool true, GrabModeAsync, GrabModeAsync) +proc initButtons (wm: WindowManager) = + discard wm.display.XUngrabButton(AnyButton, AnyModifier, wm.root) + + for button in [1, 3]: + discard wm.display.XGrabButton( + cuint button, + cuint Mod1Mask, + wm.root, + XBool true, + ButtonPressMask or ButtonReleaseMask or PointerMotionMask, + GrabModeAsync, + GrabModeAsync, + None, + None) + +# KeyFunc Handlers +proc procFromFunc (wm: WindowManager, keyfunc: KeyFunc): proc (wm: WindowManager) = + let procFuncTable = { + closeWindow: funcCloseWindow, + nextWindow: funcNextWindow, + spawnCustom: funcSpawnCustom}.toTable + + return procFuncTable[keyfunc] + +# TODO: These +proc funcCloseWindow (wm: WindowManager) = return +proc funcNextWindow (wm: WindowManager) = return +proc funcSpawnCustom (wm: WindowManager) = return + # Error Handlers proc onWMDetected (display: PDisplay, e: PXErrorEvent): cint{.cdecl.} = if e.theType == BadAccess: - consoleLog.log(lvlError, "other window manager detected") + lvlError.log("another window manager is already running") quit QuitFailure return 0 @@ -99,11 +160,11 @@ proc onXError (display: PDisplay, e: PXErrorEvent): cint{.cdecl.} = cstring errorText, cint len errorText) - consoleLog.log( - lvlError, "received X error: \n" & - " request: " & $e.request_code & "\n" & - " error code: " & $e.error_code & " - " & errorText & "\n" & - " resource id: " & $e.resourceid) + lvlError.log( + "received X error: \n" & + " request: " & $e.request_code & "\n" & + " error code: " & $e.error_code & " - " & errorText & "\n" & + " resource id: " & $e.resourceid) return 0 @@ -132,5 +193,9 @@ proc onConfigureRequest (wm: WindowManager, e: PXConfigureRequestEvent) = proc onButtonPress (wm: WindowManager, e: PXButtonEvent) = return proc onButtonRelease (wm: WindowManager, e: PXButtonEvent) = return proc onMotionNotify (wm: WindowManager, e: PXMotionEvent) = return -proc onKeyPress (wm: WindowManager, e: PXKeyEvent) = return +proc onKeyPress (wm: WindowManager, e: PXKeyEvent) = + lvlDebug.log("key event " & $e.keycode) + var handler = wm.keyhandlers[e.keycode] + handler wm + proc onKeyRelease (wm: WindowManager, e: PXKeyEvent) = return \ No newline at end of file -- cgit v1.2.3