mirror of https://github.com/yshui/picom.git
Add prototype picom-inspect
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
4954c11aae
commit
6a01cec68a
4
src/c2.c
4
src/c2.c
|
@ -1518,6 +1518,10 @@ static const char *c2_condition_to_str2(c2_ptr_t ptr) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
const char *c2_lptr_to_str(const c2_lptr_t *ptr) {
|
||||
return c2_condition_to_str2(ptr->ptr);
|
||||
}
|
||||
|
||||
/// Get the list of target number values from a struct c2_property_value
|
||||
static inline const int64_t *
|
||||
c2_values_get_number_targets(const struct c2_property_value *values, int index, size_t *n) {
|
||||
|
|
3
src/c2.h
3
src/c2.h
|
@ -57,6 +57,9 @@ typedef bool (*c2_list_foreach_cb_t)(const c2_lptr_t *cond, void *data);
|
|||
bool c2_list_foreach(const c2_lptr_t *list, c2_list_foreach_cb_t cb, void *data);
|
||||
/// Return user data stored in a condition.
|
||||
void *c2_list_get_data(const c2_lptr_t *condlist);
|
||||
/// Convert a c2_lptr_t to string. The returned string is only valid until the
|
||||
/// next call to this function, and should not be freed.
|
||||
const char *c2_lptr_to_str(const c2_lptr_t *);
|
||||
|
||||
/**
|
||||
* Destroy a condition list.
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright (c) 2024 Yuxuan Shui <yshuiv7@gmail.com>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <xcb/shape.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_event.h>
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
#include "inspect.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "c2.h"
|
||||
#include "common.h"
|
||||
#include "config.h"
|
||||
#include "err.h"
|
||||
#include "log.h"
|
||||
#include "options.h"
|
||||
#include "utils.h"
|
||||
#include "win.h"
|
||||
#include "win_defs.h"
|
||||
#include "x.h"
|
||||
|
||||
static struct managed_win *
|
||||
setup_window(struct x_connection *c, struct atom *atoms, struct options *options,
|
||||
struct c2_state *state, xcb_window_t target) {
|
||||
// Pretend we are the compositor, and build up the window state
|
||||
struct managed_win *w = ccalloc(1, struct managed_win);
|
||||
w->state = WSTATE_MAPPED;
|
||||
w->base.id = target;
|
||||
w->client_win = win_get_client_window(c, atoms, w);
|
||||
win_update_wintype(c, atoms, w);
|
||||
win_update_frame_extents(c, atoms, w, w->client_win, options->frame_opacity);
|
||||
// TODO(yshui) get leader
|
||||
win_update_name(c, atoms, w);
|
||||
win_update_class(c, atoms, w);
|
||||
win_update_role(c, atoms, w);
|
||||
|
||||
auto geometry_reply = XCB_AWAIT(xcb_get_geometry, c->c, w->base.id);
|
||||
w->g = (struct win_geometry){
|
||||
.x = geometry_reply->x,
|
||||
.y = geometry_reply->y,
|
||||
.width = geometry_reply->width,
|
||||
.height = geometry_reply->height,
|
||||
};
|
||||
free(geometry_reply);
|
||||
|
||||
auto shape_info = xcb_get_extension_data(c->c, &xcb_shape_id);
|
||||
win_on_win_size_change(w, options->shadow_offset_x, options->shadow_offset_y,
|
||||
options->shadow_radius);
|
||||
win_update_bounding_shape(c, w, shape_info->present, options->detect_rounded_corners);
|
||||
win_update_prop_fullscreen(c, atoms, w);
|
||||
|
||||
// Determine if the window is focused
|
||||
xcb_window_t wid = XCB_NONE;
|
||||
if (options->use_ewmh_active_win) {
|
||||
wid_get_prop_window(c, c->screen_info->root, atoms->a_NET_ACTIVE_WINDOW);
|
||||
} else {
|
||||
// Determine the currently focused window so we can apply appropriate
|
||||
// opacity on it
|
||||
xcb_get_input_focus_reply_t *reply =
|
||||
xcb_get_input_focus_reply(c->c, xcb_get_input_focus(c->c), NULL);
|
||||
|
||||
if (reply) {
|
||||
wid = reply->focus;
|
||||
free(reply);
|
||||
}
|
||||
}
|
||||
if (wid == w->base.id || wid == w->client_win) {
|
||||
w->focused = true;
|
||||
}
|
||||
|
||||
auto attributes_reply = XCB_AWAIT(xcb_get_window_attributes, c->c, w->base.id);
|
||||
w->a = *attributes_reply;
|
||||
w->pictfmt = x_get_pictform_for_visual(c, w->a.visual);
|
||||
free(attributes_reply);
|
||||
|
||||
c2_window_state_init(state, &w->c2_state);
|
||||
c2_window_state_update(state, &w->c2_state, c->c, w->client_win, w->base.id);
|
||||
return w;
|
||||
}
|
||||
|
||||
xcb_window_t select_window(struct x_connection *c) {
|
||||
xcb_font_t font = x_new_id(c);
|
||||
xcb_cursor_t cursor = x_new_id(c);
|
||||
const char font_name[] = "cursor";
|
||||
static const uint16_t CROSSHAIR_CHAR = 34;
|
||||
XCB_AWAIT_VOID(xcb_open_font, c->c, font, sizeof(font_name) - 1, font_name);
|
||||
XCB_AWAIT_VOID(xcb_create_glyph_cursor, c->c, cursor, font, font, CROSSHAIR_CHAR,
|
||||
CROSSHAIR_CHAR + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff);
|
||||
auto grab_reply = XCB_AWAIT(
|
||||
xcb_grab_pointer, c->c, false, c->screen_info->root,
|
||||
XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_SYNC,
|
||||
XCB_GRAB_MODE_ASYNC, c->screen_info->root, cursor, XCB_CURRENT_TIME);
|
||||
if (grab_reply->status != XCB_GRAB_STATUS_SUCCESS) {
|
||||
log_fatal("Failed to grab pointer");
|
||||
return 1;
|
||||
}
|
||||
free(grab_reply);
|
||||
|
||||
// Let the user pick a window by clicking on it, mostly stolen from
|
||||
// xprop
|
||||
xcb_window_t target = XCB_NONE;
|
||||
int buttons_pressed = 0;
|
||||
while ((target == XCB_NONE) || (buttons_pressed > 0)) {
|
||||
XCB_AWAIT_VOID(xcb_allow_events, c->c, XCB_ALLOW_ASYNC_POINTER,
|
||||
XCB_CURRENT_TIME);
|
||||
xcb_generic_event_t *ev = xcb_wait_for_event(c->c);
|
||||
if (!ev) {
|
||||
log_fatal("Connection to X server lost");
|
||||
return 1;
|
||||
}
|
||||
switch (XCB_EVENT_RESPONSE_TYPE(ev)) {
|
||||
case XCB_BUTTON_PRESS: {
|
||||
xcb_button_press_event_t *e = (xcb_button_press_event_t *)ev;
|
||||
if (target == XCB_NONE) {
|
||||
target = e->child;
|
||||
if (target == XCB_NONE) {
|
||||
target = e->root;
|
||||
}
|
||||
}
|
||||
buttons_pressed++;
|
||||
break;
|
||||
}
|
||||
case XCB_BUTTON_RELEASE: {
|
||||
if (buttons_pressed > 0) {
|
||||
buttons_pressed--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
free(ev);
|
||||
}
|
||||
XCB_AWAIT_VOID(xcb_ungrab_pointer, c->c, XCB_CURRENT_TIME);
|
||||
return target;
|
||||
}
|
||||
|
||||
struct c2_match_state {
|
||||
struct c2_state *state;
|
||||
struct managed_win *w;
|
||||
bool print_value;
|
||||
};
|
||||
|
||||
bool c2_match_once_and_log(const c2_lptr_t *cond, void *data) {
|
||||
struct c2_match_state *state = data;
|
||||
void *rule_data = NULL;
|
||||
printf(" %s ... ", c2_lptr_to_str(cond));
|
||||
bool matched = c2_match(state->state, state->w, cond, &rule_data);
|
||||
printf("%s", matched ? "\033[1;32mmatched\033[0m" : "not matched");
|
||||
if (state->print_value && matched) {
|
||||
printf("/%lu", (unsigned long)(intptr_t)rule_data);
|
||||
state->print_value = false;
|
||||
}
|
||||
printf("\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
#define BOLD(str) "\033[1m" str "\033[0m"
|
||||
|
||||
int inspect_main(int argc, char **argv, const char *config_file) {
|
||||
auto stderr_logger = stderr_logger_new();
|
||||
if (stderr_logger) {
|
||||
log_add_target_tls(stderr_logger);
|
||||
}
|
||||
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
if (!dpy) {
|
||||
log_fatal("Can't open display");
|
||||
return 1;
|
||||
}
|
||||
struct x_connection c;
|
||||
x_connection_init(&c, dpy);
|
||||
|
||||
xcb_prefetch_extension_data(c.c, &xcb_shape_id);
|
||||
|
||||
char *config_file_to_free = NULL;
|
||||
struct options options;
|
||||
bool shadow_enabled, fading_enable, hasneg;
|
||||
win_option_mask_t winopt_mask[NUM_WINTYPES] = {0};
|
||||
config_file = config_file_to_free = parse_config(
|
||||
&options, config_file, &shadow_enabled, &fading_enable, &hasneg, winopt_mask);
|
||||
|
||||
if (IS_ERR(config_file_to_free)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Parse all of the rest command line options
|
||||
if (!get_cfg(&options, argc, argv, shadow_enabled, fading_enable, hasneg, winopt_mask)) {
|
||||
log_fatal("Failed to get configuration, usually mean you have specified "
|
||||
"invalid options.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto atoms attr_unused = init_atoms(c.c);
|
||||
auto state = c2_state_new(atoms);
|
||||
options_postprocess_c2_lists(state, &c, &options);
|
||||
|
||||
auto target = select_window(&c);
|
||||
log_info("Target window: %#x", target);
|
||||
auto w = setup_window(&c, atoms, &options, state, target);
|
||||
struct c2_match_state match_state = {
|
||||
.state = state,
|
||||
.w = w,
|
||||
};
|
||||
printf("Checking " BOLD("transparent-clipping-exclude") ":\n");
|
||||
c2_list_foreach(options.transparent_clipping_blacklist, c2_match_once_and_log,
|
||||
&match_state);
|
||||
printf("Checking " BOLD("shadow-exclude") ":\n");
|
||||
c2_list_foreach(options.shadow_blacklist, c2_match_once_and_log, &match_state);
|
||||
printf("Checking " BOLD("fade-exclude") ":\n");
|
||||
c2_list_foreach(options.fade_blacklist, c2_match_once_and_log, &match_state);
|
||||
printf("Checking " BOLD("clip-shadow-above") ":\n");
|
||||
c2_list_foreach(options.shadow_clip_list, c2_match_once_and_log, &match_state);
|
||||
printf("Checking " BOLD("focus-exclude") ":\n");
|
||||
c2_list_foreach(options.focus_blacklist, c2_match_once_and_log, &match_state);
|
||||
printf("Checking " BOLD("invert-color-include") ":\n");
|
||||
c2_list_foreach(options.invert_color_list, c2_match_once_and_log, &match_state);
|
||||
printf("Checking " BOLD("blur-background-exclude") ":\n");
|
||||
c2_list_foreach(options.blur_background_blacklist, c2_match_once_and_log, &match_state);
|
||||
printf("Checking " BOLD("unredir-if-possible-exclude") ":\n");
|
||||
c2_list_foreach(options.unredir_if_possible_blacklist, c2_match_once_and_log,
|
||||
&match_state);
|
||||
printf("Checking " BOLD("rounded-corners-exclude") ":\n");
|
||||
c2_list_foreach(options.rounded_corners_blacklist, c2_match_once_and_log, &match_state);
|
||||
|
||||
match_state.print_value = true;
|
||||
printf("Checking " BOLD("opacity-rule") ":\n");
|
||||
c2_list_foreach(options.opacity_rules, c2_match_once_and_log, &match_state);
|
||||
printf("Checking " BOLD("corner-radius-rule") ":\n");
|
||||
c2_list_foreach(options.corner_radius_rules, c2_match_once_and_log, &match_state);
|
||||
|
||||
printf("\nHere are some rule(s) that match this window:\n");
|
||||
if (w->name != NULL) {
|
||||
printf(" name = '%s'\n", w->name);
|
||||
}
|
||||
if (w->class_instance != NULL) {
|
||||
printf(" class_i = '%s'\n", w->class_instance);
|
||||
}
|
||||
if (w->class_general != NULL) {
|
||||
printf(" class_g = '%s'\n", w->class_general);
|
||||
}
|
||||
if (w->role != NULL) {
|
||||
printf(" role = '%s'\n", w->role);
|
||||
}
|
||||
if (w->window_type != WINTYPE_UNKNOWN) {
|
||||
printf(" window_type = '%s'\n", WINTYPES[w->window_type].name);
|
||||
}
|
||||
printf(" %sfullscreen\n", w->is_fullscreen ? "" : "! ");
|
||||
if (w->bounding_shaped) {
|
||||
printf(" bounding_shaped\n");
|
||||
}
|
||||
printf(" border_width = %d\n", w->g.border_width);
|
||||
|
||||
pixman_region32_fini(&w->bounding_shape);
|
||||
free(w->name);
|
||||
free(w->class_instance);
|
||||
free(w->class_general);
|
||||
free(w->role);
|
||||
c2_window_state_destroy(state, &w->c2_state);
|
||||
free(w);
|
||||
|
||||
log_deinit_tls();
|
||||
free(config_file_to_free);
|
||||
c2_state_free(state);
|
||||
destroy_atoms(atoms);
|
||||
options_destroy(&options);
|
||||
XCloseDisplay(c.dpy);
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright (c) 2024 Yuxuan Shui <yshuiv7@gmail.com>
|
||||
|
||||
#pragma once
|
||||
#include <xcb/xcb.h>
|
||||
#include "compiler.h"
|
||||
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
int inspect_main(int argc, char **argv, const char *config_file);
|
||||
#else
|
||||
static inline int inspect_main(int argc attr_unused, char **argv attr_unused,
|
||||
const char *config_file attr_unused) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -44,7 +44,7 @@ if get_option('config_file')
|
|||
deps += [dependency('libconfig', version: '>=1.4', required: true)]
|
||||
|
||||
cflags += ['-DCONFIG_LIBCONFIG']
|
||||
srcs += [ 'config_libconfig.c' ]
|
||||
srcs += [ 'config_libconfig.c', 'inspect.c' ]
|
||||
endif
|
||||
if get_option('regex')
|
||||
pcre = dependency('libpcre2-8', required: true)
|
||||
|
@ -96,6 +96,10 @@ if get_option('unittest')
|
|||
test('picom unittest', picom, args: [ '--unittest' ])
|
||||
endif
|
||||
|
||||
if get_option('config_file')
|
||||
install_symlink('picom-inspect', install_dir: 'bin', pointing_to: 'picom')
|
||||
endif
|
||||
|
||||
if cc.has_argument('-fsanitize=fuzzer')
|
||||
c2_fuzz = executable('c2_fuzz', srcs + ['fuzzer/c2.c'],
|
||||
c_args: cflags + ['-fsanitize=fuzzer', '-DCONFIG_FUZZER'],
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <libgen.h>
|
||||
#include <math.h>
|
||||
#include <sched.h>
|
||||
#include <stddef.h>
|
||||
|
@ -44,6 +45,7 @@
|
|||
#include "compiler.h"
|
||||
#include "config.h"
|
||||
#include "err.h"
|
||||
#include "inspect.h"
|
||||
#include "kernel.h"
|
||||
#include "picom.h"
|
||||
#include "win_defs.h"
|
||||
|
@ -2781,6 +2783,11 @@ int PICOM_MAIN(int argc, char **argv) {
|
|||
return exit_code;
|
||||
}
|
||||
|
||||
char *exe_name = basename(argv[0]);
|
||||
if (strcmp(exe_name, "picom-inspect") == 0) {
|
||||
return inspect_main(argc, argv, config_file);
|
||||
}
|
||||
|
||||
int pfds[2];
|
||||
if (need_fork) {
|
||||
if (pipe2(pfds, O_CLOEXEC)) {
|
||||
|
|
42
src/win.c
42
src/win.c
|
@ -53,28 +53,12 @@ static const int WIN_GET_LEADER_MAX_RECURSION = 20;
|
|||
static const int ROUNDED_PIXELS = 1;
|
||||
static const double ROUNDED_PERCENT = 0.05;
|
||||
|
||||
/**
|
||||
* Retrieve the <code>WM_CLASS</code> of a window and update its
|
||||
* <code>win</code> structure.
|
||||
*/
|
||||
static bool
|
||||
win_update_class(struct x_connection *c, struct atom *atoms, struct managed_win *w);
|
||||
static int win_update_role(struct x_connection *c, struct atom *atoms, struct managed_win *w);
|
||||
static bool
|
||||
win_update_wintype(struct x_connection *c, struct atom *atoms, struct managed_win *w);
|
||||
static int win_update_name(struct x_connection *c, struct atom *atoms, struct managed_win *w);
|
||||
/**
|
||||
* Reread opacity property of a window.
|
||||
*/
|
||||
static void win_update_opacity_prop(struct x_connection *c, struct atom *atoms,
|
||||
struct managed_win *w, bool detect_client_opacity);
|
||||
static void win_update_opacity_target(session_t *ps, struct managed_win *w);
|
||||
/**
|
||||
* Retrieve frame extents from a window.
|
||||
*/
|
||||
static void
|
||||
win_update_frame_extents(struct x_connection *c, struct atom *atoms,
|
||||
struct managed_win *w, xcb_window_t client, double frame_opacity);
|
||||
static void win_update_prop_shadow_raw(struct x_connection *c, struct atom *atoms,
|
||||
struct managed_win *w);
|
||||
static bool
|
||||
|
@ -90,13 +74,7 @@ bool win_update_prop_fullscreen(struct x_connection *c, const struct atom *atoms
|
|||
static xcb_window_t
|
||||
win_get_leader_property(struct x_connection *c, struct atom *atoms, xcb_window_t wid,
|
||||
bool detect_transient, bool detect_client_leader);
|
||||
static xcb_window_t win_get_client_window(struct x_connection *c, struct atom *atoms,
|
||||
const struct managed_win *w);
|
||||
static void win_mark_client(session_t *ps, struct managed_win *w, xcb_window_t client);
|
||||
static void win_on_win_size_change(struct managed_win *w, int shadow_offset_x,
|
||||
int shadow_offset_y, int shadow_radius);
|
||||
static void win_update_bounding_shape(struct x_connection *c, struct managed_win *w,
|
||||
bool shape_exists, bool detect_rounded_corners);
|
||||
|
||||
/// Generate a "no corners" region function, from a function that returns the
|
||||
/// region via a region_t pointer argument. Corners of the window will be removed from
|
||||
|
@ -735,7 +713,7 @@ int win_update_name(struct x_connection *c, struct atom *atoms, struct managed_w
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int win_update_role(struct x_connection *c, struct atom *atoms, struct managed_win *w) {
|
||||
int win_update_role(struct x_connection *c, struct atom *atoms, struct managed_win *w) {
|
||||
char **strlst = NULL;
|
||||
int nstr = 0;
|
||||
|
||||
|
@ -1319,8 +1297,8 @@ void win_on_factor_change(session_t *ps, struct managed_win *w) {
|
|||
/**
|
||||
* Update cache data in struct _win that depends on window size.
|
||||
*/
|
||||
static void win_on_win_size_change(struct managed_win *w, int shadow_offset_x,
|
||||
int shadow_offset_y, int shadow_radius) {
|
||||
void win_on_win_size_change(struct managed_win *w, int shadow_offset_x,
|
||||
int shadow_offset_y, int shadow_radius) {
|
||||
log_trace("Window %#010x (%s) size changed, was %dx%d, now %dx%d", w->base.id,
|
||||
w->name, w->widthb, w->heightb, w->g.width + w->g.border_width * 2,
|
||||
w->g.height + w->g.border_width * 2);
|
||||
|
@ -1341,8 +1319,7 @@ static void win_on_win_size_change(struct managed_win *w, int shadow_offset_x,
|
|||
/**
|
||||
* Update window type.
|
||||
*/
|
||||
static bool
|
||||
win_update_wintype(struct x_connection *c, struct atom *atoms, struct managed_win *w) {
|
||||
bool win_update_wintype(struct x_connection *c, struct atom *atoms, struct managed_win *w) {
|
||||
const wintype_t wtype_old = w->window_type;
|
||||
|
||||
// Detect window type here
|
||||
|
@ -1478,8 +1455,8 @@ find_client_win(struct x_connection *c, struct atom *atoms, xcb_window_t w) {
|
|||
* @param ps current session
|
||||
* @param w struct _win of the parent window
|
||||
*/
|
||||
static xcb_window_t win_get_client_window(struct x_connection *c, struct atom *atoms,
|
||||
const struct managed_win *w) {
|
||||
xcb_window_t win_get_client_window(struct x_connection *c, struct atom *atoms,
|
||||
const struct managed_win *w) {
|
||||
// Always recursively look for a window with WM_STATE, as Fluxbox
|
||||
// sets override-redirect flags on all frame windows.
|
||||
xcb_window_t cw = find_client_win(c, atoms, w->base.id);
|
||||
|
@ -1844,8 +1821,7 @@ static xcb_window_t win_get_leader_raw(session_t *ps, struct managed_win *w, int
|
|||
* Retrieve the <code>WM_CLASS</code> of a window and update its
|
||||
* <code>win</code> structure.
|
||||
*/
|
||||
static bool
|
||||
win_update_class(struct x_connection *c, struct atom *atoms, struct managed_win *w) {
|
||||
bool win_update_class(struct x_connection *c, struct atom *atoms, struct managed_win *w) {
|
||||
char **strlst = NULL;
|
||||
int nstr = 0;
|
||||
|
||||
|
@ -1972,8 +1948,8 @@ gen_by_val(win_extents);
|
|||
*
|
||||
* Mark the window shape as updated
|
||||
*/
|
||||
static void win_update_bounding_shape(struct x_connection *c, struct managed_win *w,
|
||||
bool shape_exists, bool detect_rounded_corners) {
|
||||
void win_update_bounding_shape(struct x_connection *c, struct managed_win *w,
|
||||
bool shape_exists, bool detect_rounded_corners) {
|
||||
// We don't handle property updates of non-visible windows until they are
|
||||
// mapped.
|
||||
assert(w->state != WSTATE_UNMAPPED && w->state != WSTATE_DESTROYING &&
|
||||
|
|
23
src/win.h
23
src/win.h
|
@ -457,6 +457,29 @@ bool win_check_flags_all(struct managed_win *w, uint64_t flags);
|
|||
/// Mark properties as stale for a window
|
||||
void win_set_properties_stale(struct managed_win *w, const xcb_atom_t *prop, int nprops);
|
||||
|
||||
xcb_window_t win_get_client_window(struct x_connection *c, struct atom *atoms,
|
||||
const struct managed_win *w);
|
||||
bool win_update_wintype(struct x_connection *c, struct atom *atoms, struct managed_win *w);
|
||||
/**
|
||||
* Retrieve frame extents from a window.
|
||||
*/
|
||||
void win_update_frame_extents(struct x_connection *c, struct atom *atoms,
|
||||
struct managed_win *w, xcb_window_t client,
|
||||
double frame_opacity);
|
||||
/**
|
||||
* Retrieve the <code>WM_CLASS</code> of a window and update its
|
||||
* <code>win</code> structure.
|
||||
*/
|
||||
bool win_update_class(struct x_connection *c, struct atom *atoms, struct managed_win *w);
|
||||
int win_update_role(struct x_connection *c, struct atom *atoms, struct managed_win *w);
|
||||
int win_update_name(struct x_connection *c, struct atom *atoms, struct managed_win *w);
|
||||
void win_on_win_size_change(struct managed_win *w, int shadow_offset_x,
|
||||
int shadow_offset_y, int shadow_radius);
|
||||
void win_update_bounding_shape(struct x_connection *c, struct managed_win *w,
|
||||
bool shape_exists, bool detect_rounded_corners);
|
||||
bool win_update_prop_fullscreen(struct x_connection *c, const struct atom *atoms,
|
||||
struct managed_win *w);
|
||||
|
||||
static inline attr_unused void win_set_property_stale(struct managed_win *w, xcb_atom_t prop) {
|
||||
return win_set_properties_stale(w, (xcb_atom_t[]){prop}, 1);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue