aboutsummaryrefslogtreecommitdiff
path: root/src/win.h
diff options
context:
space:
mode:
authorallusive-dev <[email protected]>2023-09-19 17:47:33 +1000
committerallusive-dev <[email protected]>2023-09-19 17:47:33 +1000
commita93aba600b1c5d019b680b9f4ff3fa85d5d43a60 (patch)
tree77f8152222655657472a70e0bfa413a0495dd555 /src/win.h
parentreset (diff)
downloadcompfy-a93aba600b1c5d019b680b9f4ff3fa85d5d43a60.tar.xz
compfy-a93aba600b1c5d019b680b9f4ff3fa85d5d43a60.zip
Fixed broken files/code and other errors
Diffstat (limited to 'src/win.h')
-rw-r--r--src/win.h531
1 files changed, 531 insertions, 0 deletions
diff --git a/src/win.h b/src/win.h
new file mode 100644
index 0000000..d3a74f9
--- /dev/null
+++ b/src/win.h
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2011-2013, Christopher Jeffrey
+// Copyright (c) 2013 Richard Grenville <[email protected]>
+#pragma once
+#include <stdbool.h>
+#include <xcb/damage.h>
+#include <xcb/render.h>
+#include <xcb/xcb.h>
+
+#include "uthash_extra.h"
+
+// FIXME shouldn't need this
+#ifdef CONFIG_OPENGL
+#include <GL/gl.h>
+#endif
+
+#include "c2.h"
+#include "compiler.h"
+#include "list.h"
+#include "region.h"
+#include "render.h"
+#include "types.h"
+#include "utils.h"
+#include "win_defs.h"
+#include "x.h"
+
+struct backend_base;
+typedef struct session session_t;
+typedef struct _glx_texture glx_texture_t;
+
+#define win_stack_foreach_managed(w, win_stack) \
+ list_foreach(struct managed_win, w, win_stack, base.stack_neighbour) if (w->base.managed)
+
+#define win_stack_foreach_managed_safe(w, win_stack) \
+ list_foreach_safe(struct managed_win, w, win_stack, \
+ base.stack_neighbour) if (w->base.managed)
+
+#ifdef CONFIG_OPENGL
+// FIXME this type should be in opengl.h
+// it is very unideal for it to be here
+typedef struct {
+ /// 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;
+} glx_blur_cache_t;
+#endif
+
+/// An entry in the window stack. May or may not correspond to a window we know about.
+struct window_stack_entry {
+ struct list_node stack_neighbour;
+ /// 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;
+};
+
+/**
+ * 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.
+ * Local: the origin is the top left corner of the window, border is
+ * considered part of the window.
+ */
+
+/// Structure representing a top-level managed window.
+typedef struct win win;
+struct win {
+ UT_hash_handle hh;
+ struct list_node stack_neighbour;
+ /// 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;
+};
+
+struct win_geometry {
+ int16_t x;
+ int16_t y;
+ uint16_t width;
+ uint16_t height;
+ uint16_t border_width;
+};
+
+struct managed_win {
+ struct win base;
+ /// backend data attached to this window. Only available when
+ /// `state` is not UNMAPPED
+ void *win_image;
+ void *old_win_image; // Old window image for interpolating window contents during animations
+ void *shadow_image;
+ /// Pointer to the next higher window to paint.
+ struct managed_win *prev_trans;
+ /// Number of windows above this window
+ int stacking_rank;
+ // TODO(yshui) rethink reg_ignore
+
+ // 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;
+ /// 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;
+ /// Xinerama screen this window is on.
+ int xinerama_scr;
+ /// Window visual pict format
+ const xcb_render_pictforminfo_t *pictfmt;
+ /// Client window visual pict format
+ const xcb_render_pictforminfo_t *client_pictfmt;
+ /// 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;
+ /// bitmap for properties which needs to be updated
+ uint64_t *stale_props;
+ /// number of uint64_ts that has been allocated for stale_props
+ uint64_t stale_props_capacity;
+
+ /// Bounding shape of the window. In local coordinates.
+ /// See above about coordinate systems.
+ region_t bounding_shape;
+ /// Window flags. Definitions above.
+ uint64_t flags;
+ /// 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;
+ /// Whether this window was transient when animated on open
+ bool animation_transient;
+ /// Current position and destination, for animation
+ double animation_center_x, animation_center_y;
+ double animation_dest_center_x, animation_dest_center_y;
+ double animation_w, animation_h;
+ double animation_dest_w, animation_dest_h;
+ /// Spring animation velocity
+ double animation_velocity_x, animation_velocity_y;
+ double animation_velocity_w, animation_velocity_h;
+ /// Track animation progress; goes from 0 to 1
+ double animation_progress;
+ /// Inverse of the window distance at the start of animation, for
+ /// tracking animation progress
+ double animation_inv_og_distance;
+
+ // 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;
+
+ // Opacity-related members
+ /// Current window opacity.
+ double opacity;
+ /// Target window opacity.
+ double opacity_target;
+ /// Previous window opacity.
+ double opacity_target_old;
+ /// true if window (or client window, for broken window managers
+ /// not transferring client window's _NET_WM_OPACITY value) has opacity prop
+ 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;
+ /// Last window opacity value set by the rules.
+ double opacity_set;
+
+ /// Radius of rounded window corners
+ int corner_radius;
+ float border_col[4];
+
+ // Fading-related members
+ /// Override value of window fade state. Set by D-Bus method calls.
+ switch_t fade_force;
+ /// Whether fading is excluded by the rules. Calculated.
+ bool fade_excluded;
+
+ // 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;
+ /// X offset of shadow. Affected by commandline argument.
+ int shadow_dx;
+ /// Y offset of shadow. Affected by commandline argument.
+ int shadow_dy;
+ /// Width of shadow. Affected by window size and commandline argument.
+ int shadow_width;
+ /// Height of shadow. Affected by window size and commandline argument.
+ 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.
+ long prop_shadow;
+ /// Do not paint shadow over this window.
+ bool clip_shadow_above;
+
+ // 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;
+
+#ifdef CONFIG_OPENGL
+ /// Textures and FBO background blur use.
+ glx_blur_cache_t glx_blur_cache;
+ /// Background texture of the window
+ glx_texture_t *glx_texture_bg;
+#endif
+};
+
+/// 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);
+/// 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,
+ struct conv *kernel);
+
+/// Start the unmap of a window. We cannot unmap immediately since we might need to fade
+/// the window out.
+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 *);
+
+/// Start the destroying of a window. Windows cannot always be destroyed immediately
+/// because of fading and such.
+bool must_use destroy_win_start(session_t *ps, struct win *w);
+
+/// 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);
+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);
+void win_set_fade_force(struct managed_win *w, switch_t val);
+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);
+/**
+ * Set real focused state of a window.
+ */
+void win_set_focused(session_t *ps, struct managed_win *w);
+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);
+/**
+ * Update cache data in struct _win that depends on window size.
+ */
+void win_on_win_size_change(session_t *ps, struct managed_win *w);
+void win_unmark_client(session_t *ps, struct managed_win *w);
+void win_recheck_client(session_t *ps, struct managed_win *w);
+
+/**
+ * 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
+ */
+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);
+/**
+ * Retrieve the bounding shape of a window.
+ */
+// XXX was win_border_size
+void win_update_bounding_shape(session_t *ps, struct managed_win *w);
+/**
+ * Check if a window has BYPASS_COMPOSITOR property set
+ */
+bool win_is_bypassing_compositor(const session_t *ps, const struct managed_win *w);
+/**
+ * Get a rectangular region in global coordinates a window (and possibly
+ * its shadow) occupies.
+ *
+ * Note w->shadow and shadow geometry must be correct before calling this
+ * function.
+ */
+void win_extents(const struct managed_win *w, region_t *res);
+region_t win_extents_by_val(const struct managed_win *w);
+/**
+ * Add a window to damaged area.
+ *
+ * @param ps current session
+ * @param w struct _win element representing the window
+ */
+void add_damage_from_win(session_t *ps, const struct managed_win *w);
+/**
+ * Get a rectangular region a window occupies, excluding frame and shadow.
+ *
+ * Return region in global coordinates.
+ */
+void win_get_region_noframe_local(const struct managed_win *w, region_t *);
+void win_get_region_noframe_local_without_corners(const struct managed_win *w, region_t *);
+
+/// Get the region for the frame of the window
+void win_get_region_frame_local(const struct managed_win *w, region_t *res);
+/// Get the region for the frame of the window, by value
+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
+struct win *fill_win(session_t *ps, struct win *win);
+/// 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);
+
+/**
+ * Execute fade callback of a window if fading finished.
+ */
+bool must_use win_check_fade_finished(session_t *ps, struct managed_win *w);
+
+// Stop receiving events (except ConfigureNotify, XXX why?) from a window
+void win_ev_stop(session_t *ps, const struct win *w);
+
+/// Skip the current in progress fading of window,
+/// transition the window straight to its end state
+///
+/// @return whether the window is destroyed and freed
+bool must_use win_skip_fading(session_t *ps, struct managed_win *w);
+/**
+ * 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);
+/**
+ * Find a managed window that is, or is a parent of `wid`.
+ *
+ * @param ps current session
+ * @param wid window ID
+ * @return struct _win object of the found window, NULL if not found
+ */
+struct managed_win *find_managed_window_or_parent(session_t *ps, xcb_window_t wid);
+
+/**
+ * Check if a window is a fullscreen window.
+ *
+ * It's not using w->border_size for performance measures.
+ */
+bool attr_pure win_is_fullscreen(const session_t *ps, const struct managed_win *w);
+
+/**
+ * Check if a window is focused, without using any focus rules or forced focus settings
+ */
+bool attr_pure win_is_focused_raw(const session_t *ps, const struct managed_win *w);
+
+/// check if window has ARGB visual
+bool attr_pure win_has_alpha(const struct managed_win *w);
+
+/// check if reg_ignore_valid is true for all windows above us
+bool attr_pure win_is_region_ignore_valid(session_t *ps, const struct managed_win *w);
+
+/// Whether a given window is mapped on the X server side
+bool win_is_mapped_in_x(const struct managed_win *w);
+
+// 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);
+/// 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);
+/// 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);
+}
+
+/// Free all resources in a struct win
+void free_win_res(session_t *ps, struct managed_win *w);
+
+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);
+}
+
+static inline region_t attr_unused win_get_bounding_shape_global_by_val(struct managed_win *w) {
+ 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;
+}
+
+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;
+}
+
+/**
+ * Calculate the extents of the frame of the given window based on EWMH
+ * _NET_FRAME_EXTENTS and the X window border width.
+ */
+static inline margin_t attr_pure attr_unused win_calc_frame_extents(const struct managed_win *w) {
+ margin_t result = w->frame_extents;
+ 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);
+ return result;
+}
+
+/**
+ * Check whether a window has WM frames.
+ */
+static inline bool attr_pure attr_unused win_has_frame(const struct managed_win *w) {
+ return w->g.border_width || w->frame_extents.top || w->frame_extents.left ||
+ w->frame_extents.right || w->frame_extents.bottom;
+}