kranewm

An ICCCM & EWMH compliant X11 reparenting, dynamic window manager, written in C++
git clone git clone git://git.deurzen.net/kranewm.git
Log | Files | Refs | LICENSE

commit df8bc68bc54591351a34301124a621a6e011e85c
parent d5b624e931bbbe4c30fa61eb2deb3ba5809aa80b
Author: deurzen <m.deurzen@tum.de>
Date:   Sat, 18 Sep 2021 23:26:23 +0200

adds initial multi-screen support

Diffstat:
Mconfig.mk | 2+-
Mlaunch | 6+++---
Msrc/winsys/screen.hh | 1+
Msrc/winsys/xdata/xconnection.cc | 66+++++++++++++++++++++++++++++++++++++++++++++++++-----------------
4 files changed, 54 insertions(+), 21 deletions(-)

diff --git a/config.mk b/config.mk @@ -2,7 +2,7 @@ PROJECT = kranewm BAR = kranebar CLIENT = kranec -DEPENDENCIES = x11 xrandr xres libprocps spdlog +DEPENDENCIES = x11 xrandr xinerama xres libprocps spdlog OBJDIR = obj SRCDIR = src diff --git a/launch b/launch @@ -1,4 +1,4 @@ #!/bin/bash -set -e -XEPHYR=$(which Xephyr) -xinit ./xinitrc -- "$XEPHYR" :102 -ac -screen 800x600 -host-cursor +set -Eeo pipefail + +xinit ./xinitrc -- $(which Xephyr) :102 -ac -screen 800x600 -screen 400x400 +xinerama -host-cursor diff --git a/src/winsys/screen.hh b/src/winsys/screen.hh @@ -4,6 +4,7 @@ #include "common.hh" #include "geometry.hh" #include "window.hh" +#include "util.hh" #include <set> #include <unordered_map> diff --git a/src/winsys/xdata/xconnection.cc b/src/winsys/xdata/xconnection.cc @@ -17,6 +17,7 @@ extern "C" { #include <X11/Xutil.h> #include <X11/extensions/XRes.h> #include <X11/extensions/Xrandr.h> +#include <X11/extensions/Xinerama.h> #include <X11/keysym.h> #include <X11/keysymdef.h> #include <fcntl.h> @@ -318,36 +319,67 @@ XConnection::process_messages(std::function<void(winsys::Message)> callback) std::vector<winsys::Screen> XConnection::connected_outputs() { - XRRScreenResources* screen_resources = XRRGetScreenResources(mp_dpy, m_root); + int n_screen_info; + XineramaScreenInfo* screen_info = XineramaQueryScreens(mp_dpy, &n_screen_info); + std::vector<XineramaScreenInfo*> screen_info_vector; - if (!screen_resources) + if (!screen_info) return {}; - XRRCrtcInfo* crtc_info = NULL; - std::vector<winsys::Screen> screens = {}; + screen_info_vector.reserve(n_screen_info); + std::transform( + &screen_info[0], + &screen_info[n_screen_info], + std::back_inserter(screen_info_vector), + [](XineramaScreenInfo& screen_info) -> XineramaScreenInfo* { + return &screen_info; + } + ); - for (int i = 0; i < screen_resources->ncrtc; ++i) { - crtc_info = XRRGetCrtcInfo( - mp_dpy, - screen_resources, - screen_resources->crtcs[i] - ); + std::stable_sort( + screen_info_vector.begin(), + screen_info_vector.end(), + [](XineramaScreenInfo* screen_info1, XineramaScreenInfo* screen_info2) -> bool { + if (screen_info1->x_org < screen_info2->x_org) + return true; + + if (screen_info1->x_org == screen_info2->x_org) + return screen_info1->y_org < screen_info2->y_org; - if (crtc_info->width > 0 && crtc_info->height > 0) { + return false; + } + ); + + std::vector<winsys::Screen> screens; + screens.reserve(n_screen_info); + + std::transform( + screen_info_vector.begin(), + std::remove_if( + screen_info_vector.begin(), + screen_info_vector.end(), + [](XineramaScreenInfo* screen_info) -> bool { + return !(screen_info->width > 0 && screen_info->height > 0); + } + ), + std::back_inserter(screens), + [i=0](XineramaScreenInfo* screen_info) mutable -> winsys::Screen { winsys::Region region = winsys::Region { winsys::Pos { - crtc_info->x, - crtc_info->y + screen_info->x_org, + screen_info->y_org }, winsys::Dim { - static_cast<int>(crtc_info->width), - static_cast<int>(crtc_info->height) + screen_info->width, + screen_info->height } }; - screens.emplace_back(winsys::Screen(i, region)); + return winsys::Screen(i++, region); } - } + ); + + XFree(screen_info); return screens; }