Skip to content

Commit

Permalink
Add support for hovering buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
user committed Apr 23, 2022
1 parent 0db8fc6 commit c46e61b
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 19 deletions.
10 changes: 8 additions & 2 deletions src/atoms.nim
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,17 @@ type
IpcButtonSize = "WORM_IPC_BUTTON_SIZE",
IpcRootMenu = "WORM_IPC_ROOT_MENU",
IpcCloseActivePath = "WORM_IPC_CLOSE_ACTIVE_PATH",
IpcCloseInactivePath = "WORM_IPC_CLOSE_INACTIVE PATH",
IpcCloseInactivePath = "WORM_IPC_CLOSE_INACTIVE_PATH",
IpcCloseActiveHoveredPath = "WORM_IPC_CLOSE_ACTIVE_HOVERED_PATH"
IpcCloseInactiveHoveredPath = "WORM_IPC_CLOSE_INACTIVE_HOVERED_PATH",
IpcMaximizeActivePath = "WORM_IPC_MAXIMIZE_ACTIVE_PATH",
IpcMaximizeInactivePath = "WORM_IPC_MAXIMIZE_INACTIVE_PATH",
IpcMinimizeACtivePath = "WORM_IPC_MINIMIZE_ACTIVE_PATH",
IpcMaximizeActiveHoveredPath = "WORM_IPC_MAXIMIZE_ACTIVE_HOVERED_PATH",
IpcMaximizeInactiveHoveredPath = "WORM_IPC_MAXIMIZE_INACTIVE_HOVERED_PATH",
IpcMinimizeActivePath = "WORM_IPC_MINIMIZE_ACTIVE_PATH",
IpcMinimizeInactivePath = "WORM_IPC_MINIMIZE_INACTIVE_PATH",
IpcMinimizeActiveHoveredPath = "WORM_IPC_MINIMIZE_ACTIVE_HOVERED_PATH",
IpcMinimizeInactiveHoveredPath = "WORM_IPC_MINIMIZE_INACTIVE_HOVERED_PATH",
IpcMaximizeClient = "WORM_IPC_MAXIMIZE_CLIENT",
IpcMinimizeClient = "WORM_IPC_MINIMIZE_CLIENT",
IpcDecorationDisable = "WORM_IPC_DECORATION_DISABLE"
Expand Down
78 changes: 78 additions & 0 deletions src/events/clientmessage.nim
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,32 @@ proc handleClientMessage*(self: var Wm; ev: XClientMessageEvent) =
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcCloseActiveHoveredPath]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
var n: cint
discard self.dpy.XGetTextProperty(self.root, addr fontProp, self.ipcAtoms[
IpcCloseActiveHoveredPath])
let err = self.dpy.XmbTextPropertyToTextList(addr fontProp, cast[
ptr ptr cstring](addr fontList), addr n)
log "Changing active hovered close path to " & $fontList[0]
self.config.closePaths[bsActiveHover] = $fontList[0]
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcCloseInactiveHoveredPath]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
var n: cint
discard self.dpy.XGetTextProperty(self.root, addr fontProp, self.ipcAtoms[
IpcCloseInactiveHoveredPath])
let err = self.dpy.XmbTextPropertyToTextList(addr fontProp, cast[
ptr ptr cstring](addr fontList), addr n)
log "Changing inactive hovered close path to " & $fontList[0]
self.config.closePaths[bsInactiveHover] = $fontList[0]
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcMaximizeActivePath]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
Expand All @@ -493,6 +519,32 @@ proc handleClientMessage*(self: var Wm; ev: XClientMessageEvent) =
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcMaximizeActiveHoveredPath]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
var n: cint
discard self.dpy.XGetTextProperty(self.root, addr fontProp, self.ipcAtoms[
IpcMaximizeActiveHoveredPath])
let err = self.dpy.XmbTextPropertyToTextList(addr fontProp, cast[
ptr ptr cstring](addr fontList), addr n)
log "Changing active maximize hovered path to " & $fontList[0]
self.config.maximizePaths[bsActiveHover] = $fontList[0]
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcMaximizeInactiveHoveredPath]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
var n: cint
discard self.dpy.XGetTextProperty(self.root, addr fontProp, self.ipcAtoms[
IpcMaximizeInactiveHoveredPath])
let err = self.dpy.XmbTextPropertyToTextList(addr fontProp, cast[
ptr ptr cstring](addr fontList), addr n)
log "Changing inactive maximize hovered path to " & $fontList[0]
self.config.maximizePaths[bsInactiveHover] = $fontList[0]
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcMinimizeActivePath]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
Expand All @@ -519,6 +571,32 @@ proc handleClientMessage*(self: var Wm; ev: XClientMessageEvent) =
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcMinimizeActiveHoveredPath]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
var n: cint
discard self.dpy.XGetTextProperty(self.root, addr fontProp, self.ipcAtoms[
IpcMinimizeActiveHoveredPath])
let err = self.dpy.XmbTextPropertyToTextList(addr fontProp, cast[
ptr ptr cstring](addr fontList), addr n)
log "Changing active minimize hovered path to " & $fontList[0]
self.config.minimizePaths[bsActiveHover] = $fontList[0]
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcMinimizeInactiveHoveredPath]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
var n: cint
discard self.dpy.XGetTextProperty(self.root, addr fontProp, self.ipcAtoms[
IpcMinimizeInactiveHoveredPath])
let err = self.dpy.XmbTextPropertyToTextList(addr fontProp, cast[
ptr ptr cstring](addr fontList), addr n)
log "Changing inactive minimize hovered path to " & $fontList[0]
self.config.minimizePaths[bsInactiveHover] = $fontList[0]
if err >= Success and n > 0 and fontList != nil and fontList[0] != nil:
XFreeStringList cast[ptr cstring](fontList)
discard XFree fontProp.value
elif ev.data.l[0] == clong self.ipcAtoms[IpcDecorationDisable]:
var fontProp: XTextProperty
var fontList: ptr UncheckedArray[cstring]
Expand Down
7 changes: 3 additions & 4 deletions src/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type
beforeGeomMax*: Option[Geometry]
maximized*: bool
minimized*: bool
ButtonPaths = array[ButtonState, string]
Config* = object
borderActivePixel*, borderInactivePixel*, borderWidth*: uint
frameActivePixel*, frameInactivePixel*, frameHeight*: uint
Expand All @@ -45,13 +46,11 @@ type
frameParts*: tuple[left, center, right: seq[FramePart]]
buttonSize*: uint # always square FOR NOW
rootMenu*: string
closePaths*: array[ButtonState, string]
maximizePaths*: array[ButtonState, string]
minimizePaths*: array[ButtonState, string]
closePaths*, minimizePaths*, maximizePaths*: ButtonPaths
TagSet* = array[9, bool] # distinct

