summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--LICENSE21
-rw-r--r--README.md36
-rw-r--r--TODO3
-rw-r--r--img/kauw.pngbin0 -> 44765 bytes
-rw-r--r--kauw.nimble11
-rw-r--r--src/config.nim29
-rw-r--r--src/kauw.nim16
-rw-r--r--src/logger.nim3
-rw-r--r--src/types.nim18
-rw-r--r--src/windowmanager.nim106
11 files changed, 245 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..72497fc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.kra*
+kauw \ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..b493a23
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 fox-cat <fox@confuck.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE. \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2c2ba72
--- /dev/null
+++ b/README.md
@@ -0,0 +1,36 @@
+# (/・・)ノ kauw window manager
+kauw is an expiremental window manager built for x11 using nim
+
+currently it is but a skeleton of what's to come
+
+## goals (・・;)
+i have a few goals in mind while writing this project
+- written and configured fully in [nim]
+- easily configurable
+- easily hackable
+- be small and fairly minimalist
+- help myself learn nim and get around x11
+
+
+## development
+clone using
+```
+$ git clone https://github.com/fox-cat/kauw
+$ cd kauw
+```
+build using
+```
+$ nimble build
+```
+and you can test using [xephyr]
+```
+$ Xephyr -br -ac -noreset -screen 1920x1080 :1
+$ DISPLAY=:1 ./opozzumWM
+```
+
+## TODO
+see [TODO]
+
+[nim]: https://nim-lang.org/
+[xephyr]: https://wiki.archlinux.org/index.php/Xephyr
+[TODO]: TODO \ No newline at end of file
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..b393935
--- /dev/null
+++ b/TODO
@@ -0,0 +1,3 @@
+Todo:
+ [ ] Better config files
+ [ ] Literally everything!! \ No newline at end of file
diff --git a/img/kauw.png b/img/kauw.png
new file mode 100644
index 0000000..6a08cc6
--- /dev/null
+++ b/img/kauw.png
Binary files differ
diff --git a/kauw.nimble b/kauw.nimble
new file mode 100644
index 0000000..e7ef986
--- /dev/null
+++ b/kauw.nimble
@@ -0,0 +1,11 @@
+# Package
+version = "0.0.1"
+author = "fox-cat"
+description = "an expiremental window manager built for x11"
+license = "MIT"
+srcDir = "src"
+bin = @["kauw"]
+
+# Dependencies
+requires "nim >= 1.2.4"
+requires "x11" \ No newline at end of file
diff --git a/src/config.nim b/src/config.nim
new file mode 100644
index 0000000..23bd093
--- /dev/null
+++ b/src/config.nim
@@ -0,0 +1,29 @@
+import types
+
+# 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
+ modifier* = "mod1"
+
+ # if it isn't obvious, hex values go here
+ colours* = (
+ focused: 0xFBFDFF,
+ unfocused: 0x9BCDFF,
+ background: 0x232323)
+
+ # store keybindings here
+ keybindings*: seq[Key] = @[
+ closeWindow.initKey(
+ keys = @["c"],
+ mods = @[modifier, "shift"]),
+
+ nextWindow.initKey(
+ keys = @["tab"],
+ mods = @[modifier]),
+
+ spawnCustom.initKey(
+ keys = @["return"],
+ mods = @[modifier],
+ "st")] \ No newline at end of file
diff --git a/src/kauw.nim b/src/kauw.nim
new file mode 100644
index 0000000..c1b0d4c
--- /dev/null
+++ b/src/kauw.nim
@@ -0,0 +1,16 @@
+import
+ /windowmanager,
+ logging, /logger
+
+proc main() =
+ let wm = createWindowManager()
+
+ if wm == nil:
+ consoleLog.log(lvlError, "failed to initialize window manager")
+ quit QuitFailure
+
+ wm.run()
+
+ quit QuitSuccess
+
+main() \ No newline at end of file
diff --git a/src/logger.nim b/src/logger.nim
new file mode 100644
index 0000000..8e0c36f
--- /dev/null
+++ b/src/logger.nim
@@ -0,0 +1,3 @@
+import logging
+
+var consoleLog* = newConsoleLogger(fmtStr="kauw/ $time/ $levelname: ") \ No newline at end of file
diff --git a/src/types.nim b/src/types.nim
new file mode 100644
index 0000000..0352fc2
--- /dev/null
+++ b/src/types.nim
@@ -0,0 +1,18 @@
+type
+ KeyFunc* = enum
+ closeWindow,
+ nextWindow,
+ spawnCustom
+
+ Key* = object
+ mods*: seq[string]
+ keys*: seq[string]
+ keyfunc*: KeyFunc
+ command*: string
+
+proc initKey* (keyfunc: KeyFunc, mods: seq[string], keys: seq[string], command = ""): Key =
+ return Key(
+ mods: mods,
+ keys: keys,
+ command: command,
+ keyfunc: keyfunc) \ No newline at end of file
diff --git a/src/windowmanager.nim b/src/windowmanager.nim
new file mode 100644
index 0000000..e90ec94
--- /dev/null
+++ b/src/windowmanager.nim
@@ -0,0 +1,106 @@
+import
+ x11/[x, xlib],
+ logging, /logger
+
+type
+ WindowManager* = ref object
+ display: PDisplay
+ root: Window
+
+# Error Handlers
+proc onWMDetected (display: PDisplay, e: PXErrorEvent): cint{.cdecl.}
+proc onXError (display: PDisplay, e: PXErrorEvent): cint{.cdecl.}
+
+# Events
+proc onCreateNotify (wm: WindowManager, e: PXCreateWindowEvent): void
+proc onDestroyNotify (wm: WindowManager, e: PXDestroyWindowEvent): void
+proc onReparentNotify (wm: WindowManager, e: PXReparentEvent): void
+proc onMapNotify (wm: WindowManager, e: PXMapEvent): void
+proc onUnmapNotify (wm: WindowManager, e: PXUnmapEvent): void
+proc onConfigureNotify (wm: WindowManager, e: PXConfigureEvent): void
+proc onMapRequest (wm: WindowManager, e: PXMapRequestEvent): void
+proc onConfigureRequest (wm: WindowManager, e: PXConfigureRequestEvent): void
+proc onButtonPress (wm: WindowManager, e: PXButtonEvent): void
+proc onButtonRelease (wm: WindowManager, e: PXButtonEvent): void
+proc onMotionNotify (wm: WindowManager, e: PXMotionEvent): void
+proc onKeyPress (wm: WindowManager, e: PXKeyEvent): void
+proc onKeyRelease (wm: WindowManager, e: PXKeyEvent): void
+
+# Run window manager
+proc run* (wm: WindowManager) =
+ discard XSetErrorHandler onWMDetected # Temporary error handler if there is another window manager running
+
+ discard wm.display.XSelectInput(wm.root, SubstructureNotifyMask or SubstructureRedirectMask)
+ discard wm.display.XSync XBool false
+
+ discard XSetErrorHandler onXError
+
+ while true:
+ var e: PXEvent
+ discard wm.display.XNextEvent e
+
+ case e.theType:
+ of CreateNotify: wm.onCreateNotify addr e.xcreatewindow
+ of DestroyNotify: wm.onDestroyNotify addr e.xdestroywindow
+ of ReparentNotify: wm.onReparentNotify addr e.xreparent
+ of MapNotify: wm.onMapNotify addr e.xmap
+ of UnmapNotify: wm.onUnmapNotify addr e.xunmap
+ of ConfigureNotify: wm.onConfigureNotify addr e.xconfigure
+ of MapRequest: wm.onMapRequest addr e.xmaprequest
+ of ConfigureRequest: wm.onConfigureRequest addr e.xconfigurerequest
+ of ButtonPress: wm.onButtonPress addr e.xbutton
+ of ButtonRelease: wm.onButtonRelease addr e.xbutton
+ 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())
+
+# Error Handlers
+proc onWMDetected (display: PDisplay, e: PXErrorEvent): cint{.cdecl.} =
+ if e.theType == BadAccess:
+ consoleLog.log(lvlError, "other window manager detected")
+ quit QuitFailure
+
+ return 0
+
+proc onXError (display: PDisplay, e: PXErrorEvent): cint{.cdecl.} =
+ var errorText = newString 1024
+
+ discard display.XGetErrorText(
+ cint e.error_code,
+ 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)
+
+ return 0
+
+# Events
+proc onCreateNotify (wm: WindowManager, e: PXCreateWindowEvent) = return
+proc onDestroyNotify (wm: WindowManager, e: PXDestroyWindowEvent) = return
+proc onReparentNotify (wm: WindowManager, e: PXReparentEvent) = return
+proc onMapNotify (wm: WindowManager, e: PXMapEvent) = return
+proc onUnmapNotify (wm: WindowManager, e: PXUnmapEvent) = return
+proc onConfigureNotify (wm: WindowManager, e: PXConfigureEvent) = return
+proc onMapRequest (wm: WindowManager, e: PXMapRequestEvent) = return
+proc onConfigureRequest (wm: WindowManager, e: PXConfigureRequestEvent) = return
+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 onKeyRelease (wm: WindowManager, e: PXKeyEvent) = return \ No newline at end of file