Files
openidea/src-tauri/src/events.rs
xdpan1234andxdpan1234 0a70b0af01 fix(vcs): open comparisons in independently resizable native windows (#818)
Compare with Local, Compare Versions and the other revision comparisons open in a separate window that belongs to their project window. The window can be moved outside the main window, resized from its edges and corners, and shows the full diff. Edits made there and in the project window are mirrored both ways.

Root cause of #798: the comparison was an in-window dialog with a fixed size.

Settings and comparison windows now share one auxiliary-window mechanism (`AuxKind`, `open_auxiliary_window`). It handles labels, the title bar, placement over the parent, event forwarding, document-edit mirroring, menu routing, closing together with the parent, and remembered geometry per kind.

Co-authored-by: xdpan1234 <277608284+xdpan1234@users.noreply.github.com>
2026-11-04 12:27:45 +08:00

57 lines
1.9 KiB
Rust

use ide_core::{EventSink, IdeEvent};
use tauri::{AppHandle, Emitter};
/// Name of the single backend → UI event. Payload: [`IdeEvent`].
pub const IDE_EVENT: &str = "ide://event";
/// The other windows showing the documents of `source`'s project: its project window and the
/// auxiliary windows with documents. An edit made in one is not echoed by the backend, so they
/// get it as a patch ([`emit_document_edit`]).
pub fn document_edit_peers(app: &AppHandle, source: &str) -> Vec<String> {
let owner = crate::state::AppState::owner_window(source);
let mut peers = crate::windows::document_windows(app, owner);
peers.push(owner.to_owned());
peers.retain(|label| label != source);
peers
}
pub fn emit_document_edit(
app: &AppHandle,
peers: Vec<String>,
doc: ide_core::DocId,
base_version: u32,
version: u32,
changes: Vec<ide_core::TextChange>,
) {
let event = IdeEvent::DocPatched { doc, base_version, version, changes, workspace_edit: false };
for label in peers {
if let Err(e) = app.emit_to(label, IDE_EVENT, &event) {
tracing::warn!("failed to mirror document edit: {e}");
}
}
}
/// Forwards events to one window (`Some(label)`, plus its auxiliary windows that show its
/// project's documents) or to all windows.
pub struct TauriSink {
pub app: AppHandle,
pub window: Option<String>,
}
impl EventSink for TauriSink {
fn emit(&self, event: IdeEvent) {
let result = match &self.window {
Some(label) => {
for target in crate::windows::document_windows(&self.app, label) {
let _ = self.app.emit_to(target.as_str(), IDE_EVENT, &event);
}
self.app.emit_to(label.as_str(), IDE_EVENT, &event)
}
None => self.app.emit(IDE_EVENT, &event),
};
if let Err(e) = result {
tracing::warn!("failed to emit ide event: {e}");
}
}
}