proc defaultTagSet*: TagSet = [true, false, false, false, false, false, false,
false, false]
false, false] # put the user on tag 1 when the wm starts.

proc switchTag*(self: var TagSet; tag: uint8): void =
for i, _ in self: self[i] = false
Expand Down
78 changes: 65 additions & 13 deletions src/wm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ proc renderTop*(self: var Wm; client: var Client) =
buttonStateOrig

if not fileExists self.config.closePaths[buttonState]:
continue
buttonState = buttonStateOrig
if not fileExists self.config.closePaths[buttonState]: continue

discard self.dpy.XMapWindow client.frame.close

Expand Down Expand Up @@ -347,8 +348,16 @@ proc renderTop*(self: var Wm; client: var Client) =

of fpMaximize:

buttonState = if client.frame.maximizeHovered and buttonStateOrig == bsActive:
bsActiveHover
elif client.frame.maximizeHovered and buttonStateOrig == bsInactive:
bsInactiveHover
else:
buttonStateOrig

if not fileExists self.config.maximizePaths[buttonState]:
continue
buttonState = buttonStateOrig
if not fileExists self.config.maximizePaths[buttonState]: continue

discard self.dpy.XMapWindow client.frame.maximize

Expand Down Expand Up @@ -384,8 +393,16 @@ proc renderTop*(self: var Wm; client: var Client) =
self.XPutImage(image, client.frame.maximize, gc)
of fpMinimize:

