Files
ghostty-rs/crates/ghostty-apprt-gtk/src/class/inspector_window.rs
T
ddidderr 8bcb85a29a style: apply nightly rustfmt import grouping across the workspace
rustfmt.toml sets group_imports, imports_granularity and imports_layout,
which are nightly-only; agents formatted with stable rustfmt, which
ignored them. This is a formatting-only pass with `cargo +nightly fmt`.

Test Plan:
- cargo clippy --workspace --all-targets -- -D warnings
- cargo test --workspace
2026-10-12 05:03:37 +02:00

148 lines
4.8 KiB
Rust

//! Port of apprt/gtk/class/inspector_window.zig (`GhosttyInspectorWindow`).
//!
//! Window for displaying the Ghostty inspector.
use adw::{prelude::*, subclass::prelude::*};
use gtk::glib;
use super::{debug_warning::DebugWarning, inspector_widget::InspectorWidget, surface::Surface};
glib::wrapper! {
pub struct InspectorWindow(ObjectSubclass<imp::InspectorWindow>)
@extends adw::ApplicationWindow, gtk::ApplicationWindow, gtk::Window, gtk::Widget,
@implements gio::ActionGroup, gio::ActionMap, gtk::Accessible, gtk::Buildable,
gtk::ConstraintTarget, gtk::Native, gtk::Root, gtk::ShortcutManager;
}
use gtk::gio;
impl InspectorWindow {
pub fn new(surface: &Surface) -> Self {
crate::register_resources();
glib::Object::builder().property("surface", surface).build()
}
/// Present the window.
pub fn present_window(&self) {
self.present();
}
/// Queue a render of the embedded widget.
pub fn queue_render(&self) {
self.imp().inspector_widget.queue_render();
}
/// Debug aid: synthesize a left click in the inspector.
pub fn debug_click(&self, x: f64, y: f64) {
self.imp().inspector_widget.debug_click(x, y);
}
/// Debug aid: synthesize a mouse wheel scroll in the inspector.
pub fn debug_scroll(&self, x: f64, y: f64, dy: f64) {
self.imp().inspector_widget.debug_scroll(x, y, dy);
}
/// Debug aid: write the next rendered inspector frame to a PNG file.
pub fn debug_screenshot(&self, path: &str) {
self.imp().inspector_widget.debug_screenshot(path);
}
}
mod imp {
#[allow(clippy::wildcard_imports)]
use super::*;
#[derive(gtk::CompositeTemplate, glib::Properties, Default)]
#[properties(wrapper_type = super::InspectorWindow)]
#[template(resource = "/com/mitchellh/ghostty/ui/1.5/inspector-window.ui")]
pub struct InspectorWindow {
/// The surface that we are attached to.
#[property(get, set = Self::set_surface, nullable)]
pub surface: glib::WeakRef<Surface>,
/// The embedded inspector widget.
#[template_child]
pub inspector_widget: TemplateChild<InspectorWidget>,
/// Whether this is a debug build (shows the debug warning).
#[property(get = Self::get_debug, type = bool, name = "debug")]
_debug_prop: (),
}
impl InspectorWindow {
#[allow(clippy::unused_self)]
fn get_debug(&self) -> bool {
cfg!(debug_assertions)
}
#[allow(clippy::needless_pass_by_value)] // property setter signature
fn set_surface(&self, surface: Option<Surface>) {
self.surface.set(surface.as_ref());
}
}
#[glib::object_subclass]
impl ObjectSubclass for InspectorWindow {
const NAME: &'static str = "GhosttyInspectorWindow";
type Type = super::InspectorWindow;
type ParentType = adw::ApplicationWindow;
fn class_init(klass: &mut Self::Class) {
DebugWarning::ensure_type();
InspectorWidget::ensure_type();
klass.bind_template();
klass.bind_template_callbacks();
}
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
obj.init_template();
}
}
#[glib::derived_properties]
impl ObjectImpl for InspectorWindow {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
// Add our dev CSS class if we're in debug mode.
if cfg!(debug_assertions) {
obj.add_css_class("devel");
}
// Set our window icon. We can't set this in the blueprint file
// because its dependent on the build config.
obj.set_icon_name(Some(crate::APPLICATION_ID));
}
fn dispose(&self) {
// You MUST clear all weak refs in dispose, otherwise it causes
// memory corruption on dispose on the TARGET (weak referenced)
// object (Zig comment).
self.set_surface(None);
self.dispose_template();
}
}
impl WidgetImpl for InspectorWindow {}
impl WindowImpl for InspectorWindow {}
impl ApplicationWindowImpl for InspectorWindow {}
impl AdwApplicationWindowImpl for InspectorWindow {}
#[gtk::template_callbacks]
impl InspectorWindow {
/// `notify::surface` of the inspector widget: if the inspector's
/// surface went away, we destroy the window.
#[template_callback]
fn notify_inspector_surface(
inspector: &InspectorWidget,
_pspec: &glib::ParamSpec,
this: &super::InspectorWindow,
) {
if inspector.get_surface().is_none() {
this.destroy();
}
}
}
}