2018-10-03 17:14:51 -04:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Copyright (c) 2011-2013, Christopher Jeffrey
|
|
|
|
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
|
2018-10-20 22:10:12 -04:00
|
|
|
#pragma once
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <xcb/damage.h>
|
2019-03-10 08:34:37 -04:00
|
|
|
#include <xcb/render.h>
|
|
|
|
#include <xcb/xcb.h>
|
2018-10-20 22:10:12 -04:00
|
|
|
|
2022-08-25 00:21:19 -04:00
|
|
|
#include <backend/backend.h>
|
|
|
|
|
2019-04-03 03:36:02 -04:00
|
|
|
#include "uthash_extra.h"
|
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
#include "c2.h"
|
2019-01-18 18:30:44 -05:00
|
|
|
#include "compiler.h"
|
2019-04-17 18:14:45 -04:00
|
|
|
#include "list.h"
|
2019-01-18 18:30:44 -05:00
|
|
|
#include "region.h"
|
2018-12-15 16:11:41 -05:00
|
|
|
#include "render.h"
|
2019-03-10 08:34:37 -04:00
|
|
|
#include "types.h"
|
2019-01-20 11:53:39 -05:00
|
|
|
#include "utils.h"
|
2019-08-09 20:44:27 -04:00
|
|
|
#include "win_defs.h"
|
2019-03-10 08:34:37 -04:00
|
|
|
#include "x.h"
|
2019-04-03 03:36:02 -04:00
|
|
|
|
2019-08-09 19:56:04 -04:00
|
|
|
struct backend_base;
|
2018-09-06 14:17:26 -04:00
|
|
|
typedef struct session session_t;
|
2018-10-20 22:10:12 -04:00
|
|
|
typedef struct _glx_texture glx_texture_t;
|
|
|
|
|
2019-04-17 18:14:45 -04:00
|
|
|
#define win_stack_foreach_managed(w, win_stack) \
|
2023-08-10 18:09:56 -04:00
|
|
|
list_foreach(struct managed_win, w, win_stack, \
|
|
|
|
base.stack_neighbour) if ((w)->base.managed)
|
2019-04-17 18:14:45 -04:00
|
|
|
|
|
|
|
#define win_stack_foreach_managed_safe(w, win_stack) \
|
|
|
|
list_foreach_safe(struct managed_win, w, win_stack, \
|
2023-08-10 18:09:56 -04:00
|
|
|
base.stack_neighbour) if ((w)->base.managed)
|
2019-04-17 18:14:45 -04:00
|
|
|
|
2018-10-28 19:09:25 -04:00
|
|
|
#ifdef CONFIG_OPENGL
|
2018-10-20 22:10:12 -04:00
|
|
|
// FIXME this type should be in opengl.h
|
|
|
|
// it is very unideal for it to be here
|
|
|
|
typedef struct {
|
2019-03-10 08:34:37 -04:00
|
|
|
/// Framebuffer used for blurring.
|
|
|
|
GLuint fbo;
|
|
|
|
/// Textures used for blurring.
|
|
|
|
GLuint textures[2];
|
|
|
|
/// Width of the textures.
|
|
|
|
int width;
|
|
|
|
/// Height of the textures.
|
|
|
|
int height;
|
2018-10-20 22:10:12 -04:00
|
|
|
} glx_blur_cache_t;
|
2018-10-28 19:09:25 -04:00
|
|
|
#endif
|
2018-10-20 22:10:12 -04:00
|
|
|
|
2019-04-04 04:24:35 -04:00
|
|
|
/// An entry in the window stack. May or may not correspond to a window we know about.
|
|
|
|
struct window_stack_entry {
|
2019-04-17 18:14:45 -04:00
|
|
|
struct list_node stack_neighbour;
|
2019-04-04 04:24:35 -04:00
|
|
|
/// The actual window correspond to this stack entry. NULL if we didn't know about
|
|
|
|
/// this window (e.g. an InputOnly window, or we haven't handled the window
|
|
|
|
/// creation yet)
|
|
|
|
struct win *win;
|
|
|
|
/// The window id. Might not be unique in the stack, because there might be
|
|
|
|
/// destroyed window still fading out in the stack.
|
|
|
|
xcb_window_t id;
|
|
|
|
};
|
|
|
|
|
2018-10-20 22:10:12 -04:00
|
|
|
/**
|
|
|
|
* About coordinate systems
|
|
|
|
*
|
|
|
|
* In general, X is the horizontal axis, Y is the vertical axis.
|
|
|
|
* X goes from left to right, Y goes downwards.
|
|
|
|
*
|
|
|
|
* Global: the origin is the top left corner of the Xorg screen.
|
2019-03-04 16:37:22 -05:00
|
|
|
* Local: the origin is the top left corner of the window, border is
|
|
|
|
* considered part of the window.
|
2018-10-20 22:10:12 -04:00
|
|
|
*/
|
|
|
|
|
2019-10-23 14:27:30 -04:00
|
|
|
/// Structure representing a top-level managed window.
|
2018-09-06 14:17:26 -04:00
|
|
|
typedef struct win win;
|
2018-10-20 22:10:12 -04:00
|
|
|
struct win {
|
2019-04-17 18:14:45 -04:00
|
|
|
UT_hash_handle hh;
|
2019-04-04 04:11:27 -04:00
|
|
|
struct list_node stack_neighbour;
|
2019-04-17 18:14:45 -04:00
|
|
|
/// ID of the top-level frame window.
|
|
|
|
xcb_window_t id;
|
|
|
|
/// Whether the window is destroyed from Xorg's perspective
|
|
|
|
bool destroyed : 1;
|
|
|
|
/// True if we just received CreateNotify, and haven't queried X for any info
|
|
|
|
/// about the window
|
|
|
|
bool is_new : 1;
|
|
|
|
/// True if this window is managed, i.e. this struct is actually a `managed_win`.
|
|
|
|
/// Always false if `is_new` is true.
|
|
|
|
bool managed : 1;
|
|
|
|
};
|
2020-12-03 18:53:10 -05:00
|
|
|
|
|
|
|
struct win_geometry {
|
|
|
|
int16_t x;
|
|
|
|
int16_t y;
|
|
|
|
uint16_t width;
|
|
|
|
uint16_t height;
|
|
|
|
uint16_t border_width;
|
|
|
|
};
|
|
|
|
|
2019-04-17 18:14:45 -04:00
|
|
|
struct managed_win {
|
|
|
|
struct win base;
|
2019-03-10 08:34:37 -04:00
|
|
|
/// backend data attached to this window. Only available when
|
|
|
|
/// `state` is not UNMAPPED
|
|
|
|
void *win_image;
|
|
|
|
void *shadow_image;
|
2022-08-24 02:35:49 -04:00
|
|
|
void *mask_image;
|
2019-03-10 08:34:37 -04:00
|
|
|
/// Pointer to the next higher window to paint.
|
2019-04-17 18:14:45 -04:00
|
|
|
struct managed_win *prev_trans;
|
2019-07-25 19:00:51 -04:00
|
|
|
/// Number of windows above this window
|
|
|
|
int stacking_rank;
|
2020-08-30 10:25:58 -04:00
|
|
|
// TODO(yshui) rethink reg_ignore
|
2019-03-10 08:34:37 -04:00
|
|
|
|
|
|
|
// Core members
|
|
|
|
/// The "mapped state" of this window, doesn't necessary
|
|
|
|
/// match X mapped state, because of fading.
|
|
|
|
winstate_t state;
|
|
|
|
/// Window attributes.
|
|
|
|
xcb_get_window_attributes_reply_t a;
|
2020-12-03 18:53:10 -05:00
|
|
|
/// The geometry of the window body, excluding the window border region.
|
|
|
|
struct win_geometry g;
|
|
|
|
/// Updated geometry received in events
|
|
|
|
struct win_geometry pending_g;
|
2023-01-13 06:27:45 -05:00
|
|
|
/// X RandR monitor this window is on.
|
|
|
|
int randr_monitor;
|
2019-07-13 07:29:39 -04:00
|
|
|
/// Window visual pict format
|
2019-03-10 08:34:37 -04:00
|
|
|
const xcb_render_pictforminfo_t *pictfmt;
|
2019-07-13 07:29:39 -04:00
|
|
|
/// Client window visual pict format
|
|
|
|
const xcb_render_pictforminfo_t *client_pictfmt;
|
2019-03-10 08:34:37 -04:00
|
|
|
/// Window painting mode.
|
|
|
|
winmode_t mode;
|
|
|
|
/// Whether the window has been damaged at least once.
|
|
|
|
bool ever_damaged;
|
|
|
|
/// Whether the window was damaged after last paint.
|
|
|
|
bool pixmap_damaged;
|
|
|
|
/// Damage of the window.
|
|
|
|
xcb_damage_damage_t damage;
|
|
|
|
/// Paint info of the window.
|
|
|
|
paint_t paint;
|
2020-10-22 10:48:11 -04:00
|
|
|
/// bitmap for properties which needs to be updated
|
|
|
|
uint64_t *stale_props;
|
|
|
|
/// number of uint64_ts that has been allocated for stale_props
|
2021-11-25 03:21:41 -05:00
|
|
|
size_t stale_props_capacity;
|
2019-03-10 08:34:37 -04:00
|
|
|
|
|
|
|
/// Bounding shape of the window. In local coordinates.
|
|
|
|
/// See above about coordinate systems.
|
|
|
|
region_t bounding_shape;
|
|
|
|
/// Window flags. Definitions above.
|
2020-04-06 15:52:32 -04:00
|
|
|
uint64_t flags;
|
2019-03-10 08:34:37 -04:00
|
|
|
/// The region of screen that will be obscured when windows above is painted,
|
|
|
|
/// in global coordinates.
|
|
|
|
/// We use this to reduce the pixels that needed to be paint when painting
|
|
|
|
/// this window and anything underneath. Depends on window frame
|
|
|
|
/// opacity state, window geometry, window mapped/unmapped state,
|
|
|
|
/// window mode of the windows above. DOES NOT INCLUDE the body of THIS WINDOW.
|
|
|
|
/// NULL means reg_ignore has not been calculated for this window.
|
|
|
|
rc_region_t *reg_ignore;
|
|
|
|
/// Whether the reg_ignore of all windows beneath this window are valid
|
|
|
|
bool reg_ignore_valid;
|
|
|
|
/// Cached width/height of the window including border.
|
|
|
|
int widthb, heightb;
|
|
|
|
/// Whether the window is bounding-shaped.
|
|
|
|
bool bounding_shaped;
|
|
|
|
/// Whether the window just have rounded corners.
|
|
|
|
bool rounded_corners;
|
|
|
|
/// Whether this window is to be painted.
|
|
|
|
bool to_paint;
|
|
|
|
/// Whether the window is painting excluded.
|
|
|
|
bool paint_excluded;
|
|
|
|
/// Whether the window is unredirect-if-possible excluded.
|
|
|
|
bool unredir_if_possible_excluded;
|
|
|
|
/// Whether this window is in open/close state.
|
|
|
|
bool in_openclose;
|
|
|
|
|
|
|
|
// Client window related members
|
|
|
|
/// ID of the top-level client window of the window.
|
|
|
|
xcb_window_t client_win;
|
|
|
|
/// Type of the window.
|
|
|
|
wintype_t window_type;
|
|
|
|
/// Whether it looks like a WM window. We consider a window WM window if
|
|
|
|
/// it does not have a decedent with WM_STATE and it is not override-
|
|
|
|
/// redirected itself.
|
|
|
|
bool wmwin;
|
|
|
|
/// Leader window ID of the window.
|
|
|
|
xcb_window_t leader;
|
|
|
|
/// Cached topmost window ID of the window.
|
|
|
|
xcb_window_t cache_leader;
|
|
|
|
|
|
|
|
// Focus-related members
|
|
|
|
/// Whether the window is to be considered focused.
|
|
|
|
bool focused;
|
|
|
|
/// Override value of window focus state. Set by D-Bus method calls.
|
|
|
|
switch_t focused_force;
|
|
|
|
|
|
|
|
// Blacklist related members
|
|
|
|
/// Name of the window.
|
|
|
|
char *name;
|
|
|
|
/// Window instance class of the window.
|
|
|
|
char *class_instance;
|
|
|
|
/// Window general class of the window.
|
|
|
|
char *class_general;
|
|
|
|
/// <code>WM_WINDOW_ROLE</code> value of the window.
|
|
|
|
char *role;
|
2024-02-14 13:38:20 -05:00
|
|
|
/// Whether the window sets the EWMH fullscreen property.
|
|
|
|
bool is_ewmh_fullscreen;
|
2024-02-14 13:54:04 -05:00
|
|
|
/// Whether the window should be considered fullscreen. Based on
|
|
|
|
/// `is_ewmh_fullscreen`, or the windows spatial relation with the
|
|
|
|
/// root window. Which one is used is determined by user configuration.
|
|
|
|
bool is_fullscreen;
|
2024-02-14 19:07:31 -05:00
|
|
|
/// Whether the window is the EWMH active window.
|
|
|
|
bool is_ewmh_focused;
|
2019-03-10 08:34:37 -04:00
|
|
|
|
|
|
|
// Opacity-related members
|
|
|
|
/// Current window opacity.
|
|
|
|
double opacity;
|
|
|
|
/// Target window opacity.
|
2019-07-26 18:40:30 -04:00
|
|
|
double opacity_target;
|
2019-12-20 14:17:38 -05:00
|
|
|
/// Previous window opacity.
|
|
|
|
double opacity_target_old;
|
2019-03-10 08:34:37 -04:00
|
|
|
/// true if window (or client window, for broken window managers
|
2020-10-12 12:34:51 -04:00
|
|
|
/// not transferring client window's _NET_WM_WINDOW_OPACITY value) has opacity
|
|
|
|
/// prop
|
2019-03-10 08:34:37 -04:00
|
|
|
bool has_opacity_prop;
|
|
|
|
/// Cached value of opacity window attribute.
|
|
|
|
opacity_t opacity_prop;
|
|
|
|
/// true if opacity is set by some rules
|
|
|
|
bool opacity_is_set;
|
2019-07-26 17:28:53 -04:00
|
|
|
/// Last window opacity value set by the rules.
|
2019-03-10 08:34:37 -04:00
|
|
|
double opacity_set;
|
|
|
|
|
2020-09-30 11:39:47 -04:00
|
|
|
/// Radius of rounded window corners
|
|
|
|
int corner_radius;
|
2020-04-02 01:56:42 -04:00
|
|
|
float border_col[4];
|
2020-09-30 11:39:47 -04:00
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
// Fading-related members
|
|
|
|
/// Override value of window fade state. Set by D-Bus method calls.
|
|
|
|
switch_t fade_force;
|
2020-10-22 21:08:34 -04:00
|
|
|
/// Whether fading is excluded by the rules. Calculated.
|
|
|
|
bool fade_excluded;
|
2019-03-10 08:34:37 -04:00
|
|
|
|
2021-12-01 17:51:57 -05:00
|
|
|
/// Whether transparent clipping is excluded by the rules.
|
|
|
|
bool transparent_clipping_excluded;
|
|
|
|
|
2019-03-10 08:34:37 -04:00
|
|
|
// Frame-opacity-related members
|
|
|
|
/// Current window frame opacity. Affected by window opacity.
|
|
|
|
double frame_opacity;
|
|
|
|
/// Frame extents. Acquired from _NET_FRAME_EXTENTS.
|
|
|
|
margin_t frame_extents;
|
|
|
|
|
|
|
|
// Shadow-related members
|
|
|
|
/// Whether a window has shadow. Calculated.
|
|
|
|
bool shadow;
|
|
|
|
/// Override value of window shadow state. Set by D-Bus method calls.
|
|
|
|
switch_t shadow_force;
|
|
|
|
/// Opacity of the shadow. Affected by window opacity and frame opacity.
|
|
|
|
double shadow_opacity;
|
2024-01-30 22:09:28 -05:00
|
|
|
/// X offset of shadow. Affected by command line argument.
|
2019-03-10 08:34:37 -04:00
|
|
|
int shadow_dx;
|
2024-01-30 22:09:28 -05:00
|
|
|
/// Y offset of shadow. Affected by command line argument.
|
2019-03-10 08:34:37 -04:00
|
|
|
int shadow_dy;
|
2024-01-30 22:09:28 -05:00
|
|
|
/// Width of shadow. Affected by window size and command line argument.
|
2019-03-10 08:34:37 -04:00
|
|
|
int shadow_width;
|
2024-01-30 22:09:28 -05:00
|
|
|
/// Height of shadow. Affected by window size and command line argument.
|
2019-03-10 08:34:37 -04:00
|
|
|
int shadow_height;
|
|
|
|
/// Picture to render shadow. Affected by window size.
|
|
|
|
paint_t shadow_paint;
|
|
|
|
/// The value of _COMPTON_SHADOW attribute of the window. Below 0 for
|
|
|
|
/// none.
|
2021-11-25 03:21:41 -05:00
|
|
|
long long prop_shadow;
|
2021-07-09 13:17:23 -04:00
|
|
|
/// Do not paint shadow over this window.
|
|
|
|
bool clip_shadow_above;
|
2019-03-10 08:34:37 -04:00
|
|
|
|
|
|
|
// Dim-related members
|
|
|
|
/// Whether the window is to be dimmed.
|
|
|
|
bool dim;
|
|
|
|
|
|
|
|
/// Whether to invert window color.
|
|
|
|
bool invert_color;
|
|
|
|
/// Override value of window color inversion state. Set by D-Bus method
|
|
|
|
/// calls.
|
|
|
|
switch_t invert_color_force;
|
|
|
|
|
|
|
|
/// Whether to blur window background.
|
|
|
|
bool blur_background;
|
2018-10-20 22:10:12 -04:00
|
|
|
|
2020-10-12 12:34:51 -04:00
|
|
|
/// The custom window shader to use when rendering.
|
|
|
|
struct shader_info *fg_shader;
|
|
|
|
|
2018-10-20 22:10:12 -04:00
|
|
|
#ifdef CONFIG_OPENGL
|
2019-03-10 08:34:37 -04:00
|
|
|
/// Textures and FBO background blur use.
|
|
|
|
glx_blur_cache_t glx_blur_cache;
|
2020-09-30 11:09:27 -04:00
|
|
|
/// Background texture of the window
|
|
|
|
glx_texture_t *glx_texture_bg;
|
2018-10-20 22:10:12 -04:00
|
|
|
#endif
|
|
|
|
};
|
2018-09-06 14:17:26 -04:00
|
|
|
|
2020-08-27 12:44:58 -04:00
|
|
|
/// Process pending updates/images flags on a window. Has to be called in X critical
|
|
|
|
/// section
|
|
|
|
void win_process_update_flags(session_t *ps, struct managed_win *w);
|
|
|
|
void win_process_image_flags(session_t *ps, struct managed_win *w);
|
2022-08-25 12:59:19 -04:00
|
|
|
bool win_bind_mask(struct backend_base *b, struct managed_win *w);
|
2019-09-28 19:04:09 -04:00
|
|
|
/// Bind a shadow to the window, with color `c` and shadow kernel `kernel`
|
|
|
|
bool win_bind_shadow(struct backend_base *b, struct managed_win *w, struct color c,
|
2022-08-25 00:21:19 -04:00
|
|
|
struct backend_shadow_context *kernel);
|
2019-09-19 11:59:36 -04:00
|
|
|
|
2019-09-19 20:23:44 -04:00
|
|
|
/// Start the unmap of a window. We cannot unmap immediately since we might need to fade
|
|
|
|
/// the window out.
|
2019-09-19 20:41:56 -04:00
|
|
|
void unmap_win_start(struct session *, struct managed_win *);
|
|
|
|
|
|
|
|
/// Start the mapping of a window. We cannot map immediately since we might need to fade
|
|
|
|
/// the window in.
|
|
|
|
void map_win_start(struct session *, struct managed_win *);
|
2019-09-19 20:23:44 -04:00
|
|
|
|
|
|
|
/// Start the destroying of a window. Windows cannot always be destroyed immediately
|
|
|
|
/// because of fading and such.
|
2019-09-19 20:41:56 -04:00
|
|
|
bool must_use destroy_win_start(session_t *ps, struct win *w);
|
2019-09-19 20:23:44 -04:00
|
|
|
|
2019-09-19 13:48:12 -04:00
|
|
|
/// Release images bound with a window, set the *_NONE flags on the window. Only to be
|
|
|
|
/// used when de-initializing the backend outside of win.c
|
|
|
|
void win_release_images(struct backend_base *base, struct managed_win *w);
|
2019-04-17 18:14:45 -04:00
|
|
|
winmode_t attr_pure win_calc_mode(const struct managed_win *w);
|
|
|
|
void win_set_shadow_force(session_t *ps, struct managed_win *w, switch_t val);
|
2019-07-24 21:27:02 -04:00
|
|
|
void win_set_fade_force(struct managed_win *w, switch_t val);
|
2019-04-17 18:14:45 -04:00
|
|
|
void win_set_focused_force(session_t *ps, struct managed_win *w, switch_t val);
|
|
|
|
void win_set_invert_color_force(session_t *ps, struct managed_win *w, switch_t val);
|
2018-09-06 14:17:26 -04:00
|
|
|
/**
|
|
|
|
* Set real focused state of a window.
|
|
|
|
*/
|
2019-05-24 18:13:24 -04:00
|
|
|
void win_set_focused(session_t *ps, struct managed_win *w);
|
2019-04-17 18:14:45 -04:00
|
|
|
bool attr_pure win_should_fade(session_t *ps, const struct managed_win *w);
|
|
|
|
void win_on_factor_change(session_t *ps, struct managed_win *w);
|
2019-02-21 09:08:08 -05:00
|
|
|
/**
|
|
|
|
* Update cache data in struct _win that depends on window size.
|
|
|
|
*/
|
2019-04-17 18:14:45 -04:00
|
|
|
void win_on_win_size_change(session_t *ps, struct managed_win *w);
|
|
|
|
void win_unmark_client(session_t *ps, struct managed_win *w);
|
2020-04-09 22:26:13 -04:00
|
|
|
void win_recheck_client(session_t *ps, struct managed_win *w);
|
2019-07-26 18:40:30 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate and return the opacity target of a window.
|
|
|
|
*
|
|
|
|
* The priority of opacity settings are:
|
|
|
|
*
|
|
|
|
* inactive_opacity_override (if set, and unfocused) > _NET_WM_WINDOW_OPACITY (if set) >
|
|
|
|
* opacity-rules (if matched) > window type default opacity > active/inactive opacity
|
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
* @param w struct _win object representing the window
|
|
|
|
*
|
|
|
|
* @return target opacity
|
|
|
|
*/
|
2020-04-05 08:07:06 -04:00
|
|
|
double attr_pure win_calc_opacity_target(session_t *ps, const struct managed_win *w);
|
2019-04-17 18:14:45 -04:00
|
|
|
bool attr_pure win_should_dim(session_t *ps, const struct managed_win *w);
|
2023-01-13 06:27:45 -05:00
|
|
|
|
2023-06-29 00:39:36 -04:00
|
|
|
void win_update_monitor(struct x_monitors *monitors, struct managed_win *mw);
|
2023-01-13 06:27:45 -05:00
|
|
|
|
2018-09-06 14:17:26 -04:00
|
|
|
/**
|
|
|
|
* Retrieve the bounding shape of a window.
|
|
|
|
*/
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-29 23:56:00 -04:00
|
|
|
// XXX was win_border_size
|
2019-04-17 18:14:45 -04:00
|
|
|
void win_update_bounding_shape(session_t *ps, struct managed_win *w);
|
2024-02-14 13:54:04 -05:00
|
|
|
/// Recheck if a window is fullscreen
|
|
|
|
void win_update_is_fullscreen(const session_t *ps, struct managed_win *w);
|
2020-01-18 13:00:35 -05:00
|
|
|
/**
|
|
|
|
* Check if a window has BYPASS_COMPOSITOR property set
|
|
|
|
*/
|
|
|
|
bool win_is_bypassing_compositor(const session_t *ps, const struct managed_win *w);
|
2018-09-06 14:17:26 -04:00
|
|
|
/**
|
2018-12-21 19:33:40 -05:00
|
|
|
* Get a rectangular region in global coordinates a window (and possibly
|
|
|
|
* its shadow) occupies.
|
2018-09-06 14:17:26 -04:00
|
|
|
*
|
|
|
|
* Note w->shadow and shadow geometry must be correct before calling this
|
|
|
|
* function.
|
|
|
|
*/
|
2019-04-17 18:14:45 -04:00
|
|
|
void win_extents(const struct managed_win *w, region_t *res);
|
|
|
|
region_t win_extents_by_val(const struct managed_win *w);
|
2018-09-06 14:17:26 -04:00
|
|
|
/**
|
|
|
|
* Add a window to damaged area.
|
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
* @param w struct _win element representing the window
|
|
|
|
*/
|
2019-04-17 18:14:45 -04:00
|
|
|
void add_damage_from_win(session_t *ps, const struct managed_win *w);
|
2018-09-06 14:17:26 -04:00
|
|
|
/**
|
|
|
|
* Get a rectangular region a window occupies, excluding frame and shadow.
|
2018-10-12 20:17:59 -04:00
|
|
|
*
|
|
|
|
* Return region in global coordinates.
|
2018-09-06 14:17:26 -04:00
|
|
|
*/
|
2019-04-17 18:14:45 -04:00
|
|
|
void win_get_region_noframe_local(const struct managed_win *w, region_t *);
|
2020-09-05 10:43:25 -04:00
|
|
|
void win_get_region_noframe_local_without_corners(const struct managed_win *w, region_t *);
|
2019-03-04 16:37:22 -05:00
|
|
|
|
|
|
|
/// Get the region for the frame of the window
|
2019-04-17 18:14:45 -04:00
|
|
|
void win_get_region_frame_local(const struct managed_win *w, region_t *res);
|
2019-03-04 16:37:22 -05:00
|
|
|
/// Get the region for the frame of the window, by value
|
2019-04-17 18:14:45 -04:00
|
|
|
region_t win_get_region_frame_local_by_val(const struct managed_win *w);
|
|
|
|
/// Insert a new window above window with id `below`, if there is no window, add to top
|
|
|
|
/// New window will be in unmapped state
|
|
|
|
struct win *add_win_above(session_t *ps, xcb_window_t id, xcb_window_t below);
|
|
|
|
/// Insert a new win entry at the top of the stack
|
|
|
|
struct win *add_win_top(session_t *ps, xcb_window_t id);
|
|
|
|
/// Query the Xorg for information about window `win`
|
|
|
|
/// `win` pointer might become invalid after this function returns
|
2019-04-19 16:10:38 -04:00
|
|
|
struct win *fill_win(session_t *ps, struct win *win);
|
2019-04-27 08:36:42 -04:00
|
|
|
/// Move window `w` to be right above `below`
|
|
|
|
void restack_above(session_t *ps, struct win *w, xcb_window_t below);
|
|
|
|
/// Move window `w` to the bottom of the stack
|
|
|
|
void restack_bottom(session_t *ps, struct win *w);
|
|
|
|
/// Move window `w` to the top of the stack
|
|
|
|
void restack_top(session_t *ps, struct win *w);
|
2019-02-20 21:29:06 -05:00
|
|
|
|
2018-12-15 16:11:41 -05:00
|
|
|
/**
|
|
|
|
* Execute fade callback of a window if fading finished.
|
|
|
|
*/
|
2019-09-16 17:14:34 -04:00
|
|
|
bool must_use win_check_fade_finished(session_t *ps, struct managed_win *w);
|
2018-12-15 16:11:41 -05:00
|
|
|
|
2018-11-03 18:38:18 -04:00
|
|
|
// Stop receiving events (except ConfigureNotify, XXX why?) from a window
|
2019-04-17 18:14:45 -04:00
|
|
|
void win_ev_stop(session_t *ps, const struct win *w);
|
2018-11-03 18:38:18 -04:00
|
|
|
|
2019-02-20 21:12:07 -05:00
|
|
|
/// Skip the current in progress fading of window,
|
|
|
|
/// transition the window straight to its end state
|
2019-09-16 17:14:34 -04:00
|
|
|
///
|
|
|
|
/// @return whether the window is destroyed and freed
|
|
|
|
bool must_use win_skip_fading(session_t *ps, struct managed_win *w);
|
2019-04-17 18:14:45 -04:00
|
|
|
/**
|
|
|
|
* Find a managed window from window id in window linked list of the session.
|
|
|
|
*/
|
|
|
|
struct managed_win *find_managed_win(session_t *ps, xcb_window_t id);
|
|
|
|
struct win *find_win(session_t *ps, xcb_window_t id);
|
|
|
|
struct managed_win *find_toplevel(session_t *ps, xcb_window_t id);
|
|
|
|
/**
|
2020-04-05 16:20:58 -04:00
|
|
|
* Find a managed window that is, or is a parent of `wid`.
|
2019-04-17 18:14:45 -04:00
|
|
|
*
|
|
|
|
* @param ps current session
|
|
|
|
* @param wid window ID
|
|
|
|
* @return struct _win object of the found window, NULL if not found
|
|
|
|
*/
|
2020-04-05 16:20:58 -04:00
|
|
|
struct managed_win *find_managed_window_or_parent(session_t *ps, xcb_window_t wid);
|
2019-04-17 18:14:45 -04:00
|
|
|
|
|
|
|
/**
|
2020-03-17 15:19:13 -04:00
|
|
|
* Check if a window is focused, without using any focus rules or forced focus settings
|
2019-04-17 18:14:45 -04:00
|
|
|
*/
|
2024-02-14 19:07:31 -05:00
|
|
|
bool attr_pure win_is_focused_raw(const struct managed_win *w);
|
2018-09-29 14:07:39 -04:00
|
|
|
|
|
|
|
/// check if window has ARGB visual
|
2019-04-17 18:14:45 -04:00
|
|
|
bool attr_pure win_has_alpha(const struct managed_win *w);
|
Convert XfixesRegion to pixman region
Re-did the painting logic, and document it.
It is unclear to me what is the previous painting logic. But the current
one is basically this:
1. Go through all windows top to bottom, and put visible windows (not
unmapped, opacity > 0, etc) into a linked list, from bottom to top
2. Accumulate a region of ignore on each window, which is basically the
region of screen that is obscured by all the windows above current
one.
3. Paint all the visible windows from bottom to top. Subtract the region
of ignore from the painting region. If we need to paint shadow, we
subtract the body of the window from the shadow painting region too,
because we don't want shadow behind the window.
4. region of ignore is invalidated when window stack change, an
window on top moved or changed shape, when window changed between
opaque and transparent, etc.
Notes:
It is unclear whether all the different shapes of a window (extents,
noframe, border, bounding shape, etc) are calculated correctly or not.
It is unclear if window shape related events are handled correctly or
not. Need more testing.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
2018-09-29 23:56:00 -04:00
|
|
|
|
|
|
|
/// check if reg_ignore_valid is true for all windows above us
|
2019-04-17 18:14:45 -04:00
|
|
|
bool attr_pure win_is_region_ignore_valid(session_t *ps, const struct managed_win *w);
|
|
|
|
|
2019-09-19 20:59:25 -04:00
|
|
|
/// Whether a given window is mapped on the X server side
|
|
|
|
bool win_is_mapped_in_x(const struct managed_win *w);
|
|
|
|
|
2019-04-17 18:14:45 -04:00
|
|
|
// Find the managed window immediately below `w` in the window stack
|
|
|
|
struct managed_win *attr_pure win_stack_find_next_managed(const session_t *ps,
|
|
|
|
const struct list_node *w);
|
2020-04-06 15:52:32 -04:00
|
|
|
/// Set flags on a window. Some sanity checks are performed
|
|
|
|
void win_set_flags(struct managed_win *w, uint64_t flags);
|
|
|
|
/// Clear flags on a window. Some sanity checks are performed
|
|
|
|
void win_clear_flags(struct managed_win *w, uint64_t flags);
|
|
|
|
/// Returns true if any of the flags in `flags` is set
|
|
|
|
bool win_check_flags_any(struct managed_win *w, uint64_t flags);
|
|
|
|
/// Returns true if all of the flags in `flags` are set
|
|
|
|
bool win_check_flags_all(struct managed_win *w, uint64_t flags);
|
2020-11-27 00:34:54 -05:00
|
|
|
/// Mark properties as stale for a window
|
|
|
|
void win_set_properties_stale(struct managed_win *w, const xcb_atom_t *prop, int nprops);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2018-10-12 20:17:59 -04:00
|
|
|
|
2019-02-09 10:50:40 -05:00
|
|
|
/// Free all resources in a struct win
|
2019-04-17 18:14:45 -04:00
|
|
|
void free_win_res(session_t *ps, struct managed_win *w);
|
2019-02-09 10:50:40 -05:00
|
|
|
|
2020-09-05 10:43:25 -04:00
|
|
|
static inline void win_region_remove_corners(const struct managed_win *w, region_t *res) {
|
|
|
|
region_t corners;
|
|
|
|
pixman_region32_init_rects(
|
|
|
|
&corners,
|
|
|
|
(rect_t[]){
|
|
|
|
{.x1 = 0, .y1 = 0, .x2 = w->corner_radius, .y2 = w->corner_radius},
|
|
|
|
{.x1 = 0, .y1 = w->heightb - w->corner_radius, .x2 = w->corner_radius, .y2 = w->heightb},
|
|
|
|
{.x1 = w->widthb - w->corner_radius, .y1 = 0, .x2 = w->widthb, .y2 = w->corner_radius},
|
|
|
|
{.x1 = w->widthb - w->corner_radius,
|
|
|
|
.y1 = w->heightb - w->corner_radius,
|
|
|
|
.x2 = w->widthb,
|
|
|
|
.y2 = w->heightb},
|
|
|
|
},
|
|
|
|
4);
|
|
|
|
pixman_region32_subtract(res, res, &corners);
|
|
|
|
pixman_region32_fini(&corners);
|
|
|
|
}
|
|
|
|
|
2020-10-22 23:34:05 -04:00
|
|
|
static inline region_t attr_unused win_get_bounding_shape_global_by_val(struct managed_win *w) {
|
2019-03-10 08:34:37 -04:00
|
|
|
region_t ret;
|
|
|
|
pixman_region32_init(&ret);
|
|
|
|
pixman_region32_copy(&ret, &w->bounding_shape);
|
|
|
|
pixman_region32_translate(&ret, w->g.x, w->g.y);
|
|
|
|
return ret;
|
2018-10-12 20:17:59 -04:00
|
|
|
}
|
2018-10-20 22:10:12 -04:00
|
|
|
|
2020-09-05 10:43:25 -04:00
|
|
|
static inline region_t
|
|
|
|
win_get_bounding_shape_global_without_corners_by_val(struct managed_win *w) {
|
|
|
|
region_t ret;
|
|
|
|
pixman_region32_init(&ret);
|
|
|
|
pixman_region32_copy(&ret, &w->bounding_shape);
|
|
|
|
win_region_remove_corners(w, &ret);
|
|
|
|
pixman_region32_translate(&ret, w->g.x, w->g.y);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-10-20 22:10:12 -04:00
|
|
|
/**
|
|
|
|
* Calculate the extents of the frame of the given window based on EWMH
|
|
|
|
* _NET_FRAME_EXTENTS and the X window border width.
|
|
|
|
*/
|
2020-10-22 23:34:05 -04:00
|
|
|
static inline margin_t attr_pure attr_unused win_calc_frame_extents(const struct managed_win *w) {
|
2019-03-10 08:34:37 -04:00
|
|
|
margin_t result = w->frame_extents;
|
2019-03-30 05:07:21 -04:00
|
|
|
result.top = max2(result.top, w->g.border_width);
|
|
|
|
result.left = max2(result.left, w->g.border_width);
|
|
|
|
result.bottom = max2(result.bottom, w->g.border_width);
|
|
|
|
result.right = max2(result.right, w->g.border_width);
|
2019-03-10 08:34:37 -04:00
|
|
|
return result;
|
2018-10-20 22:10:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether a window has WM frames.
|
|
|
|
*/
|
2020-10-22 23:34:05 -04:00
|
|
|
static inline bool attr_pure attr_unused win_has_frame(const struct managed_win *w) {
|
2019-03-10 08:34:37 -04:00
|
|
|
return w->g.border_width || w->frame_extents.top || w->frame_extents.left ||
|
|
|
|
w->frame_extents.right || w->frame_extents.bottom;
|
2018-10-20 22:10:12 -04:00
|
|
|
}
|