mirror of https://github.com/yshui/picom.git
core: drop xinerama
there are two x extensions for working with monitors (especially multiple): xinerama and randr. xinerama is old, feature-poor and in general isn't used anymore compared to the randr: new, feature-rich and widely-used. for some reason we were using both of them, so let's drop xinerama to keep things simple, clean and small. and to be modern. the drop was done in three steps: * first step was to replace all the xinerama-based code with the randr-based one and to replace or remove all the xinerama mentions; * second step was to replace the xinerama's terminology with the randr's one. xinerama was referring only to the word "screen", while randr refers to multiple words and i think the word "monitor" is the most suitable for us and, hopefully, clear both to a contributor and to an end user; * third step was to refactor the new randr-based code if needed and to address related todo's (mostly about moving related functions elsewhere). all the steps were done well except addressing a leftover todo about moving the win_update_monitor function to the x.c which wasn't done. the xinerama-shadow-crop option was renamed to crop-shadow-to-monitor, but it's previous name is still accepted, has effect and the deprecation message is printed to preserve backwards-compatibility.
This commit is contained in:
parent
102a0bc5e0
commit
986b3c1cb3
|
@ -36,7 +36,7 @@ jobs:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
- run: sudo apt update && sudo apt install libxext-dev libxcb1-dev libxcb-dpms0-dev libxcb-damage0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-render-util0-dev libxcb-render0-dev libxcb-randr0-dev libxcb-composite0-dev libxcb-image0-dev libxcb-present-dev libxcb-xinerama0-dev libxcb-glx0-dev libpixman-1-dev libdbus-1-dev libconfig-dev libgl1-mesa-dev libpcre2-dev libevdev-dev uthash-dev libev-dev libx11-xcb-dev meson ninja-build
|
- run: sudo apt update && sudo apt install libxext-dev libxcb1-dev libxcb-dpms0-dev libxcb-damage0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-render-util0-dev libxcb-render0-dev libxcb-randr0-dev libxcb-composite0-dev libxcb-image0-dev libxcb-present-dev libxcb-glx0-dev libpixman-1-dev libdbus-1-dev libconfig-dev libgl1-mesa-dev libpcre2-dev libevdev-dev uthash-dev libev-dev libx11-xcb-dev meson ninja-build
|
||||||
if: ${{ matrix.language == 'cpp' }}
|
if: ${{ matrix.language == 'cpp' }}
|
||||||
|
|
||||||
# Autobuild
|
# Autobuild
|
||||||
|
|
|
@ -32,7 +32,6 @@ Assuming you already have all the usual building tools installed (e.g. gcc, pyth
|
||||||
* xcb-composite
|
* xcb-composite
|
||||||
* xcb-image
|
* xcb-image
|
||||||
* xcb-present
|
* xcb-present
|
||||||
* xcb-xinerama
|
|
||||||
* xcb-glx
|
* xcb-glx
|
||||||
* pixman
|
* pixman
|
||||||
* libdbus (optional, disable with the `-Ddbus=false` meson configure flag)
|
* libdbus (optional, disable with the `-Ddbus=false` meson configure flag)
|
||||||
|
@ -45,7 +44,7 @@ Assuming you already have all the usual building tools installed (e.g. gcc, pyth
|
||||||
On Debian based distributions (e.g. Ubuntu), the needed packages are
|
On Debian based distributions (e.g. Ubuntu), the needed packages are
|
||||||
|
|
||||||
```
|
```
|
||||||
libxext-dev libxcb1-dev libxcb-damage0-dev libxcb-dpms0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-render-util0-dev libxcb-render0-dev libxcb-randr0-dev libxcb-composite0-dev libxcb-image0-dev libxcb-present-dev libxcb-xinerama0-dev libxcb-glx0-dev libpixman-1-dev libdbus-1-dev libconfig-dev libgl-dev libegl-dev libpcre2-dev libevdev-dev uthash-dev libev-dev libx11-xcb-dev meson
|
libxext-dev libxcb1-dev libxcb-damage0-dev libxcb-dpms0-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-render-util0-dev libxcb-render0-dev libxcb-randr0-dev libxcb-composite0-dev libxcb-image0-dev libxcb-present-dev libxcb-glx0-dev libpixman-1-dev libdbus-1-dev libconfig-dev libgl-dev libegl-dev libpcre2-dev libevdev-dev uthash-dev libev-dev libx11-xcb-dev meson
|
||||||
```
|
```
|
||||||
|
|
||||||
On Fedora, the needed packages are
|
On Fedora, the needed packages are
|
||||||
|
|
|
@ -217,8 +217,8 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box
|
||||||
*--shadow-exclude-reg* 'GEOMETRY'::
|
*--shadow-exclude-reg* 'GEOMETRY'::
|
||||||
Specify a X geometry that describes the region in which shadow should not be painted in, such as a dock window region. Use `--shadow-exclude-reg x10+0-0`, for example, if the 10 pixels on the bottom of the screen should not have shadows painted on.
|
Specify a X geometry that describes the region in which shadow should not be painted in, such as a dock window region. Use `--shadow-exclude-reg x10+0-0`, for example, if the 10 pixels on the bottom of the screen should not have shadows painted on.
|
||||||
|
|
||||||
*--xinerama-shadow-crop*::
|
*--crop-shadow-to-monitor*::
|
||||||
Crop shadow of a window fully on a particular Xinerama screen to the screen.
|
Crop shadow of a window fully on a particular monitor to that monitor. This is currently implemented using the X RandR extension.
|
||||||
|
|
||||||
*--backend* 'BACKEND'::
|
*--backend* 'BACKEND'::
|
||||||
Specify the backend to use: `xrender`, `glx`, or `xr_glx_hybrid`. `xrender` is the default one.
|
Specify the backend to use: `xrender`, `glx`, or `xr_glx_hybrid`. `xrender` is the default one.
|
||||||
|
|
|
@ -61,8 +61,9 @@ shadow-exclude = [
|
||||||
#
|
#
|
||||||
# shadow-exclude-reg = ""
|
# shadow-exclude-reg = ""
|
||||||
|
|
||||||
# Crop shadow of a window fully on a particular Xinerama screen to the screen.
|
# Crop shadow of a window fully on a particular monitor to that monitor. This is
|
||||||
# xinerama-shadow-crop = false
|
# currently implemented using the X RandR extension.
|
||||||
|
# crop-shadow-to-monitor = false
|
||||||
|
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
|
|
|
@ -327,18 +327,18 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||||
®_shadow_clip);
|
®_shadow_clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps->o.xinerama_shadow_crop && w->xinerama_scr >= 0 &&
|
if (ps->o.crop_shadow_to_monitor && w->randr_monitor >= 0 &&
|
||||||
w->xinerama_scr < ps->xinerama_nscrs) {
|
w->randr_monitor < ps->randr_nmonitors) {
|
||||||
// There can be a window where number of screens is
|
// There can be a window where number of monitors is
|
||||||
// updated, but the screen number attached to the windows
|
// updated, but the monitor number attached to the window
|
||||||
// have not.
|
// have not.
|
||||||
//
|
//
|
||||||
// Window screen number will be updated eventually, so
|
// Window monitor number will be updated eventually, so
|
||||||
// here we just check to make sure we don't access out of
|
// here we just check to make sure we don't access out of
|
||||||
// bounds.
|
// bounds.
|
||||||
pixman_region32_intersect(
|
pixman_region32_intersect(
|
||||||
®_shadow, ®_shadow,
|
®_shadow, ®_shadow,
|
||||||
&ps->xinerama_scr_regs[w->xinerama_scr]);
|
&ps->randr_monitor_regs[w->randr_monitor]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ps->o.transparent_clipping) {
|
if (ps->o.transparent_clipping) {
|
||||||
|
|
10
src/common.h
10
src/common.h
|
@ -368,12 +368,10 @@ typedef struct session {
|
||||||
int glx_event;
|
int glx_event;
|
||||||
/// Error base number for X GLX extension.
|
/// Error base number for X GLX extension.
|
||||||
int glx_error;
|
int glx_error;
|
||||||
/// Whether X Xinerama extension exists.
|
/// Number of X RandR monitors.
|
||||||
bool xinerama_exists;
|
int randr_nmonitors;
|
||||||
/// Xinerama screen regions.
|
/// X RandR monitor regions.
|
||||||
region_t *xinerama_scr_regs;
|
region_t *randr_monitor_regs;
|
||||||
/// Number of Xinerama screens.
|
|
||||||
int xinerama_nscrs;
|
|
||||||
/// Whether X Sync extension exists.
|
/// Whether X Sync extension exists.
|
||||||
bool xsync_exists;
|
bool xsync_exists;
|
||||||
/// Event base number for X Sync extension.
|
/// Event base number for X Sync extension.
|
||||||
|
|
|
@ -747,7 +747,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
|
||||||
.shadow_opacity = .75,
|
.shadow_opacity = .75,
|
||||||
.shadow_blacklist = NULL,
|
.shadow_blacklist = NULL,
|
||||||
.shadow_ignore_shaped = false,
|
.shadow_ignore_shaped = false,
|
||||||
.xinerama_shadow_crop = false,
|
.crop_shadow_to_monitor = false,
|
||||||
.shadow_clip_list = NULL,
|
.shadow_clip_list = NULL,
|
||||||
|
|
||||||
.corner_radius = 0,
|
.corner_radius = 0,
|
||||||
|
|
|
@ -153,8 +153,8 @@ typedef struct options {
|
||||||
c2_lptr_t *shadow_blacklist;
|
c2_lptr_t *shadow_blacklist;
|
||||||
/// Whether bounding-shaped window should be ignored.
|
/// Whether bounding-shaped window should be ignored.
|
||||||
bool shadow_ignore_shaped;
|
bool shadow_ignore_shaped;
|
||||||
/// Whether to crop shadow to the very Xinerama screen.
|
/// Whether to crop shadow to the very X RandR monitor.
|
||||||
bool xinerama_shadow_crop;
|
bool crop_shadow_to_monitor;
|
||||||
/// Don't draw shadow over these windows. A linked list of conditions.
|
/// Don't draw shadow over these windows. A linked list of conditions.
|
||||||
c2_lptr_t *shadow_clip_list;
|
c2_lptr_t *shadow_clip_list;
|
||||||
|
|
||||||
|
|
|
@ -384,8 +384,12 @@ char *parse_config_libconfig(options_t *opt, const char *config_file, bool *shad
|
||||||
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped", &opt->shadow_ignore_shaped);
|
lcfg_lookup_bool(&cfg, "shadow-ignore-shaped", &opt->shadow_ignore_shaped);
|
||||||
// --detect-rounded-corners
|
// --detect-rounded-corners
|
||||||
lcfg_lookup_bool(&cfg, "detect-rounded-corners", &opt->detect_rounded_corners);
|
lcfg_lookup_bool(&cfg, "detect-rounded-corners", &opt->detect_rounded_corners);
|
||||||
// --xinerama-shadow-crop
|
// --crop-shadow-to-monitor
|
||||||
lcfg_lookup_bool(&cfg, "xinerama-shadow-crop", &opt->xinerama_shadow_crop);
|
if (lcfg_lookup_bool(&cfg, "xinerama-shadow-crop", &opt->crop_shadow_to_monitor)) {
|
||||||
|
log_warn("xinerama-shadow-crop is deprecated. Use crop-shadow-to-monitor "
|
||||||
|
"instead.");
|
||||||
|
}
|
||||||
|
lcfg_lookup_bool(&cfg, "crop-shadow-to-monitor", &opt->crop_shadow_to_monitor);
|
||||||
// --detect-client-opacity
|
// --detect-client-opacity
|
||||||
lcfg_lookup_bool(&cfg, "detect-client-opacity", &opt->detect_client_opacity);
|
lcfg_lookup_bool(&cfg, "detect-client-opacity", &opt->detect_client_opacity);
|
||||||
// --refresh-rate
|
// --refresh-rate
|
||||||
|
|
|
@ -1202,7 +1202,7 @@ static bool cdbus_process_opts_get(session_t *ps, DBusMessage *msg) {
|
||||||
cdbus_m_opts_get_do(shadow_offset_x, cdbus_reply_int32);
|
cdbus_m_opts_get_do(shadow_offset_x, cdbus_reply_int32);
|
||||||
cdbus_m_opts_get_do(shadow_offset_y, cdbus_reply_int32);
|
cdbus_m_opts_get_do(shadow_offset_y, cdbus_reply_int32);
|
||||||
cdbus_m_opts_get_do(shadow_opacity, cdbus_reply_double);
|
cdbus_m_opts_get_do(shadow_opacity, cdbus_reply_double);
|
||||||
cdbus_m_opts_get_do(xinerama_shadow_crop, cdbus_reply_bool);
|
cdbus_m_opts_get_do(crop_shadow_to_monitor, cdbus_reply_bool);
|
||||||
|
|
||||||
cdbus_m_opts_get_do(fade_delta, cdbus_reply_int32);
|
cdbus_m_opts_get_do(fade_delta, cdbus_reply_int32);
|
||||||
cdbus_m_opts_get_do(fade_in_step, cdbus_reply_double);
|
cdbus_m_opts_get_do(fade_in_step, cdbus_reply_double);
|
||||||
|
|
|
@ -2,21 +2,21 @@
|
||||||
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
|
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <xcb/xcb.h>
|
|
||||||
#include <xcb/composite.h>
|
#include <xcb/composite.h>
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
#include "backend/driver.h"
|
#include "backend/driver.h"
|
||||||
#include "diagnostic.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "picom.h"
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "diagnostic.h"
|
||||||
|
#include "picom.h"
|
||||||
|
|
||||||
void print_diagnostics(session_t *ps, const char *config_file, bool compositor_running) {
|
void print_diagnostics(session_t *ps, const char *config_file, bool compositor_running) {
|
||||||
printf("**Version:** " PICOM_VERSION "\n");
|
printf("**Version:** " PICOM_VERSION "\n");
|
||||||
//printf("**CFLAGS:** %s\n", "??");
|
// printf("**CFLAGS:** %s\n", "??");
|
||||||
printf("\n### Extensions:\n\n");
|
printf("\n### Extensions:\n\n");
|
||||||
printf("* Shape: %s\n", ps->shape_exists ? "Yes" : "No");
|
printf("* Shape: %s\n", ps->shape_exists ? "Yes" : "No");
|
||||||
printf("* XRandR: %s\n", ps->randr_exists ? "Yes" : "No");
|
printf("* RandR: %s\n", ps->randr_exists ? "Yes" : "No");
|
||||||
printf("* Present: %s\n", ps->present_exists ? "Present" : "Not Present");
|
printf("* Present: %s\n", ps->present_exists ? "Present" : "Not Present");
|
||||||
printf("\n### Misc:\n\n");
|
printf("\n### Misc:\n\n");
|
||||||
printf("* Use Overlay: %s\n", ps->overlay != XCB_NONE ? "Yes" : "No");
|
printf("* Use Overlay: %s\n", ps->overlay != XCB_NONE ? "Yes" : "No");
|
||||||
|
|
|
@ -237,8 +237,8 @@ static void configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
||||||
win_set_flags(mw, WIN_FLAGS_SIZE_STALE);
|
win_set_flags(mw, WIN_FLAGS_SIZE_STALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate which screen this window is on
|
// Recalculate which monitor this window is on
|
||||||
win_update_screen(ps->xinerama_nscrs, ps->xinerama_scr_regs, mw);
|
win_update_monitor(ps->randr_nmonitors, ps->randr_monitor_regs, mw);
|
||||||
}
|
}
|
||||||
|
|
||||||
// override_redirect flag cannot be changed after window creation, as far
|
// override_redirect flag cannot be changed after window creation, as far
|
||||||
|
|
|
@ -16,8 +16,7 @@ cflags = []
|
||||||
|
|
||||||
required_xcb_packages = [
|
required_xcb_packages = [
|
||||||
'xcb-render', 'xcb-damage', 'xcb-randr', 'xcb-sync', 'xcb-composite',
|
'xcb-render', 'xcb-damage', 'xcb-randr', 'xcb-sync', 'xcb-composite',
|
||||||
'xcb-shape', 'xcb-xinerama', 'xcb-xfixes', 'xcb-present', 'xcb-glx',
|
'xcb-shape', 'xcb-xfixes', 'xcb-present', 'xcb-glx', 'xcb-dpms', 'xcb'
|
||||||
'xcb-dpms', 'xcb'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
required_packages = [
|
required_packages = [
|
||||||
|
|
|
@ -72,6 +72,9 @@ static const struct picom_option picom_options[] = {
|
||||||
"managers not passing _NET_WM_WINDOW_OPACITY of client windows to frame"},
|
"managers not passing _NET_WM_WINDOW_OPACITY of client windows to frame"},
|
||||||
{"refresh-rate" , required_argument, 269, NULL , NULL},
|
{"refresh-rate" , required_argument, 269, NULL , NULL},
|
||||||
{"vsync" , optional_argument, 270, NULL , "Enable VSync"},
|
{"vsync" , optional_argument, 270, NULL , "Enable VSync"},
|
||||||
|
{"crop-shadow-to-monitor" , no_argument , 271, NULL , "Crop shadow of a window fully on a particular monitor to that monitor. "
|
||||||
|
"This is currently implemented using the X RandR extension"},
|
||||||
|
{"xinerama-shadow-crop" , no_argument , 272, NULL , NULL},
|
||||||
{"sw-opti" , no_argument , 274, NULL , NULL},
|
{"sw-opti" , no_argument , 274, NULL , NULL},
|
||||||
{"vsync-aggressive" , no_argument , 275, NULL , NULL},
|
{"vsync-aggressive" , no_argument , 275, NULL , NULL},
|
||||||
{"use-ewmh-active-win" , no_argument , 276, NULL , "Use _NET_WM_ACTIVE_WINDOW on the root window to determine which window is "
|
{"use-ewmh-active-win" , no_argument , 276, NULL , "Use _NET_WM_ACTIVE_WINDOW on the root window to determine which window is "
|
||||||
|
@ -119,7 +122,6 @@ static const struct picom_option picom_options[] = {
|
||||||
{"opacity-rule" , required_argument, 304, "OPACITY:COND", "Specify a list of opacity rules, see man page for more details"},
|
{"opacity-rule" , required_argument, 304, "OPACITY:COND", "Specify a list of opacity rules, see man page for more details"},
|
||||||
{"shadow-exclude-reg" , required_argument, 305, NULL , NULL},
|
{"shadow-exclude-reg" , required_argument, 305, NULL , NULL},
|
||||||
{"paint-exclude" , required_argument, 306, NULL , NULL},
|
{"paint-exclude" , required_argument, 306, NULL , NULL},
|
||||||
{"xinerama-shadow-crop" , no_argument , 307, NULL , "Crop shadow of a window fully on a particular Xinerama screen to the screen."},
|
|
||||||
{"unredir-if-possible-exclude" , required_argument, 308, "COND" , "Conditions of windows that shouldn't be considered full-screen for "
|
{"unredir-if-possible-exclude" , required_argument, 308, "COND" , "Conditions of windows that shouldn't be considered full-screen for "
|
||||||
"unredirecting screen."},
|
"unredirecting screen."},
|
||||||
{"unredir-if-possible-delay" , required_argument, 309, NULL, "Delay before unredirecting the window, in milliseconds. Defaults to 0."},
|
{"unredir-if-possible-delay" , required_argument, 309, NULL, "Delay before unredirecting the window, in milliseconds. Defaults to 0."},
|
||||||
|
@ -485,8 +487,8 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||||
P_CASEBOOL(267, detect_rounded_corners);
|
P_CASEBOOL(267, detect_rounded_corners);
|
||||||
P_CASEBOOL(268, detect_client_opacity);
|
P_CASEBOOL(268, detect_client_opacity);
|
||||||
case 269:
|
case 269:
|
||||||
log_warn("--refresh-rate has been deprecated, please remove it from"
|
log_warn("--refresh-rate has been deprecated, please remove it "
|
||||||
"your command line options");
|
"from your command line options");
|
||||||
break;
|
break;
|
||||||
case 270:
|
case 270:
|
||||||
if (optarg) {
|
if (optarg) {
|
||||||
|
@ -499,6 +501,12 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||||
opt->vsync = true;
|
opt->vsync = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
P_CASEBOOL(271, crop_shadow_to_monitor);
|
||||||
|
case 272:
|
||||||
|
opt->crop_shadow_to_monitor = true;
|
||||||
|
log_warn("--xinerama-shadow-crop is deprecated. Use "
|
||||||
|
"--crop-shadow-to-monitor instead.");
|
||||||
|
break;
|
||||||
case 274:
|
case 274:
|
||||||
log_warn("--sw-opti has been deprecated, please remove it from the "
|
log_warn("--sw-opti has been deprecated, please remove it from the "
|
||||||
"command line options");
|
"command line options");
|
||||||
|
@ -506,7 +514,7 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||||
case 275:
|
case 275:
|
||||||
// --vsync-aggressive
|
// --vsync-aggressive
|
||||||
log_error("--vsync-aggressive has been removed, please remove it"
|
log_error("--vsync-aggressive has been removed, please remove it"
|
||||||
" from the command line options");
|
" from the command line options");
|
||||||
failed = true;
|
failed = true;
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(276, use_ewmh_active_win);
|
P_CASEBOOL(276, use_ewmh_active_win);
|
||||||
|
@ -625,7 +633,6 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||||
// --paint-exclude
|
// --paint-exclude
|
||||||
condlst_add(&opt->paint_blacklist, optarg);
|
condlst_add(&opt->paint_blacklist, optarg);
|
||||||
break;
|
break;
|
||||||
P_CASEBOOL(307, xinerama_shadow_crop);
|
|
||||||
case 308:
|
case 308:
|
||||||
// --unredir-if-possible-exclude
|
// --unredir-if-possible-exclude
|
||||||
condlst_add(&opt->unredir_if_possible_blacklist, optarg);
|
condlst_add(&opt->unredir_if_possible_blacklist, optarg);
|
||||||
|
|
80
src/picom.c
80
src/picom.c
|
@ -28,7 +28,6 @@
|
||||||
#include <xcb/render.h>
|
#include <xcb/render.h>
|
||||||
#include <xcb/sync.h>
|
#include <xcb/sync.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
#include <xcb/xinerama.h>
|
|
||||||
|
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
#include <test.h>
|
#include <test.h>
|
||||||
|
@ -111,21 +110,6 @@ void quit(session_t *ps) {
|
||||||
ev_break(ps->loop, EVBREAK_ALL);
|
ev_break(ps->loop, EVBREAK_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Free Xinerama screen info.
|
|
||||||
*
|
|
||||||
* XXX consider moving to x.c
|
|
||||||
*/
|
|
||||||
static inline void free_xinerama_info(session_t *ps) {
|
|
||||||
if (ps->xinerama_scr_regs) {
|
|
||||||
for (int i = 0; i < ps->xinerama_nscrs; ++i)
|
|
||||||
pixman_region32_fini(&ps->xinerama_scr_regs[i]);
|
|
||||||
free(ps->xinerama_scr_regs);
|
|
||||||
ps->xinerama_scr_regs = NULL;
|
|
||||||
}
|
|
||||||
ps->xinerama_nscrs = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current system clock in milliseconds.
|
* Get current system clock in milliseconds.
|
||||||
*/
|
*/
|
||||||
|
@ -135,41 +119,6 @@ static inline int64_t get_time_ms(void) {
|
||||||
return (int64_t)tp.tv_sec * 1000 + (int64_t)tp.tv_nsec / 1000000;
|
return (int64_t)tp.tv_sec * 1000 + (int64_t)tp.tv_nsec / 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Move to x.c
|
|
||||||
void cxinerama_upd_scrs(session_t *ps) {
|
|
||||||
// XXX Consider deprecating Xinerama, switch to RandR when necessary
|
|
||||||
free_xinerama_info(ps);
|
|
||||||
|
|
||||||
if (!ps->o.xinerama_shadow_crop || !ps->xinerama_exists)
|
|
||||||
return;
|
|
||||||
|
|
||||||
xcb_xinerama_is_active_reply_t *active =
|
|
||||||
xcb_xinerama_is_active_reply(ps->c, xcb_xinerama_is_active(ps->c), NULL);
|
|
||||||
if (!active || !active->state) {
|
|
||||||
free(active);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
free(active);
|
|
||||||
|
|
||||||
auto xinerama_scrs =
|
|
||||||
xcb_xinerama_query_screens_reply(ps->c, xcb_xinerama_query_screens(ps->c), NULL);
|
|
||||||
if (!xinerama_scrs) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xcb_xinerama_screen_info_t *scrs =
|
|
||||||
xcb_xinerama_query_screens_screen_info(xinerama_scrs);
|
|
||||||
ps->xinerama_nscrs = xcb_xinerama_query_screens_screen_info_length(xinerama_scrs);
|
|
||||||
|
|
||||||
ps->xinerama_scr_regs = ccalloc(ps->xinerama_nscrs, region_t);
|
|
||||||
for (int i = 0; i < ps->xinerama_nscrs; ++i) {
|
|
||||||
const xcb_xinerama_screen_info_t *const s = &scrs[i];
|
|
||||||
pixman_region32_init_rect(&ps->xinerama_scr_regs[i], s->x_org, s->y_org,
|
|
||||||
s->width, s->height);
|
|
||||||
}
|
|
||||||
free(xinerama_scrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool dpms_screen_is_off(xcb_dpms_info_reply_t *info) {
|
static inline bool dpms_screen_is_off(xcb_dpms_info_reply_t *info) {
|
||||||
// state is a bool indicating whether dpms is enabled
|
// state is a bool indicating whether dpms is enabled
|
||||||
return info->state && (info->power_level != XCB_DPMS_DPMS_MODE_ON);
|
return info->state && (info->power_level != XCB_DPMS_DPMS_MODE_ON);
|
||||||
|
@ -691,8 +640,8 @@ static void configure_root(session_t *ps) {
|
||||||
|
|
||||||
static void handle_root_flags(session_t *ps) {
|
static void handle_root_flags(session_t *ps) {
|
||||||
if ((ps->root_flags & ROOT_FLAGS_SCREEN_CHANGE) != 0) {
|
if ((ps->root_flags & ROOT_FLAGS_SCREEN_CHANGE) != 0) {
|
||||||
if (ps->o.xinerama_shadow_crop) {
|
if (ps->o.crop_shadow_to_monitor) {
|
||||||
cxinerama_upd_scrs(ps);
|
x_update_randr_monitors(ps);
|
||||||
}
|
}
|
||||||
ps->root_flags &= ~(uint64_t)ROOT_FLAGS_SCREEN_CHANGE;
|
ps->root_flags &= ~(uint64_t)ROOT_FLAGS_SCREEN_CHANGE;
|
||||||
}
|
}
|
||||||
|
@ -1834,7 +1783,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
||||||
xcb_prefetch_extension_data(ps->c, &xcb_shape_id);
|
xcb_prefetch_extension_data(ps->c, &xcb_shape_id);
|
||||||
xcb_prefetch_extension_data(ps->c, &xcb_xfixes_id);
|
xcb_prefetch_extension_data(ps->c, &xcb_xfixes_id);
|
||||||
xcb_prefetch_extension_data(ps->c, &xcb_randr_id);
|
xcb_prefetch_extension_data(ps->c, &xcb_randr_id);
|
||||||
xcb_prefetch_extension_data(ps->c, &xcb_xinerama_id);
|
|
||||||
xcb_prefetch_extension_data(ps->c, &xcb_present_id);
|
xcb_prefetch_extension_data(ps->c, &xcb_present_id);
|
||||||
xcb_prefetch_extension_data(ps->c, &xcb_sync_id);
|
xcb_prefetch_extension_data(ps->c, &xcb_sync_id);
|
||||||
xcb_prefetch_extension_data(ps->c, &xcb_glx_id);
|
xcb_prefetch_extension_data(ps->c, &xcb_glx_id);
|
||||||
|
@ -2092,18 +2040,10 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query X RandR
|
// Query X RandR
|
||||||
if (ps->o.xinerama_shadow_crop) {
|
if (ps->o.crop_shadow_to_monitor && !ps->randr_exists) {
|
||||||
if (!ps->randr_exists) {
|
log_fatal("No X RandR extension. crop-shadow-to-monitor cannot be "
|
||||||
log_fatal("No XRandR extension. xinerama-shadow-crop cannot be "
|
"enabled.");
|
||||||
"enabled.");
|
goto err;
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query X Xinerama extension
|
|
||||||
if (ps->o.xinerama_shadow_crop) {
|
|
||||||
ext_info = xcb_get_extension_data(ps->c, &xcb_xinerama_id);
|
|
||||||
ps->xinerama_exists = ext_info && ext_info->present;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rebuild_screen_reg(ps);
|
rebuild_screen_reg(ps);
|
||||||
|
@ -2198,12 +2138,12 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Monitor screen changes if vsync_sw is enabled and we are using
|
// Monitor screen changes if vsync_sw is enabled and we are using
|
||||||
// an auto-detected refresh rate, or when Xinerama features are enabled
|
// an auto-detected refresh rate, or when X RandR features are enabled
|
||||||
if (ps->randr_exists && ps->o.xinerama_shadow_crop) {
|
if (ps->randr_exists && ps->o.crop_shadow_to_monitor) {
|
||||||
xcb_randr_select_input(ps->c, ps->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
|
xcb_randr_select_input(ps->c, ps->root, XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
cxinerama_upd_scrs(ps);
|
x_update_randr_monitors(ps);
|
||||||
|
|
||||||
{
|
{
|
||||||
xcb_render_create_picture_value_list_t pa = {
|
xcb_render_create_picture_value_list_t pa = {
|
||||||
|
@ -2436,7 +2376,7 @@ static void session_destroy(session_t *ps) {
|
||||||
}
|
}
|
||||||
free(ps->o.blur_kerns);
|
free(ps->o.blur_kerns);
|
||||||
free(ps->o.glx_fshader_win_str);
|
free(ps->o.glx_fshader_win_str);
|
||||||
free_xinerama_info(ps);
|
x_free_randr_info(ps);
|
||||||
|
|
||||||
// Release custom window shaders
|
// Release custom window shaders
|
||||||
free(ps->o.window_shader_fg);
|
free(ps->o.window_shader_fg);
|
||||||
|
|
|
@ -42,8 +42,6 @@ void circulate_win(session_t *ps, xcb_circulate_notify_event_t *ce);
|
||||||
|
|
||||||
void root_damaged(session_t *ps);
|
void root_damaged(session_t *ps);
|
||||||
|
|
||||||
void cxinerama_upd_scrs(session_t *ps);
|
|
||||||
|
|
||||||
void queue_redraw(session_t *ps);
|
void queue_redraw(session_t *ps);
|
||||||
|
|
||||||
void discard_pending(session_t *ps, uint32_t sequence);
|
void discard_pending(session_t *ps, uint32_t sequence);
|
||||||
|
|
19
src/render.c
19
src/render.c
|
@ -1098,18 +1098,19 @@ void paint_all(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||||
if (!ps->o.wintype_option[w->window_type].full_shadow)
|
if (!ps->o.wintype_option[w->window_type].full_shadow)
|
||||||
pixman_region32_subtract(®_tmp, ®_tmp, &bshape_no_corners);
|
pixman_region32_subtract(®_tmp, ®_tmp, &bshape_no_corners);
|
||||||
|
|
||||||
if (ps->o.xinerama_shadow_crop && w->xinerama_scr >= 0 &&
|
if (ps->o.crop_shadow_to_monitor && w->randr_monitor >= 0 &&
|
||||||
w->xinerama_scr < ps->xinerama_nscrs)
|
w->randr_monitor < ps->randr_nmonitors) {
|
||||||
// There can be a window where number of screens
|
// There can be a window where number of monitors is
|
||||||
// is updated, but the screen number attached to
|
// updated, but the monitor number attached to the window
|
||||||
// the windows have not.
|
// have not.
|
||||||
//
|
//
|
||||||
// Window screen number will be updated
|
// Window monitor number will be updated eventually, so
|
||||||
// eventually, so here we just check to make sure
|
// here we just check to make sure we don't access out of
|
||||||
// we don't access out of bounds.
|
// bounds.
|
||||||
pixman_region32_intersect(
|
pixman_region32_intersect(
|
||||||
®_tmp, ®_tmp,
|
®_tmp, ®_tmp,
|
||||||
&ps->xinerama_scr_regs[w->xinerama_scr]);
|
&ps->randr_monitor_regs[w->randr_monitor]);
|
||||||
|
}
|
||||||
|
|
||||||
// Detect if the region is empty before painting
|
// Detect if the region is empty before painting
|
||||||
if (pixman_region32_not_empty(®_tmp)) {
|
if (pixman_region32_not_empty(®_tmp)) {
|
||||||
|
|
44
src/win.c
44
src/win.c
|
@ -14,7 +14,6 @@
|
||||||
#include <xcb/render.h>
|
#include <xcb/render.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_renderutil.h>
|
#include <xcb/xcb_renderutil.h>
|
||||||
#include <xcb/xinerama.h>
|
|
||||||
|
|
||||||
#include "atom.h"
|
#include "atom.h"
|
||||||
#include "backend/backend.h"
|
#include "backend/backend.h"
|
||||||
|
@ -517,7 +516,7 @@ void win_process_update_flags(session_t *ps, struct managed_win *w) {
|
||||||
win_clear_flags(w, WIN_FLAGS_POSITION_STALE);
|
win_clear_flags(w, WIN_FLAGS_POSITION_STALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
win_update_screen(ps->xinerama_nscrs, ps->xinerama_scr_regs, w);
|
win_update_monitor(ps->randr_nmonitors, ps->randr_monitor_regs, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (win_check_flags_all(w, WIN_FLAGS_PROPERTY_STALE)) {
|
if (win_check_flags_all(w, WIN_FLAGS_PROPERTY_STALE)) {
|
||||||
|
@ -1550,7 +1549,7 @@ struct win *fill_win(session_t *ps, struct win *w) {
|
||||||
.shadow = false,
|
.shadow = false,
|
||||||
.clip_shadow_above = false,
|
.clip_shadow_above = false,
|
||||||
.fg_shader = NULL,
|
.fg_shader = NULL,
|
||||||
.xinerama_scr = -1,
|
.randr_monitor = -1,
|
||||||
.mode = WMODE_TRANS,
|
.mode = WMODE_TRANS,
|
||||||
.ever_damaged = false,
|
.ever_damaged = false,
|
||||||
.client_win = XCB_NONE,
|
.client_win = XCB_NONE,
|
||||||
|
@ -2434,33 +2433,24 @@ bool win_skip_fading(session_t *ps, struct managed_win *w) {
|
||||||
return win_check_fade_finished(ps, w);
|
return win_check_fade_finished(ps, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// TODO(absolutelynothelix): rename to x_update_win_(randr_?)monitor and move to
|
||||||
* Get the Xinerama screen a window is on.
|
// the x.c.
|
||||||
*
|
void win_update_monitor(int nmons, region_t *mons, struct managed_win *mw) {
|
||||||
* Return an index >= 0, or -1 if not found.
|
mw->randr_monitor = -1;
|
||||||
*
|
for (int i = 0; i < nmons; i++) {
|
||||||
* TODO(yshui) move to x.c
|
auto e = pixman_region32_extents(&mons[i]);
|
||||||
* TODO(yshui) use xrandr
|
if (e->x1 <= mw->g.x && e->y1 <= mw->g.y &&
|
||||||
*/
|
e->x2 >= mw->g.x + mw->widthb && e->y2 >= mw->g.y + mw->heightb) {
|
||||||
void win_update_screen(int nscreens, region_t *screens, struct managed_win *w) {
|
mw->randr_monitor = i;
|
||||||
w->xinerama_scr = -1;
|
log_debug("Window %#010x (%s), %dx%d+%dx%d, is entirely on the "
|
||||||
|
"monitor %d (%dx%d+%dx%d)",
|
||||||
for (int i = 0; i < nscreens; i++) {
|
mw->base.id, mw->name, mw->g.x, mw->g.y, mw->widthb,
|
||||||
auto e = pixman_region32_extents(&screens[i]);
|
mw->heightb, i, e->x1, e->y1, e->x2 - e->x1, e->y2 - e->y1);
|
||||||
if (e->x1 <= w->g.x && e->y1 <= w->g.y && e->x2 >= w->g.x + w->widthb &&
|
|
||||||
e->y2 >= w->g.y + w->heightb) {
|
|
||||||
w->xinerama_scr = i;
|
|
||||||
log_debug("Window %#010x (%s), %dx%d+%dx%d, is on screen "
|
|
||||||
"%d "
|
|
||||||
"(%dx%d+%dx%d)",
|
|
||||||
w->base.id, w->name, w->g.x, w->g.y, w->widthb, w->heightb,
|
|
||||||
i, e->x1, e->y1, e->x2 - e->x1, e->y2 - e->y1);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log_debug("Window %#010x (%s), %dx%d+%dx%d, is not contained by any "
|
log_debug("Window %#010x (%s), %dx%d+%dx%d, is not entirely on any monitor",
|
||||||
"screen",
|
mw->base.id, mw->name, mw->g.x, mw->g.y, mw->widthb, mw->heightb);
|
||||||
w->base.id, w->name, w->g.x, w->g.y, w->g.width, w->g.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map an already registered window
|
/// Map an already registered window
|
||||||
|
|
10
src/win.h
10
src/win.h
|
@ -123,8 +123,8 @@ struct managed_win {
|
||||||
struct win_geometry g;
|
struct win_geometry g;
|
||||||
/// Updated geometry received in events
|
/// Updated geometry received in events
|
||||||
struct win_geometry pending_g;
|
struct win_geometry pending_g;
|
||||||
/// Xinerama screen this window is on.
|
/// X RandR monitor this window is on.
|
||||||
int xinerama_scr;
|
int randr_monitor;
|
||||||
/// Window visual pict format
|
/// Window visual pict format
|
||||||
const xcb_render_pictforminfo_t *pictfmt;
|
const xcb_render_pictforminfo_t *pictfmt;
|
||||||
/// Client window visual pict format
|
/// Client window visual pict format
|
||||||
|
@ -345,7 +345,11 @@ void win_recheck_client(session_t *ps, struct managed_win *w);
|
||||||
*/
|
*/
|
||||||
double attr_pure win_calc_opacity_target(session_t *ps, const struct managed_win *w);
|
double attr_pure win_calc_opacity_target(session_t *ps, const struct managed_win *w);
|
||||||
bool attr_pure win_should_dim(session_t *ps, const struct managed_win *w);
|
bool attr_pure win_should_dim(session_t *ps, const struct managed_win *w);
|
||||||
void win_update_screen(int nscreens, region_t *screens, struct managed_win *w);
|
|
||||||
|
// TODO(absolutelynothelix): rename to x_update_win_(randr_?)monitor and move to
|
||||||
|
// the x.h.
|
||||||
|
void win_update_monitor(int nmons, region_t *mons, struct managed_win *mw);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the bounding shape of a window.
|
* Retrieve the bounding shape of a window.
|
||||||
*/
|
*/
|
||||||
|
|
38
src/x.c
38
src/x.c
|
@ -9,6 +9,7 @@
|
||||||
#include <xcb/composite.h>
|
#include <xcb/composite.h>
|
||||||
#include <xcb/damage.h>
|
#include <xcb/damage.h>
|
||||||
#include <xcb/glx.h>
|
#include <xcb/glx.h>
|
||||||
|
#include <xcb/randr.h>
|
||||||
#include <xcb/render.h>
|
#include <xcb/render.h>
|
||||||
#include <xcb/sync.h>
|
#include <xcb/sync.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
@ -787,3 +788,40 @@ xcb_screen_t *x_screen_of_display(xcb_connection_t *c, int screen) {
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void x_update_randr_monitors(session_t *ps) {
|
||||||
|
x_free_randr_info(ps);
|
||||||
|
|
||||||
|
if (!ps->o.crop_shadow_to_monitor || !ps->randr_exists) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_randr_get_monitors_reply_t *r = xcb_randr_get_monitors_reply(
|
||||||
|
ps->c, xcb_randr_get_monitors(ps->c, ps->root, true), NULL);
|
||||||
|
if (!r) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ps->randr_nmonitors = xcb_randr_get_monitors_monitors_length(r);
|
||||||
|
ps->randr_monitor_regs = ccalloc(ps->randr_nmonitors, region_t);
|
||||||
|
xcb_randr_monitor_info_iterator_t monitor_info_it =
|
||||||
|
xcb_randr_get_monitors_monitors_iterator(r);
|
||||||
|
for (int i = 0; monitor_info_it.rem; xcb_randr_monitor_info_next(&monitor_info_it)) {
|
||||||
|
xcb_randr_monitor_info_t *mi = monitor_info_it.data;
|
||||||
|
pixman_region32_init_rect(&ps->randr_monitor_regs[i++], mi->x, mi->y,
|
||||||
|
mi->width, mi->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void x_free_randr_info(session_t *ps) {
|
||||||
|
if (ps->randr_monitor_regs) {
|
||||||
|
for (int i = 0; i < ps->randr_nmonitors; i++) {
|
||||||
|
pixman_region32_fini(&ps->randr_monitor_regs[i]);
|
||||||
|
}
|
||||||
|
free(ps->randr_monitor_regs);
|
||||||
|
ps->randr_monitor_regs = NULL;
|
||||||
|
}
|
||||||
|
ps->randr_nmonitors = 0;
|
||||||
|
}
|
||||||
|
|
10
src/x.h
10
src/x.h
|
@ -302,4 +302,14 @@ x_get_pictfmt_for_standard(xcb_connection_t *c, xcb_pict_standard_t std);
|
||||||
|
|
||||||
xcb_screen_t *x_screen_of_display(xcb_connection_t *c, int screen);
|
xcb_screen_t *x_screen_of_display(xcb_connection_t *c, int screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X RandR-related functions.
|
||||||
|
*
|
||||||
|
* The x_update_randr_monitors function populates ps->randr_nmonitors and
|
||||||
|
* ps->randr_monitor_regs with the data X RandR provided and the
|
||||||
|
* x_free_randr_info function frees them.
|
||||||
|
*/
|
||||||
|
void x_update_randr_monitors(session_t *ps);
|
||||||
|
void x_free_randr_info(session_t *ps);
|
||||||
|
|
||||||
uint32_t attr_deprecated xcb_generate_id(xcb_connection_t *c);
|
uint32_t attr_deprecated xcb_generate_id(xcb_connection_t *c);
|
||||||
|
|
|
@ -64,8 +64,9 @@ shadow-exclude = [
|
||||||
#
|
#
|
||||||
# shadow-exclude-reg = ""
|
# shadow-exclude-reg = ""
|
||||||
|
|
||||||
# Crop shadow of a window fully on a particular Xinerama screen to the screen.
|
# Crop shadow of a window fully on a particular monitor to that monitor. This is
|
||||||
# xinerama-shadow-crop = false
|
# currently implemented using the X RandR extension.
|
||||||
|
# crop-shadow-to-monitor = false
|
||||||
|
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
|
|
Loading…
Reference in New Issue