Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #54 - requires testing. #100

Merged
merged 2 commits into from Sep 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/nimdow.nim
Expand Up @@ -21,10 +21,10 @@ when isMainModule:
configloader.configLoc = findConfigPath()

let
loadedConfig = newConfig()
eventManager = newXEventManager()
loadedConfig = newConfig(eventManager)
configTable = loadConfigFile()

let eventManager = newXEventManager()
let nimdow = newWindowManager(eventManager, loadedConfig, configTable)

logger.enabled = loadedConfig.loggingEnabled
Expand Down
24 changes: 12 additions & 12 deletions src/nimdowpkg/config/configloader.nim
Expand Up @@ -34,15 +34,17 @@ type
# Hex values
fgColor*, bgColor*, selectionColor*: int
Config* = ref object
eventManager: XEventManager
identifierTable*: Table[string, Action]
keyComboTable*: Table[KeyCombo, Action]
windowSettings*: WindowSettings
barSettings*: BarSettings
listener*: XEventListener
loggingEnabled*: bool

proc newConfig*(): Config =
proc newConfig*(eventManager: XEventManager): Config =
Config(
eventManager: eventManager,
identifierTable: initTable[string, Action](),
keyComboTable: initTable[KeyCombo, Action](),
windowSettings: WindowSettings(
Expand All @@ -66,18 +68,18 @@ proc newConfig*(): Config =
)

proc configureAction*(this: Config, actionName: string, actionInvokee: Action)
proc hookConfig*(this: Config, eventManager: XEventManager)
proc hookConfig*(this: Config)
proc populateKeyComboTable*(this: Config, configTable: TomlTable, display: PDisplay)
proc populateControlAction(this: Config, display: PDisplay, action: string, configTable: TomlTable)
proc getKeyCombos(this: Config, configTable: TomlTable, display: PDisplay, action: string): seq[KeyCombo]
proc getKeysForAction(this: Config, configTable: TomlTable, action: string): seq[string]
proc getModifiersForAction(this: Config, configTable: TomlTable, action: string): seq[TomlValueRef]
proc getAutostartCommands(this: Config, configTable: TomlTable): seq[string]
proc runCommands(commands: varargs[string])
proc runCommands(this: Config, commands: varargs[string])

proc runAutostartCommands*(this: Config, configTable: TomlTable) =
let autostartCommands = this.getAutostartCommands(configTable)
runCommands(autostartCommands)
this.runCommands(autostartCommands)

proc getAutostartCommands(this: Config, configTable: TomlTable): seq[string] =
if not configTable.hasKey("autostart"):
Expand All @@ -95,10 +97,11 @@ proc getAutostartCommands(this: Config, configTable: TomlTable): seq[string] =
else:
result.add(cmd.stringVal)

proc runCommands(commands: varargs[string]) =
proc runCommands(this: Config, commands: varargs[string]) =
for cmd in commands:
try:
discard startProcess(command = cmd, options = { poEvalCommand })
let process = startProcess(command = cmd, options = { poEvalCommand })
this.eventManager.submitProcess(process)
except:
log "Failed to start command: " & cmd, lvlWarn

Expand All @@ -123,18 +126,15 @@ proc configureAction*(this: Config, actionName: string, actionInvokee: Action) =
proc configureExternalProcess(this: Config, command: string) =
this.identifierTable[command] =
proc(keycode: int) =
try:
discard startProcess(command = command, options = { poEvalCommand })
except:
log "Failed to start command: " & command, lvlWarn
this.runCommands(command)

proc hookConfig*(this: Config, eventManager: XEventManager) =
proc hookConfig*(this: Config) =
this.listener = proc(e: XEvent) =
let mask: int = cleanMask(int(e.xkey.state))
let keyCombo: KeyCombo = (int(e.xkey.keycode), mask)
if this.keyComboTable.hasKey(keyCombo):
this.keyComboTable[keyCombo](keyCombo.keycode)
eventManager.addListener(this.listener, KeyPress)
this.eventManager.addListener(this.listener, KeyPress)

proc populateControlsTable(this: Config, configTable: TomlTable, display: PDisplay) =
if not configTable.hasKey("controls"):
Expand Down
22 changes: 21 additions & 1 deletion src/nimdowpkg/event/xeventmanager.nim
@@ -1,13 +1,15 @@
import
x11/xlib,
tables,
sets
sets,
osproc

type
XEventListener* = proc(e: XEvent)
XEventManager* = ref object
listenerMap: Table[cint, HashSet[XEventListener]]
event: XEvent
processes: seq[Process]

proc newXEventManager*(): XEventManager =
XEventManager(listenerMap: initTable[cint, HashSet[XEventListener]]())
Expand Down Expand Up @@ -35,6 +37,21 @@ proc dispatchEvent*(this: XEventManager, e: XEvent) =
for listener in listeners:
listener(e)

proc submitProcess*(this: XEventManager, process: Process) =
this.processes.add(process)

proc closeFinishedProcesses(this: XEventManager) =
## Closes any finished processes
## and removes them from the processes seqeunce.
var i = 0
while i < this.processes.len:
let process = this.processes[i]
if not process.running():
process.close()
this.processes.del(i)
else:
i.inc

proc startEventListenerLoop*(this: XEventManager, display: PDisplay) =
## Infinitely listens for and dispatches libx.TXEvents.
## This proc will not return unless there is an error.
Expand All @@ -43,6 +60,9 @@ proc startEventListenerLoop*(this: XEventManager, display: PDisplay) =
# XNextEvent returns 0 unless there is an error.
while XNextEvent(display, addr(this.event)) == 0:
this.dispatchEvent(this.event)
this.closeFinishedProcesses()

# Cleanup
this.closeFinishedProcesses()
discard XCloseDisplay(display)

6 changes: 3 additions & 3 deletions src/nimdowpkg/windowmanager.nim
Expand Up @@ -110,7 +110,7 @@ proc newWindowManager*(eventManager: XEventManager, config: Config, configTable:
result.config.populateGeneralSettings(configTable)
result.mapConfigActions()
result.config.populateKeyComboTable(configTable, result.display)
result.config.hookConfig(eventManager)
result.config.hookConfig()
result.hookConfigKeys()

result.windowSettings = result.config.windowSettings
Expand Down Expand Up @@ -254,12 +254,12 @@ proc reloadConfig*(this: WindowManager) =
# Remove old config listener.
this.eventManager.removeListener(this.config.listener, KeyPress)

this.config = newConfig()
this.config = newConfig(this.eventManager)
let configTable = configloader.loadConfigFile()
this.config.populateGeneralSettings(configTable)
this.mapConfigActions()
this.config.populateKeyComboTable(configTable, this.display)
this.config.hookConfig(this.eventManager)
this.config.hookConfig()
this.hookConfigKeys()

this.windowSettings = this.config.windowSettings
Expand Down