Skip to content
Open
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
11 changes: 11 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ jobs:
- run: nim r -d:useCpu tests/test_cpu_pixels.nim
if: matrix.os == 'windows-latest'

- name: Check two X11 monitors
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update -qq
sudo apt-get install -y x11-xserver-utils
xvfb-run -a -s "-noreset -screen 0 1600x600x24" sh -ec '
xrandr --setmonitor LEFT 800/200x600/150+0+0 screen
xrandr --setmonitor RIGHT 800/200x600/150+800+0 none
nim r --parallelBuild:1 tests/test_screens.nim
'

# Build native examples.
- run: nim c examples/basic.nim
- run: nim c examples/basic_boxy.nim
Expand Down
8 changes: 2 additions & 6 deletions examples/screens.nim
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import windy

when defined(windows) or defined(macosx):
# Screens API only currently supported on Windows and macOS

let screens = getScreens()
for screen in screens:
echo screen
for screen in getScreens():
echo screen
23 changes: 22 additions & 1 deletion src/windy/platforms/linux/x11.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import
std/[os, osproc, sequtils, sets, strformat, strutils, times, unicode, uri, pathnorm],
../../[common, internal],
vmath, pixie,
x11/[glx, keysym, x, xevent, xlib, xcursor]
x11/[glx, keysym, x, xevent, xlib, xcursor, xrandr]

import ../../http
export http
Expand Down Expand Up @@ -625,6 +625,27 @@ proc `title=`*(window: Window, v: string) =
window.handle.setProperty(xaNetWMIconName, xaUTF8String, 8, v)
display.Xutf8SetWMProperties(window.handle, v, v, nil, 0, nil, nil, nil)

proc getScreens*(): seq[common.Screen] =
## Returns active X11 monitors and their desktop positions (RandR 1.5).
init()
var major, minor, count: cint
if display.XRRQueryVersion(major.addr, minor.addr) == 0 or
(major == 1 and minor < 5) or major < 1:
raise WindyError.newException("Screen enumeration requires RandR 1.5")
let monitors = display.XRRGetMonitors(display.defaultRootWindow, 1, count.addr)
if monitors == nil:
return
defer: XRRFreeMonitors(monitors)
for i in 0 ..< count:
let monitor = monitors[i]
result.add common.Screen(
left: monitor.x,
top: monitor.y,
right: monitor.x + monitor.width,
bottom: monitor.y + monitor.height,
primary: monitor.primary != 0
)

proc contentScale*(window: Window): float32 =
const defaultScreenDpi = 96.0

Expand Down
15 changes: 15 additions & 0 deletions src/windy/platforms/linux/x11/xrandr.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import x, xlib

type
XRRMonitorInfo* {.bycopy.} = object
name*: Atom
primary*, automatic*, noutput*: cint
x*, y*, width*, height*, mwidth*, mheight*: cint
outputs*: ptr culong

{.push cdecl, dynlib: "libXrandr.so.2", importc.}
proc XRRQueryVersion*(display: Display, major, minor: ptr cint): cint
proc XRRGetMonitors*(display: Display, window: Window, active: cint,
count: ptr cint): ptr UncheckedArray[XRRMonitorInfo]
proc XRRFreeMonitors*(monitors: ptr UncheckedArray[XRRMonitorInfo])
{.pop.}
10 changes: 10 additions & 0 deletions tests/test_screens.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Run on the two-monitor Xvfb layout configured by the build workflow.
import windy, std/algorithm
var screens = getScreens()
screens.sort(proc(a, b: Screen): int = cmp(a.left, b.left))
doAssert screens.len == 2, "each monitor must be returned separately"
doAssert screens[0].left == 0 and screens[0].right == 800
doAssert screens[1].left == 800 and screens[1].right == 1600
for screen in screens:
doAssert screen.top == 0 and screen.bottom == 600
echo "Two distinct X11 monitor bounds passed"