summaryrefslogtreecommitdiff
path: root/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js
diff options
context:
space:
mode:
authorNippy <nippy@Nippy-Mac-mini.local>2026-10-09 17:23:53 +0200
committerNippy <nippy@Nippy-Mac-mini.local>2026-10-09 17:23:53 +0200
commit9d5be1660d8f74038ebed3d74fdbc809e43787ae (patch)
tree4cb46c3765be87ca4c5219f2f714425d7dfddb56 /raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js
parentdeb4b8a9c407832c35100a643bd7a592589c9679 (diff)
downloadRaveOS-PKGBUILD-9d5be1660d8f74038ebed3d74fdbc809e43787ae.tar.gz
RaveOS-PKGBUILD-9d5be1660d8f74038ebed3d74fdbc809e43787ae.zip
gnome fix
Diffstat (limited to 'raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js')
-rw-r--r--raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js291
1 files changed, 291 insertions, 0 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js
new file mode 100644
index 0000000..84832d9
--- /dev/null
+++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js
@@ -0,0 +1,291 @@
+import St from 'gi://St';
+
+export function transform_to_actor_space(actor, { x, y, width, height }) {
+ if (!actor)
+ return null;
+ const [actor_x, actor_y] = actor.get_transformed_position();
+ const [actor_width, actor_height] = actor.get_size();
+ const [transformed_width, transformed_height] = actor.get_transformed_size();
+ const scale_x = actor_width > 0 ? transformed_width / actor_width : 1;
+ const scale_y = actor_height > 0 ? transformed_height / actor_height : 1;
+
+ return {
+ x: (x - actor_x) / scale_x,
+ y: (y - actor_y) / scale_y,
+ width: width / scale_x,
+ height: height / scale_y,
+ };
+}
+
+export const PopupBlurSurfaceGeometry = class PopupBlurSurfaceGeometry {
+ get(actor, { use_content = true, use_margins = true } = {}) {
+ const actor_geometry = this.get_transformed_actor(actor);
+ if (!this.has_valid_geometry(actor_geometry))
+ return actor_geometry;
+
+ const margin_geometry = use_margins
+ ? this.get_margin_adjusted(actor, actor_geometry)
+ : actor_geometry;
+ if (!use_content)
+ return margin_geometry;
+
+ const content_geometry = this.get_transformed_content(actor, margin_geometry);
+
+ if (!this.should_use_content(margin_geometry, content_geometry))
+ return margin_geometry;
+
+ return content_geometry;
+ }
+
+ get_transformed_actor(actor) {
+ const extents = actor.get_transformed_extents();
+ const top_left = extents?.get_top_left();
+ const bottom_right = extents?.get_bottom_right();
+
+ if (top_left && bottom_right) {
+ return {
+ x: top_left.x,
+ y: top_left.y,
+ width: bottom_right.x - top_left.x,
+ height: bottom_right.y - top_left.y,
+ };
+ }
+
+ if (!actor)
+ return null;
+ const [x, y] = actor.get_transformed_position();
+ const [width, height] = actor.get_transformed_size();
+ return { x, y, width, height };
+ }
+
+ get_transformed_clip(actor) {
+ if (!actor?.has_clip)
+ return null;
+
+ const [clip_x, clip_y, clip_width, clip_height] = actor.get_clip();
+ if (clip_width <= 0 || clip_height <= 0)
+ return null;
+
+ const [actor_x, actor_y] = actor.get_transformed_position();
+ const [actor_width, actor_height] = actor.get_transformed_size();
+ const scale_x = this.get_actor_scale(actor, actor_width, 'width');
+ const scale_y = this.get_actor_scale(actor, actor_height, 'height');
+
+ return {
+ x: actor_x + clip_x * scale_x,
+ y: actor_y + clip_y * scale_y,
+ width: clip_width * scale_x,
+ height: clip_height * scale_y,
+ };
+ }
+
+ get_margin_adjusted(actor, geometry) {
+ const margins = this.get_margins(actor);
+ if (!margins)
+ return geometry;
+
+ const scale_x = this.get_actor_scale(actor, geometry.width, 'width');
+ const scale_y = this.get_actor_scale(actor, geometry.height, 'height');
+
+ return this.shrink(geometry,
+ margins.top * scale_y,
+ margins.right * scale_x,
+ margins.bottom * scale_y,
+ margins.left * scale_x
+ ) ?? geometry;
+ }
+
+ get_transformed_content(actor, boundary) {
+ const children = this.get_transformed_children(actor);
+ if (!this.has_valid_geometry(children))
+ return null;
+
+ const insets = this.get_paint_insets(actor, boundary);
+ const geometry = this.inflate(
+ children,
+ insets.top,
+ insets.right,
+ insets.bottom,
+ insets.left
+ );
+
+ return this.intersect(geometry, boundary);
+ }
+
+ get_transformed_children(actor) {
+ let geometry = null;
+
+ this.get_children(actor).forEach(child => {
+ if (!this.is_visible(child))
+ return;
+
+ const child_geometry = this.get_transformed_actor(child);
+ if (!this.has_valid_geometry(child_geometry))
+ return;
+
+ geometry = this.union(geometry, child_geometry);
+ });
+
+ return geometry;
+ }
+
+ get_margins(actor) {
+ const margins = {
+ top: this.get_margin(actor, 'top', St.Side.TOP),
+ right: this.get_margin(actor, 'right', St.Side.RIGHT),
+ bottom: this.get_margin(actor, 'bottom', St.Side.BOTTOM),
+ left: this.get_margin(actor, 'left', St.Side.LEFT),
+ };
+
+ return Object.values(margins).some(margin => margin > 0) ? margins : null;
+ }
+
+ get_margin(actor, side_name, side) {
+ const property_names = [
+ `margin_${side_name}`,
+ `margin${side_name[0].toUpperCase()}${side_name.slice(1)}`,
+ ];
+
+ for (const property of property_names) {
+ const value = actor[property];
+ if (typeof value === 'number')
+ return value;
+ }
+
+ const getter = actor[`get_margin_${side_name}`];
+ if (getter) {
+ const value = getter.call(actor);
+ if (typeof value === 'number')
+ return value;
+ }
+
+ try {
+ const theme_node = actor.get_theme_node();
+ if (!theme_node?.get_margin)
+ return 0;
+
+ return theme_node.get_margin(side);
+ } catch (e) {
+ // get_theme_node() may throw when actor is not yet mapped to a stage
+ return 0;
+ }
+ }
+
+ get_paint_insets(actor, geometry) {
+ const scale_x = this.get_actor_scale(actor, geometry.width, 'width');
+ const scale_y = this.get_actor_scale(actor, geometry.height, 'height');
+
+ return {
+ top: this.get_inset(actor, St.Side.TOP) * scale_y,
+ right: this.get_inset(actor, St.Side.RIGHT) * scale_x,
+ bottom: this.get_inset(actor, St.Side.BOTTOM) * scale_y,
+ left: this.get_inset(actor, St.Side.LEFT) * scale_x,
+ };
+ }
+
+ get_inset(actor, side) {
+ try {
+ const theme_node = actor.get_theme_node();
+ if (!theme_node)
+ return 0;
+
+ let inset = 0;
+ if (theme_node.get_padding)
+ inset += theme_node.get_padding(side);
+ if (theme_node.get_border_width)
+ inset += theme_node.get_border_width(side);
+ return inset;
+ } catch (e) {
+ // get_theme_node() may throw when actor is not yet mapped to a stage
+ return 0;
+ }
+ }
+
+ get_actor_scale(actor, transformed_size, property) {
+ const size = actor ? (actor[property] ?? (actor[`get_${property}`] ? actor[`get_${property}`]() : 0)) : 0;
+ return size > 0 ? transformed_size / size : 1;
+ }
+
+ should_use_content(outer, content) {
+ if (!this.has_valid_geometry(content))
+ return false;
+
+ if (
+ content.width > outer.width + 1
+ || content.height > outer.height + 1
+ )
+ return false;
+
+ return outer.width - content.width > 2 || outer.height - content.height > 2;
+ }
+
+ is_visible(actor) {
+ return actor?.visible && actor.mapped;
+ }
+
+ get_children(actor) {
+ return actor ? actor.get_children() : [];
+ }
+
+ has_valid_geometry(geometry) {
+ return geometry?.width > 0 && geometry?.height > 0;
+ }
+
+ shrink(geometry, top, right, bottom, left) {
+ const width = geometry.width - left - right;
+ const height = geometry.height - top - bottom;
+
+ if (width <= 0 || height <= 0)
+ return null;
+
+ return {
+ x: geometry.x + left,
+ y: geometry.y + top,
+ width,
+ height,
+ };
+ }
+
+ inflate(geometry, top, right, bottom, left) {
+ return {
+ x: geometry.x - left,
+ y: geometry.y - top,
+ width: geometry.width + left + right,
+ height: geometry.height + top + bottom,
+ };
+ }
+
+ intersect(a, b) {
+ const x1 = Math.max(a.x, b.x);
+ const y1 = Math.max(a.y, b.y);
+ const x2 = Math.min(a.x + a.width, b.x + b.width);
+ const y2 = Math.min(a.y + a.height, b.y + b.height);
+
+ if (x2 <= x1 || y2 <= y1)
+ return null;
+
+ return {
+ x: x1,
+ y: y1,
+ width: x2 - x1,
+ height: y2 - y1,
+ };
+ }
+
+ union(a, b) {
+ if (!a)
+ return b;
+
+ const x1 = Math.min(a.x, b.x);
+ const y1 = Math.min(a.y, b.y);
+ const x2 = Math.max(a.x + a.width, b.x + b.width);
+ const y2 = Math.max(a.y + a.height, b.y + b.height);
+
+ return {
+ x: x1,
+ y: y1,
+ width: x2 - x1,
+ height: y2 - y1,
+ };
+ }
+};