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_placement.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_placement.js')
| -rw-r--r-- | raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_placement.js | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_placement.js b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_placement.js new file mode 100644 index 0000000..cad36f9 --- /dev/null +++ b/raveos-gnome-theme/theme-data/extensions/installed/blur-my-shell@aunetx/components/popup/surface_placement.js @@ -0,0 +1,328 @@ +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; + +import { PopupBlurSurfaceGeometry, transform_to_actor_space } from './surface_geometry.js'; + +export const PopupBlurSurfacePlacement = class PopupBlurSurfacePlacement { + constructor(surface) { + this.surface = surface; + this.geometry = new PopupBlurSurfaceGeometry(); + this.clear(); + this.ready = false; + } + + get_surface_geometry() { + this.offscreen = false; + + const geometry = this.get_unclipped_surface_geometry(); + if (!this.has_valid_geometry(geometry)) + return null; + + const clipped_geometry = this.get_clipped_surface_geometry(geometry); + if (!this.has_valid_geometry(clipped_geometry)) + return null; + + const monitor_geometry = this.get_monitor_clipped_surface_geometry(clipped_geometry); + if (!this.has_valid_geometry(monitor_geometry)) { + this.offscreen = true; + return null; + } + + return monitor_geometry; + } + + get_unclipped_monitor_surface_geometry() { + this.offscreen = false; + + const geometry = this.get_unclipped_surface_geometry(); + if (!this.has_valid_geometry(geometry)) + return null; + + const monitor_geometry = this.get_monitor_clipped_surface_geometry(geometry); + if (!this.has_valid_geometry(monitor_geometry)) { + this.offscreen = true; + return null; + } + + return monitor_geometry; + } + + get_unclipped_surface_geometry() { + const geometry_actor = this.surface.get_geometry_actor(); + const geometry = this.geometry.get(geometry_actor, { + use_content: this.surface.should_use_content_geometry(), + use_margins: this.surface.should_use_margin_geometry(), + }); + if (!this.has_valid_geometry(geometry)) + return null; + + return this.create_surface_geometry( + geometry.x, + geometry.y, + geometry.width, + geometry.height + ); + } + + create_surface_geometry(target_x, target_y, width, height) { + const local_geometry = transform_to_actor_space(this.surface.parent, { + x: target_x, + y: target_y, + width, + height, + }); + if (!local_geometry) + return null; + + return { + target_x, + target_y, + target_width: width, + target_height: height, + x: Math.round(local_geometry.x), + y: Math.round(local_geometry.y), + width: Math.ceil(local_geometry.width), + height: Math.ceil(local_geometry.height), + }; + } + + get_clipped_surface_geometry(geometry) { + let clipped = { + x: geometry.target_x, + y: geometry.target_y, + width: geometry.target_width, + height: geometry.target_height, + }; + + let actor = this.surface.get_geometry_actor(); + while (actor && actor !== this.surface.parent) { + const clip = this.geometry.get_transformed_clip(actor); + if (clip) { + clipped = this.geometry.intersect(clipped, clip); + if (!this.has_valid_geometry(clipped)) + return null; + } + + actor = actor.get_parent(); + } + + return this.create_surface_geometry( + clipped.x, + clipped.y, + clipped.width, + clipped.height + ); + } + + get_monitor_clipped_surface_geometry(geometry) { + const rect = { + x: geometry.target_x, + y: geometry.target_y, + width: geometry.target_width, + height: geometry.target_height, + }; + const cached_monitor = this.get_cached_monitor(); + const match = cached_monitor + ? this.get_monitor_intersection(rect, cached_monitor.monitor, cached_monitor.index) + : this.find_best_monitor_intersection(rect); + + if (!match) + return null; + + this.monitor_index = match.monitor_index; + + const surface_geometry = this.create_surface_geometry( + rect.x, + rect.y, + rect.width, + rect.height + ); + surface_geometry.monitor_index = match.monitor_index; + return surface_geometry; + } + + get_cached_monitor() { + if (this.monitor_index === null) + return null; + + const monitor = Main.layoutManager.monitors?.[this.monitor_index]; + if (!monitor) { + this.monitor_index = null; + return null; + } + + return { monitor, index: this.monitor_index }; + } + + find_best_monitor_intersection(rect) { + let best_match = null; + let best_area = 0; + + (Main.layoutManager.monitors ?? []).forEach((monitor, index) => { + const match = this.get_monitor_intersection(rect, monitor, index); + if (!match) + return; + + const area = match.intersection.width * match.intersection.height; + if (area > best_area) { + best_match = match; + best_area = area; + } + }); + + return best_match; + } + + get_monitor_intersection(rect, monitor, monitor_index) { + const intersection = this.geometry.intersect(rect, monitor); + if (!this.has_valid_geometry(intersection)) + return null; + + return { + monitor_index, + intersection, + }; + } + + has_valid_geometry(geometry) { + return geometry?.width > 0 && geometry?.height > 0; + } + + keep_transition_visible(transition_state) { + if (this.offscreen || !this.ready || !this.has_cached_geometry() || !transition_state.running) + return false; + + const opacity = this.surface.update_opacity(transition_state); + if (opacity <= 0) + return false; + + if (this.surface.static_blur) { + this.surface.blur_actor?.show(); + } + this.surface.show_actors(); + return true; + } + + has_cached_geometry() { + return ( + this.x !== null + && this.y !== null + && this.width > 0 + && this.height > 0 + ); + } + + has_cached_surface_geometry() { + return ( + this.surface_x !== null + && this.surface_y !== null + && this.surface_width > 0 + && this.surface_height > 0 + ); + } + + has_surface_geometry_changed(geometry) { + return ( + this.has_valid_geometry(geometry) + && ( + !this.has_cached_surface_geometry() + || this.surface_x !== geometry.x + || this.surface_y !== geometry.y + || this.surface_width !== geometry.width + || this.surface_height !== geometry.height + ) + ); + } + + store_surface_geometry(geometry) { + this.surface_x = geometry.x; + this.surface_y = geometry.y; + this.surface_width = geometry.width; + this.surface_height = geometry.height; + } + + prepare_visible_geometry() { + if (this.ready) + return true; + + this.ready = true; + this.surface.opacity = 0; + this.surface.update_surface_opacity(0); + this.surface.hide_actors(); + this.surface.queue_update(); + return false; + } + + update_surface_geometry(geometry) { + if (this.surface.static_blur) { + if (!this.update_static_geometry( + geometry.target_x, + geometry.target_y, + geometry.target_width, + geometry.target_height + )) + return false; + } else { + if (!this.update_dynamic_geometry(geometry.x, geometry.y, geometry.width, geometry.height)) + return false; + } + + this.store_surface_geometry(geometry); + return true; + } + + update_dynamic_geometry(x, y, width, height) { + if (this.x !== x || this.y !== y) { + this.surface.blur_actor.set_position(x, y); + this.x = x; + this.y = y; + } + + if (this.width !== width || this.height !== height) { + this.surface.blur_actor.set_size(width, height); + this.width = width; + this.height = height; + } + + return true; + } + + update_static_geometry(target_x, target_y, width, height) { + const geometry = this.surface.static_actor.update_geometry( + target_x, + target_y, + width, + height, + this.monitor_index + ); + this.surface.sync_static_actor(); + + if (!geometry) { + this.surface.hide_actors(); + return false; + } + + this.x = geometry.x; + this.y = geometry.y; + this.width = geometry.width; + this.height = geometry.height; + return true; + } + + hide() { + this.ready = false; + this.clear(); + } + + clear() { + this.x = null; + this.y = null; + this.width = null; + this.height = null; + this.surface_x = null; + this.surface_y = null; + this.surface_width = null; + this.surface_height = null; + this.monitor_index = null; + this.offscreen = false; + } +}; |