How Sniffnet Manages Window Position and Size in Iced
Sniffnet centralizes window geometry management in the ConfigWindow struct, which sanitizes dimensions on startup, updates in real-time through native window event subscriptions, and persists across sessions via serde serialization.
Sniffnet, the open-source network traffic analyzer built with Rust and the Iced GUI framework, implements explicit window property management to ensure user preferences survive application restarts. Through a dedicated configuration pipeline, the application tracks window position, size, and scale factors rather than deferring to window manager defaults. This technical examination reveals how Sniffnet handles window geometry from initialization through runtime updates to its specialized thumbnail mode.
The ConfigWindow Struct: Centralized Geometry Storage
All window property state in Sniffnet resides in the ConfigWindow struct, defined in src/gui/types/config_window.rs. This type encapsulates three critical geometry fields: size (stored as SizeTuple), position (as PositionTuple), and thumbnail_position (also PositionTuple) for the compact overlay view.
The struct exposes getter methods—size(), position(), and thumbnail_position()—that return strongly-typed Iced geometry objects (iced::Size and iced::Point). For mutations, ConfigWindow provides set_size(), set_position(), and set_thumbnail_position(), all of which accept raw pixel values and the current scale_factor to store logical coordinates. Additionally, the scale_size() method rescales stored dimensions proportionally when the UI scale changes, and sanitize() clamps values to sensible minimums and screen bounds.
Initialization and Sanitization Workflow
When Sniffnet launches, the global Conf structure loads the existing configuration via Conf::load() in src/gui/types/conf.rs. Immediately after deserialization, the implementation calls conf.window.sanitize(scale_factor) to validate the stored geometry against current display constraints, preventing off-screen windows or negative dimensions.
The startup routine in src/main.rs (lines 73-76) then constructs the initial iced::window::Settings using these sanitized values:
let size = conf.window.size(); // Width/Height
let position = Position::Specific(conf.window.position()); // (x, y)
This approach ensures that the application window restores to its last known valid state, accounting for display changes or corrupted configuration files that might otherwise place the window outside accessible screen real estate.
Runtime Window Event Handling
During execution, the Sniffer struct subscribes to native window events through Iced's subscription system. In src/gui/sniffer.rs, specific handlers process Moved and Resized events to keep the configuration cache synchronized with actual window state.
When the user moves the window, window_moved updates the appropriate position field based on whether the application is in thumbnail mode:
fn window_moved(&mut self, x: f32, y: f32) {
let sf = self.conf.settings.scale_factor;
if self.thumbnail {
self.conf.window.set_thumbnail_position(x, y, sf);
} else {
self.conf.window.set_position(x, y, sf);
}
}
Similarly, window_resized handles dimension changes (lines 622-644), though it ignores size updates while in thumbnail mode since the thumbnail uses fixed dimensions:
fn window_resized(&mut self, w: f32, h: f32) -> Task<Message> {
if !self.thumbnail {
let sf = self.conf.settings.scale_factor;
self.conf.window.set_size(w, h, sf);
} else if !self.timing_events.was_just_thumbnail_enter() {
return self.toggle_thumbnail(true);
}
Task::none()
}
Scale Factor Adaptation
Sniffnet maintains geometry independently of the UI scale factor to support high-DPI displays. When users adjust the scale via settings or keyboard shortcuts, Sniffer::change_scale_factor in src/gui/sniffer.rs (lines 30-34) triggers proportional resizing:
let old = self.conf.settings.scale_factor;
self.conf.settings.scale_factor = new;
self.conf.window.scale_size(old, new);
The scale_size implementation multiplies the stored width and height by the ratio of new to old scale factors, then re-sanitizes the results. This ensures that physical pixel dimensions remain constant while logical coordinates update, preventing window shrinkage or growth when switching between 100% and 200% scaling.
Thumbnail Mode Geometry Management
Sniffnet implements a thumbnail mode that transforms the full application into a compact overlay. This feature requires distinct geometry tracking to restore the original window size and position when exiting the thumbnail view.
In src/gui/sniffer.rs (lines 734-754), the toggle_thumbnail method swaps configurations atomically: it saves the current normal window position to memory, applies the stored thumbnail_position, and sets fixed thumbnail dimensions (240×135 logical pixels). When toggling back, the process reverses, retrieving the previous normal geometry from ConfigWindow and applying it via Iced window commands. This seamless transition relies on the thumbnail_position field maintained separately from the primary position storage.
Configuration Persistence Across Sessions
Because ConfigWindow derives Serialize and Deserialize, and is embedded within the Conf structure, window geometry automatically persists to disk. The application utilizes the confy crate to store configuration in the user's config directory, writing the current ConfigWindow state—including size, position, and thumbnail coordinates—when the application exits.
On subsequent launches, Conf::load() reads this serialized state, restoring the exact window configuration from the previous session. This persistence mechanism ensures that users retain their preferred layout without manual repositioning, even across system restarts or application updates.
Summary
-
Centralized storage: The
ConfigWindowstruct insrc/gui/types/config_window.rsacts as the single source of truth for all window geometry, encapsulating size, position, and thumbnail-specific coordinates. -
Startup validation:
Conf::load()sanitizes stored values against screen bounds viaconfig_window.sanitize(), preventing off-screen windows or negative dimensions at initialization. -
Real-time synchronization:
Sniffersubscribes to native window events, immediately updatingConfigWindowthroughwindow_movedandwindow_resizedhandlers as users manipulate the window. -
Scale awareness: The
scale_sizemethod adjusts stored dimensions proportionally when the UI scale factor changes, maintaining consistent physical window sizes across different DPI settings. -
Dual-mode geometry: Sniffnet maintains separate position tracking for normal and thumbnail modes, enabling seamless transitions between full-size analysis and compact overlay views.
-
Automatic persistence: Through serde serialization and the
confyconfiguration manager, window properties survive application restarts without explicit user action.
Frequently Asked Questions
Where does Sniffnet store the window position and size?
Sniffnet stores window geometry in a configuration file managed by the confy crate, typically located in the user's configuration directory. The ConfigWindow struct—part of the Conf structure—serializes size, position, and thumbnail_position fields using serde, writing them to disk automatically when the application exits and reading them via Conf::load() at startup.
How does Sniffnet handle window resizing when the UI scale changes?
When the scale factor changes (e.g., from 100% to 150%), Sniffer::change_scale_factor calls ConfigWindow::scale_size(old_factor, new_factor), which multiplies the stored width and height by the ratio of new to old scale. This rescaling maintains the physical pixel dimensions while updating logical coordinates, then re-invokes sanitize() to ensure the rescaled window remains within valid screen bounds.
What happens to window geometry when entering thumbnail mode?
When activating thumbnail mode via toggle_thumbnail in src/gui/sniffer.rs, Sniffnet saves the current normal window position and switches to the stored thumbnail_position coordinates with fixed dimensions (240×135 logical pixels). When exiting thumbnail mode, the application restores the previous normal geometry from memory, ensuring users return to their exact previous layout rather than a default position.
Why does Sniffnet sanitize window properties on startup?
The sanitize() method in ConfigWindow clamps size and position values to minimum thresholds (preventing zero or negative dimensions) and validates that coordinates remain within accessible display areas. This protects against corrupted configuration files, display configuration changes (such as disconnecting a monitor where the window was previously located), or manual config edits that might otherwise render the window inaccessible or invisible.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →