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

(#26) tracking windows #82

Merged
merged 6 commits into from
Dec 26, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,16 @@ $ nimble build -d:developer
This will enable:
- Reloading the shaders with `Ctrl+R`

## Experimental Live Update
## Experimental Features Compilation Flags

See issue [#26]. For an experimental Live Update feature compile the application with the following flags:
Experimental or unstable features can be enabled by passing the following flags to `nimble build` command:

```console
$ nimble build -d:live
```

For a faster Live Update feature based on MIT-SHM X11 extension use `-d:mitshm`:

```console
$ nimble build -d:live -d:mitshm
```

The MIT-SHM support would probably not work for you until
[nim-lang/x11#31](https://github.com/nim-lang/x11/pull/31) is merged.

The feature is really unstable and experimental, so use it at your own risk.
| Flag | Description |
|---------------|--------------------------------------------------------------------------------------------------------------------------------|
| `-d:live` | Live image update. See issue [#26]. |
| `-d:mitshm` | Enables fater Live image update using MIT-SHM X11 extension. Should be used along with `-d:live` to have an effect |
| `-d:windowed` | Run boomer in windowed mode instead of fullscreen. |
| `-d:select` | Application lets the user to click on te window to "track" and it will track that specific window instead of the whole screen. |

## NixOS Overlay

Expand Down
65 changes: 55 additions & 10 deletions src/boomer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ import navigation
import screenshot
import config

import x11/xlib, x11/x, x11/xutil, x11/keysym, x11/xrandr, x11/xshm
import x11/xlib,
x11/x,
x11/xutil,
x11/keysym,
x11/xrandr,
x11/xshm,
x11/cursorfont
import opengl, opengl/glx
import la

Expand Down Expand Up @@ -128,6 +134,38 @@ proc getCursorPosition(display: PDisplay): Vec2f =
result.x = root_x.float32
result.y = root_y.float32

proc selectWindow(display: PDisplay): TWindow =
var cursor = XCreateFontCursor(display, XC_crosshair)
defer: discard XFreeCursor(display, cursor)

var root = DefaultRootWindow(display)
discard XGrabPointer(display, root, 0,
ButtonMotionMask or
ButtonPressMask or
ButtonReleaseMask,
GrabModeAsync, GrabModeAsync,
root, cursor,
CurrentTime)
defer: discard XUngrabPointer(display, CurrentTime)

discard XGrabKeyboard(display, root, 0,
GrabModeAsync, GrabModeAsync,
CurrentTime)
defer: discard XUngrabKeyboard(display, CurrentTime)

var event: TXEvent
while true:
discard XNextEvent(display, addr event)
case event.theType
of ButtonPress:
return event.xbutton.subwindow
of KeyPress:
return root
else:
discard

return root

proc main() =
var config = defaultConfig
let
Expand All @@ -147,9 +185,14 @@ proc main() =
defer:
discard XCloseDisplay(display)

var root = DefaultRootWindow(display)

var screenConfig = XRRGetScreenInfo(display, root)
when defined(select):
echo "Please select window:"
var trackingWindow = selectWindow(display)
else:
var trackingWindow = DefaultRootWindow(display)

var screenConfig = XRRGetScreenInfo(display, DefaultRootWindow(display))
let rate = XRRConfigCurrentRate(screenConfig)
echo "Screen rate: ", rate

Expand Down Expand Up @@ -177,21 +220,22 @@ proc main() =

echo "Visual ", vi.visualid, " selected"
var swa: TXSetWindowAttributes
swa.colormap = XCreateColormap(display, root,
swa.colormap = XCreateColormap(display, DefaultRootWindow(display),
vi.visual, AllocNone)
swa.event_mask = ButtonPressMask or ButtonReleaseMask or
KeyPressMask or KeyReleaseMask or
PointerMotionMask or ExposureMask or ClientMessage
swa.override_redirect = 1
swa.save_under = 1
when not defined(windowed):
swa.override_redirect = 1
swa.save_under = 1

var attributes: TXWindowAttributes
discard XGetWindowAttributes(
display,
DefaultRootWindow(display),
addr attributes)
var win = XCreateWindow(
display, root,
display, DefaultRootWindow(display),
0, 0, attributes.width.cuint, attributes.height.cuint, 0,
vi.depth, InputOutput, vi.visual,
CWColormap or CWEventMask or CWOverrideRedirect or CWSaveUnder, addr swa)
Expand Down Expand Up @@ -219,7 +263,7 @@ proc main() =

var shaderProgram = newShaderProgram(vertexShader, fragmentShader)

var screenshot = newScreenshot(display)
var screenshot = newScreenshot(display, trackingWindow)
defer: screenshot.destroy(display)

let w = screenshot.image.width.float32
Expand Down Expand Up @@ -303,7 +347,8 @@ proc main() =
let dt = 1.0 / rate.float
while not quitting:
# TODO(#78): Is there a better solution to keep the focus always on the window?
discard XSetInputFocus(display, win, RevertToParent, CurrentTime);
when not defined(windowed):
discard XSetInputFocus(display, win, RevertToParent, CurrentTime);

var wa: TXWindowAttributes
discard XGetWindowAttributes(display, win, addr wa)
Expand Down Expand Up @@ -413,7 +458,7 @@ proc main() =
glFinish()

when defined(live):
screenshot.refresh(display)
screenshot.refresh(display, trackingWindow)
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB.GLint,
Expand Down
19 changes: 9 additions & 10 deletions src/screenshot.nim
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ type Screenshot* = object
when defined(mitshm):
shminfo*: PXShmSegmentInfo

proc newScreenshot*(display: PDisplay): Screenshot =
var root = DefaultRootWindow(display)
proc newScreenshot*(display: PDisplay, window: TWindow): Screenshot =
var attributes: TXWindowAttributes
discard XGetWindowAttributes(display, root, addr attributes)
discard XGetWindowAttributes(display, window, addr attributes)

when defined(mitshm):
result.shminfo = cast[PXShmSegmentInfo](
Expand Down Expand Up @@ -70,28 +69,28 @@ proc newScreenshot*(display: PDisplay): Screenshot =

discard XShmAttach(display, result.shminfo)
discard XShmGetImage(
display, root, result.image, 0.cint, 0.cint, AllPlanes)
display, window, result.image, 0.cint, 0.cint, AllPlanes)
else:
result.image = XGetImage(
display, root,
display, window,
0, 0,
attributes.width.cuint,
attributes.height.cuint,
AllPlanes,
ZPixmap)

proc refresh*(screenshot: var Screenshot, display: PDisplay) =
var root = DefaultRootWindow(display)

proc refresh*(screenshot: var Screenshot, display: PDisplay, window: TWindow) =
when defined(mitshm):
# TODO(#83): MITSHM live update does not support window resizing
discard XShmGetImage(
display,
root, screenshot.image,
window, screenshot.image,
0.cint, 0.cint,
AllPlanes)
else:
# TODO(#84): XGetImage live update does not support window resizing
screenshot.image = XGetSubImage(
display, root,
display, window,
0, 0,
screenshot.image.width.cuint,
screenshot.image.height.cuint,
Expand Down