mirror of
https://github.com/yshui/picom.git
synced 2025-04-14 17:53:25 -04:00
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
22 changed files with 143 additions and 153 deletions
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
|
@ -36,7 +36,7 @@ jobs:
|
|||
languages: ${{ matrix.language }}
|
||||
|
||||
# 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' }}
|
||||
|
||||
# Autobuild
|
||||
|
|
|
@ -32,7 +32,6 @@ Assuming you already have all the usual building tools installed (e.g. gcc, pyth
|
|||
* xcb-composite
|
||||
* xcb-image
|
||||
* xcb-present
|
||||
* xcb-xinerama
|
||||
* xcb-glx
|
||||
* pixman
|
||||
* 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
|
||||
|
||||
```
|
||||
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
|
||||
|
|
|
@ -217,8 +217,8 @@ May also be one of the predefined kernels: `3x3box` (default), `5x5box`, `7x7box
|
|||
*--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.
|
||||
|
||||
*--xinerama-shadow-crop*::
|
||||
Crop shadow of a window fully on a particular Xinerama screen to the screen.
|
||||
*--crop-shadow-to-monitor*::
|
||||
Crop shadow of a window fully on a particular monitor to that monitor. This is currently implemented using the X RandR extension.
|
||||
|
||||
*--backend* 'BACKEND'::
|
||||
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 = ""
|
||||
|
||||
# Crop shadow of a window fully on a particular Xinerama screen to the screen.
|
||||
# xinerama-shadow-crop = false
|
||||
# Crop shadow of a window fully on a particular monitor to that monitor. This is
|
||||
# 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);
|
||||
}
|
||||
|
||||
if (ps->o.xinerama_shadow_crop && w->xinerama_scr >= 0 &&
|
||||
w->xinerama_scr < ps->xinerama_nscrs) {
|
||||
// There can be a window where number of screens is
|
||||
// updated, but the screen number attached to the windows
|
||||
if (ps->o.crop_shadow_to_monitor && w->randr_monitor >= 0 &&
|
||||
w->randr_monitor < ps->randr_nmonitors) {
|
||||
// There can be a window where number of monitors is
|
||||
// updated, but the monitor number attached to the window
|
||||
// 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
|
||||
// bounds.
|
||||
pixman_region32_intersect(
|
||||
®_shadow, ®_shadow,
|
||||
&ps->xinerama_scr_regs[w->xinerama_scr]);
|
||||
&ps->randr_monitor_regs[w->randr_monitor]);
|
||||
}
|
||||
|
||||
if (ps->o.transparent_clipping) {
|
||||
|
|
10
src/common.h
10
src/common.h
|
@ -368,12 +368,10 @@ typedef struct session {
|
|||
int glx_event;
|
||||
/// Error base number for X GLX extension.
|
||||
int glx_error;
|
||||
/// Whether X Xinerama extension exists.
|
||||
bool xinerama_exists;
|
||||
/// Xinerama screen regions.
|
||||
region_t *xinerama_scr_regs;
|
||||
/// Number of Xinerama screens.
|
||||
int xinerama_nscrs;
|
||||
/// Number of X RandR monitors.
|
||||
int randr_nmonitors;
|
||||
/// X RandR monitor regions.
|
||||
region_t *randr_monitor_regs;
|
||||
/// Whether X Sync extension exists.
|
||||
bool xsync_exists;
|
||||
/// 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_blacklist = NULL,
|
||||
.shadow_ignore_shaped = false,
|
||||
.xinerama_shadow_crop = false,
|
||||
.crop_shadow_to_monitor = false,
|
||||
.shadow_clip_list = NULL,
|
||||
|
||||
.corner_radius = 0,
|
||||
|
|
|
@ -153,8 +153,8 @@ typedef struct options {
|
|||
c2_lptr_t *shadow_blacklist;
|
||||
/// Whether bounding-shaped window should be ignored.
|
||||
bool shadow_ignore_shaped;
|
||||
/// Whether to crop shadow to the very Xinerama screen.
|
||||
bool xinerama_shadow_crop;
|
||||
/// Whether to crop shadow to the very X RandR monitor.
|
||||
bool crop_shadow_to_monitor;
|
||||
/// Don't draw shadow over these windows. A linked list of conditions.
|
||||
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);
|
||||
// --detect-rounded-corners
|
||||
lcfg_lookup_bool(&cfg, "detect-rounded-corners", &opt->detect_rounded_corners);
|
||||
// --xinerama-shadow-crop
|
||||
lcfg_lookup_bool(&cfg, "xinerama-shadow-crop", &opt->xinerama_shadow_crop);
|
||||
// --crop-shadow-to-monitor
|
||||
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
|
||||
lcfg_lookup_bool(&cfg, "detect-client-opacity", &opt->detect_client_opacity);
|
||||
// --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_y, cdbus_reply_int32);
|
||||
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_in_step, cdbus_reply_double);
|
||||
|
|
|
@ -2,21 +2,21 @@
|
|||
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/composite.h>
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "backend/driver.h"
|
||||
#include "diagnostic.h"
|
||||
#include "config.h"
|
||||
#include "picom.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) {
|
||||
printf("**Version:** " PICOM_VERSION "\n");
|
||||
//printf("**CFLAGS:** %s\n", "??");
|
||||
// printf("**CFLAGS:** %s\n", "??");
|
||||
printf("\n### Extensions:\n\n");
|
||||
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("\n### Misc:\n\n");
|
||||
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);
|
||||
}
|
||||
|
||||
// Recalculate which screen this window is on
|
||||
win_update_screen(ps->xinerama_nscrs, ps->xinerama_scr_regs, mw);
|
||||
// Recalculate which monitor this window is on
|
||||
win_update_monitor(ps->randr_nmonitors, ps->randr_monitor_regs, mw);
|
||||
}
|
||||
|
||||
// override_redirect flag cannot be changed after window creation, as far
|
||||
|
|
|
@ -16,8 +16,7 @@ cflags = []
|
|||
|
||||
required_xcb_packages = [
|
||||
'xcb-render', 'xcb-damage', 'xcb-randr', 'xcb-sync', 'xcb-composite',
|
||||
'xcb-shape', 'xcb-xinerama', 'xcb-xfixes', 'xcb-present', 'xcb-glx',
|
||||
'xcb-dpms', 'xcb'
|
||||
'xcb-shape', 'xcb-xfixes', 'xcb-present', 'xcb-glx', 'xcb-dpms', 'xcb'
|
||||
]
|
||||
|
||||
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"},
|
||||
{"refresh-rate" , required_argument, 269, NULL , NULL},
|
||||
{"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},
|
||||
{"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 "
|
||||
|
@ -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"},
|
||||
{"shadow-exclude-reg" , required_argument, 305, 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 "
|
||||
"unredirecting screen."},
|
||||
{"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(268, detect_client_opacity);
|
||||
case 269:
|
||||
log_warn("--refresh-rate has been deprecated, please remove it from"
|
||||
"your command line options");
|
||||
log_warn("--refresh-rate has been deprecated, please remove it "
|
||||
"from your command line options");
|
||||
break;
|
||||
case 270:
|
||||
if (optarg) {
|
||||
|
@ -499,6 +501,12 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
|||
opt->vsync = true;
|
||||
}
|
||||
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:
|
||||
log_warn("--sw-opti has been deprecated, please remove it from the "
|
||||
"command line options");
|
||||
|
@ -506,7 +514,7 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
|||
case 275:
|
||||
// --vsync-aggressive
|
||||
log_error("--vsync-aggressive has been removed, please remove it"
|
||||
" from the command line options");
|
||||
" from the command line options");
|
||||
failed = true;
|
||||
break;
|
||||
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
|
||||
condlst_add(&opt->paint_blacklist, optarg);
|
||||
break;
|
||||
P_CASEBOOL(307, xinerama_shadow_crop);
|
||||
case 308:
|
||||
// --unredir-if-possible-exclude
|
||||
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/sync.h>
|
||||
#include <xcb/xfixes.h>
|
||||
#include <xcb/xinerama.h>
|
||||
|
||||
#include <ev.h>
|
||||
#include <test.h>
|
||||
|
@ -111,21 +110,6 @@ void quit(session_t *ps) {
|
|||
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.
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// state is a bool indicating whether dpms is enabled
|
||||
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) {
|
||||
if ((ps->root_flags & ROOT_FLAGS_SCREEN_CHANGE) != 0) {
|
||||
if (ps->o.xinerama_shadow_crop) {
|
||||
cxinerama_upd_scrs(ps);
|
||||
if (ps->o.crop_shadow_to_monitor) {
|
||||
x_update_randr_monitors(ps);
|
||||
}
|
||||
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_xfixes_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_sync_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
|
||||
if (ps->o.xinerama_shadow_crop) {
|
||||
if (!ps->randr_exists) {
|
||||
log_fatal("No XRandR extension. xinerama-shadow-crop cannot be "
|
||||
"enabled.");
|
||||
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;
|
||||
if (ps->o.crop_shadow_to_monitor && !ps->randr_exists) {
|
||||
log_fatal("No X RandR extension. crop-shadow-to-monitor cannot be "
|
||||
"enabled.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
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
|
||||
// an auto-detected refresh rate, or when Xinerama features are enabled
|
||||
if (ps->randr_exists && ps->o.xinerama_shadow_crop) {
|
||||
// an auto-detected refresh rate, or when X RandR features are enabled
|
||||
if (ps->randr_exists && ps->o.crop_shadow_to_monitor) {
|
||||
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 = {
|
||||
|
@ -2436,7 +2376,7 @@ static void session_destroy(session_t *ps) {
|
|||
}
|
||||
free(ps->o.blur_kerns);
|
||||
free(ps->o.glx_fshader_win_str);
|
||||
free_xinerama_info(ps);
|
||||
x_free_randr_info(ps);
|
||||
|
||||
// Release custom window shaders
|
||||
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 cxinerama_upd_scrs(session_t *ps);
|
||||
|
||||
void queue_redraw(session_t *ps);
|
||||
|
||||
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)
|
||||
pixman_region32_subtract(®_tmp, ®_tmp, &bshape_no_corners);
|
||||
|
||||
if (ps->o.xinerama_shadow_crop && w->xinerama_scr >= 0 &&
|
||||
w->xinerama_scr < ps->xinerama_nscrs)
|
||||
// There can be a window where number of screens
|
||||
// is updated, but the screen number attached to
|
||||
// the windows have not.
|
||||
if (ps->o.crop_shadow_to_monitor && w->randr_monitor >= 0 &&
|
||||
w->randr_monitor < ps->randr_nmonitors) {
|
||||
// There can be a window where number of monitors is
|
||||
// updated, but the monitor number attached to the window
|
||||
// have not.
|
||||
//
|
||||
// Window screen number will be updated
|
||||
// eventually, so here we just check to make sure
|
||||
// we don't access out of bounds.
|
||||
// Window monitor number will be updated eventually, so
|
||||
// here we just check to make sure we don't access out of
|
||||
// bounds.
|
||||
pixman_region32_intersect(
|
||||
®_tmp, ®_tmp,
|
||||
&ps->xinerama_scr_regs[w->xinerama_scr]);
|
||||
&ps->randr_monitor_regs[w->randr_monitor]);
|
||||
}
|
||||
|
||||
// Detect if the region is empty before painting
|
||||
if (pixman_region32_not_empty(®_tmp)) {
|
||||
|
|
44
src/win.c
44
src/win.c
|
@ -14,7 +14,6 @@
|
|||
#include <xcb/render.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_renderutil.h>
|
||||
#include <xcb/xinerama.h>
|
||||
|
||||
#include "atom.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_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)) {
|
||||
|
@ -1550,7 +1549,7 @@ struct win *fill_win(session_t *ps, struct win *w) {
|
|||
.shadow = false,
|
||||
.clip_shadow_above = false,
|
||||
.fg_shader = NULL,
|
||||
.xinerama_scr = -1,
|
||||
.randr_monitor = -1,
|
||||
.mode = WMODE_TRANS,
|
||||
.ever_damaged = false,
|
||||
.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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Xinerama screen a window is on.
|
||||
*
|
||||
* Return an index >= 0, or -1 if not found.
|
||||
*
|
||||
* TODO(yshui) move to x.c
|
||||
* TODO(yshui) use xrandr
|
||||
*/
|
||||
void win_update_screen(int nscreens, region_t *screens, struct managed_win *w) {
|
||||
w->xinerama_scr = -1;
|
||||
|
||||
for (int i = 0; i < nscreens; i++) {
|
||||
auto e = pixman_region32_extents(&screens[i]);
|
||||
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);
|
||||
// TODO(absolutelynothelix): rename to x_update_win_(randr_?)monitor and move to
|
||||
// the x.c.
|
||||
void win_update_monitor(int nmons, region_t *mons, struct managed_win *mw) {
|
||||
mw->randr_monitor = -1;
|
||||
for (int i = 0; i < nmons; i++) {
|
||||
auto e = pixman_region32_extents(&mons[i]);
|
||||
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) {
|
||||
mw->randr_monitor = i;
|
||||
log_debug("Window %#010x (%s), %dx%d+%dx%d, is entirely on the "
|
||||
"monitor %d (%dx%d+%dx%d)",
|
||||
mw->base.id, mw->name, mw->g.x, mw->g.y, mw->widthb,
|
||||
mw->heightb, i, e->x1, e->y1, e->x2 - e->x1, e->y2 - e->y1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
log_debug("Window %#010x (%s), %dx%d+%dx%d, is not contained by any "
|
||||
"screen",
|
||||
w->base.id, w->name, w->g.x, w->g.y, w->g.width, w->g.height);
|
||||
log_debug("Window %#010x (%s), %dx%d+%dx%d, is not entirely on any monitor",
|
||||
mw->base.id, mw->name, mw->g.x, mw->g.y, mw->widthb, mw->heightb);
|
||||
}
|
||||
|
||||
/// Map an already registered window
|
||||
|
|
10
src/win.h
10
src/win.h
|
@ -123,8 +123,8 @@ struct managed_win {
|
|||
struct win_geometry g;
|
||||
/// Updated geometry received in events
|
||||
struct win_geometry pending_g;
|
||||
/// Xinerama screen this window is on.
|
||||
int xinerama_scr;
|
||||
/// X RandR monitor this window is on.
|
||||
int randr_monitor;
|
||||
/// Window visual pict format
|
||||
const xcb_render_pictforminfo_t *pictfmt;
|
||||
/// 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);
|
||||
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.
|
||||
*/
|
||||
|
|
38
src/x.c
38
src/x.c
|
@ -9,6 +9,7 @@
|
|||
#include <xcb/composite.h>
|
||||
#include <xcb/damage.h>
|
||||
#include <xcb/glx.h>
|
||||
#include <xcb/randr.h>
|
||||
#include <xcb/render.h>
|
||||
#include <xcb/sync.h>
|
||||
#include <xcb/xcb.h>
|
||||
|
@ -787,3 +788,40 @@ xcb_screen_t *x_screen_of_display(xcb_connection_t *c, int screen) {
|
|||
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
|
|
@ -64,8 +64,9 @@ shadow-exclude = [
|
|||
#
|
||||
# shadow-exclude-reg = ""
|
||||
|
||||
# Crop shadow of a window fully on a particular Xinerama screen to the screen.
|
||||
# xinerama-shadow-crop = false
|
||||
# Crop shadow of a window fully on a particular monitor to that monitor. This is
|
||||
# currently implemented using the X RandR extension.
|
||||
# crop-shadow-to-monitor = false
|
||||
|
||||
|
||||
#################################
|
||||
|
|
Loading…
Add table
Reference in a new issue