buttonState = if client.frame.minimizeHovered and buttonStateOrig == bsActive:
bsActiveHover
elif client.frame.minimizeHovered and buttonStateOrig == bsInactive:
bsInactiveHover
else:
buttonStateOrig

if not fileExists self.config.minimizePaths[buttonState]:
continue
buttonState = buttonStateOrig
if not fileExists self.config.minimizePaths[buttonState]: continue

discard self.dpy.XMapWindow client.frame.minimize

Expand Down Expand Up @@ -449,7 +466,8 @@ proc renderTop*(self: var Wm; client: var Client) =
buttonStateOrig

if not fileExists self.config.closePaths[buttonState]:
continue
buttonState = buttonStateOrig
if not fileExists self.config.closePaths[buttonState]: continue

let image = self.XCreateImage(self.config.closePaths[buttonState], fp, attr)

Expand Down Expand Up @@ -499,8 +517,16 @@ proc renderTop*(self: var Wm; client: var Client) =

of fpMaximize:

buttonState = if client.frame.maximizeHovered and buttonStateOrig == bsActive:
bsActiveHover
elif client.frame.maximizeHovered and buttonStateOrig == bsInactive:
bsInactiveHover
else:
buttonStateOrig

if not fileExists self.config.maximizePaths[buttonState]:
continue
buttonState = buttonStateOrig
if not fileExists self.config.maximizePaths[buttonState]: continue

discard self.dpy.XMapWindow client.frame.maximize

Expand Down Expand Up @@ -541,8 +567,16 @@ proc renderTop*(self: var Wm; client: var Client) =
self.XPutImage(image, client.frame.maximize, gc)
of fpMinimize:

buttonState = if client.frame.minimizeHovered and buttonStateOrig == bsActive:
bsActiveHover
elif client.frame.minimizeHovered and buttonStateOrig == bsInactive:
bsInactiveHover
else:
buttonStateOrig

if not fileExists self.config.minimizePaths[buttonState]:
continue
buttonState = buttonStateOrig
if not fileExists self.config.minimizePaths[buttonState]: continue

let image = self.XCreateImage(self.config.minimizePaths[buttonState], fp, attr)

Expand Down Expand Up @@ -570,7 +604,6 @@ proc renderTop*(self: var Wm; client: var Client) =
(extent.width div 2) + btnXOffset + textXOffset + btnSize
elif i == 2:
# ez
echo "HIT"
btnSize * 2
elif (i == 1 and centerFrames.len >= 3 and (centerFrames[0] == fpTitle or centerFrames[1] == fpTitle)):
-(extent.width div 2) + btnSize
Expand Down Expand Up @@ -635,8 +668,12 @@ proc renderTop*(self: var Wm; client: var Client) =
bsInactiveHover
else:
buttonStateOrig

if not fileExists self.config.closePaths[buttonState]:
continue
buttonState = buttonStateOrig
if not fileExists self.config.closePaths[buttonState]: continue

discard self.dpy.XMapWindow client.frame.close

let image = self.XCreateImage(self.config.closePaths[buttonState], fp, attr)

Expand Down Expand Up @@ -676,14 +713,21 @@ proc renderTop*(self: var Wm; client: var Client) =
btnYOffset
)

discard self.dpy.XMapWindow client.frame.close

self.XPutImage(image, client.frame.close, gc)

of fpMaximize:

buttonState = if client.frame.maximizeHovered and buttonStateOrig == bsActive:
bsActiveHover
elif client.frame.maximizeHovered and buttonStateOrig == bsInactive:
bsInactiveHover
else:
buttonStateOrig

if not fileExists self.config.maximizePaths[buttonState]:
continue
buttonState = buttonStateOrig
if not fileExists self.config.maximizePaths[buttonState]: continue

