diff options
| author | Nippy <nippy@Nippy-Mac-mini.local> | 2026-10-09 17:23:53 +0200 |
|---|---|---|
| committer | Nippy <nippy@Nippy-Mac-mini.local> | 2026-10-09 17:23:53 +0200 |
| commit | 9d5be1660d8f74038ebed3d74fdbc809e43787ae (patch) | |
| tree | 4cb46c3765be87ca4c5219f2f714425d7dfddb56 /raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_geometry.js | |
| parent | deb4b8a9c407832c35100a643bd7a592589c9679 (diff) | |
| download | RaveOS-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.js | 291 |
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, + }; + } +}; |