discard self.dpy.XMapWindow client.frame.maximize

Expand Down Expand Up @@ -732,10 +776,16 @@ proc renderTop*(self: var Wm; client: var Client) =
self.XPutImage(image, client.frame.maximize, gc)
of fpMinimize:

if not fileExists self.config.minimizePaths[buttonState]:
continue
buttonState = if client.frame.minimizeHovered and buttonStateOrig == bsActive:
bsActiveHover
elif client.frame.minimizeHovered and buttonStateOrig == bsInactive:
bsInactiveHover
else:
buttonStateOrig

discard self.dpy.XMapWindow client.frame.minimize
if not fileExists self.config.minimizePaths[buttonState]:
buttonState = buttonStateOrig
if not fileExists self.config.minimizePaths[buttonState]: continue

let
rightFrames = self.config.frameParts.right
Expand Down Expand Up @@ -777,6 +827,8 @@ proc renderTop*(self: var Wm; client: var Client) =
self.config.buttonOffset.y.cint
)

discard self.dpy.XMapWindow client.frame.minimize

let image = self.XCreateImage(self.config.minimizePaths[buttonState], fp, attr)

self.XPutImage(image, client.frame.minimize, gc)
Expand Down
18 changes: 18 additions & 0 deletions src/wormc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,36 @@ proc main() =
of "close-inactive-path":
dpy.sendStrPrep(ipcAtoms[IpcCloseInactivePath], params[i+1])
data = ipcAtoms[IpcCloseInactivePath].formatMess()
of "close-active-hovered-path":
dpy.sendStrPrep(ipcAtoms[IpcCloseActiveHoveredPath], params[i+1])
data = ipcAtoms[IpcCloseActiveHoveredPath].formatMess()
of "close-inactive-hovered-path":
dpy.sendStrPrep(ipcAtoms[IpcCloseInactiveHoveredPath], params[i+1])
data = ipcAtoms[IpcCloseInactiveHoveredPath].formatMess()
of "maximize-active-path":
dpy.sendStrPrep(ipcAtoms[IpcMaximizeActivePath], params[i+1])
data = ipcAtoms[IpcMaximizeActivePath].formatMess()
of "maximize-inactive-path":
dpy.sendStrPrep(ipcAtoms[IpcMaximizeInactivePath], params[i+1])
data = ipcAtoms[IpcMaximizeInactivePath].formatMess()
of "maximize-active-hovered-path":
dpy.sendStrPrep(ipcAtoms[IpcMaximizeActiveHoveredPath], params[i+1])
data = ipcAtoms[IpcMaximizeActiveHoveredPath].formatMess()
of "maximize-inactive-hovered-path":
dpy.sendStrPrep(ipcAtoms[IpcMaximizeInactiveHoveredPath], params[i+1])
data = ipcAtoms[IpcMaximizeInactiveHoveredPath].formatMess()
of "minimize-active-path":
dpy.sendStrPrep(ipcAtoms[IpcMinimizeActivePath], params[i+1])
data = ipcAtoms[IpcMinimizeActivePath].formatMess()
of "minimize-inactive-path":
dpy.sendStrPrep(ipcAtoms[IpcMinimizeInactivePath], params[i+1])
data = ipcAtoms[IpcMinimizeInactivePath].formatMess()
of "minimize-active-hovered-path":
dpy.sendStrPrep(ipcAtoms[IpcMinimizeActiveHoveredPath], params[i+1])
data = ipcAtoms[IpcMinimizeActiveHoveredPath].formatMess()
of "minimize-inactive-hovered-path":
dpy.sendStrPrep(ipcAtoms[IpcMinimizeInactiveHoveredPath], params[i+1])
data = ipcAtoms[IpcMinimizeInactiveHoveredPath].formatMess()
of "decoration-disable":
dpy.sendStrPrep(ipcAtoms[IpcDecorationDisable], params[i+1])
data = ipcAtoms[IpcDecorationDisable].formatMess()
Expand Down

0 comments on commit c46e61b

Please sign in to comment.