mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 08:28:12 +08:00
Desktop: Fix frontend message response dispatch (#3247)
* One annoying debugging session later Discovered that the editor handles frontend messages differently from other messages. It requires all frontend messages to be fully processed before dispatching any resulting messages. In the web frontend, this behavior happened implicitly because message dispatch is queued at the current end of the JavaScript execution queue. For the desktop frontend, I added a vector to collect all responses until the entire batch of frontend messages is handled, and then dispatch them afterwards. * Fix double click travel
This commit is contained in:
+11
-7
@@ -82,7 +82,7 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_desktop_frontend_message(&mut self, message: DesktopFrontendMessage) {
|
fn handle_desktop_frontend_message(&mut self, message: DesktopFrontendMessage, responses: &mut Vec<DesktopWrapperMessage>) {
|
||||||
match message {
|
match message {
|
||||||
DesktopFrontendMessage::ToWeb(messages) => {
|
DesktopFrontendMessage::ToWeb(messages) => {
|
||||||
let Some(bytes) = serialize_frontend_messages(messages) else {
|
let Some(bytes) = serialize_frontend_messages(messages) else {
|
||||||
@@ -205,7 +205,7 @@ impl App {
|
|||||||
to_front: false,
|
to_front: false,
|
||||||
select_after_open: true,
|
select_after_open: true,
|
||||||
};
|
};
|
||||||
self.dispatch_desktop_wrapper_message(message);
|
responses.push(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DesktopFrontendMessage::PersistenceLoadRemainingDocuments => {
|
DesktopFrontendMessage::PersistenceLoadRemainingDocuments => {
|
||||||
@@ -216,7 +216,7 @@ impl App {
|
|||||||
to_front: true,
|
to_front: true,
|
||||||
select_after_open: false,
|
select_after_open: false,
|
||||||
};
|
};
|
||||||
self.dispatch_desktop_wrapper_message(message);
|
responses.push(message);
|
||||||
}
|
}
|
||||||
for (id, document) in self.persistent_data.documents_after_current() {
|
for (id, document) in self.persistent_data.documents_after_current() {
|
||||||
let message = DesktopWrapperMessage::LoadDocument {
|
let message = DesktopWrapperMessage::LoadDocument {
|
||||||
@@ -225,11 +225,11 @@ impl App {
|
|||||||
to_front: false,
|
to_front: false,
|
||||||
select_after_open: false,
|
select_after_open: false,
|
||||||
};
|
};
|
||||||
self.dispatch_desktop_wrapper_message(message);
|
responses.push(message);
|
||||||
}
|
}
|
||||||
if let Some(id) = self.persistent_data.current_document_id() {
|
if let Some(id) = self.persistent_data.current_document_id() {
|
||||||
let message = DesktopWrapperMessage::SelectDocument { id };
|
let message = DesktopWrapperMessage::SelectDocument { id };
|
||||||
self.dispatch_desktop_wrapper_message(message);
|
responses.push(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DesktopFrontendMessage::PersistenceWritePreferences { preferences } => {
|
DesktopFrontendMessage::PersistenceWritePreferences { preferences } => {
|
||||||
@@ -238,14 +238,18 @@ impl App {
|
|||||||
DesktopFrontendMessage::PersistenceLoadPreferences => {
|
DesktopFrontendMessage::PersistenceLoadPreferences => {
|
||||||
let preferences = self.persistent_data.load_preferences();
|
let preferences = self.persistent_data.load_preferences();
|
||||||
let message = DesktopWrapperMessage::LoadPreferences { preferences };
|
let message = DesktopWrapperMessage::LoadPreferences { preferences };
|
||||||
self.dispatch_desktop_wrapper_message(message);
|
responses.push(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_desktop_frontend_messages(&mut self, messages: Vec<DesktopFrontendMessage>) {
|
fn handle_desktop_frontend_messages(&mut self, messages: Vec<DesktopFrontendMessage>) {
|
||||||
|
let mut responses = Vec::new();
|
||||||
for message in messages {
|
for message in messages {
|
||||||
self.handle_desktop_frontend_message(message);
|
self.handle_desktop_frontend_message(message, &mut responses);
|
||||||
|
}
|
||||||
|
for message in responses {
|
||||||
|
self.dispatch_desktop_wrapper_message(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,7 +246,8 @@ impl ClickTracker {
|
|||||||
return ClickCount::Single;
|
return ClickCount::Single;
|
||||||
};
|
};
|
||||||
|
|
||||||
let previous = record.time;
|
let prev_time = record.time;
|
||||||
|
let prev_position = record.position;
|
||||||
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
record.time = now;
|
record.time = now;
|
||||||
@@ -270,10 +271,10 @@ impl ClickTracker {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let dx = position.x.abs_diff(record.position.x);
|
let dx = position.x.abs_diff(prev_position.x);
|
||||||
let dy = position.y.abs_diff(record.position.y);
|
let dy = position.y.abs_diff(prev_position.y);
|
||||||
let within_dist = dx <= MULTICLICK_ALLOWED_TRAVEL && dy <= MULTICLICK_ALLOWED_TRAVEL;
|
let within_dist = dx <= MULTICLICK_ALLOWED_TRAVEL && dy <= MULTICLICK_ALLOWED_TRAVEL;
|
||||||
let within_time = now.saturating_duration_since(previous) <= MULTICLICK_TIMEOUT;
|
let within_time = now.saturating_duration_since(prev_time) <= MULTICLICK_TIMEOUT;
|
||||||
|
|
||||||
let count = if within_time && within_dist { ClickCount::Double } else { ClickCount::Single };
|
let count = if within_time && within_dist { ClickCount::Double } else { ClickCount::Single };
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ impl<'a> DesktopWrapperMessageDispatcher<'a> {
|
|||||||
frontend_messages.extend(current_frontend_messages);
|
frontend_messages.extend(current_frontend_messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.respond(DesktopFrontendMessage::ToWeb(frontend_messages));
|
if !frontend_messages.is_empty() {
|
||||||
|
self.respond(DesktopFrontendMessage::ToWeb(frontend_messages));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,10 +136,12 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
PortfolioMessage::Init => {
|
PortfolioMessage::Init => {
|
||||||
// Load persistent data from the browser database
|
// Tell frontend to load persistent preferences
|
||||||
responses.add(FrontendMessage::TriggerLoadFirstAutoSaveDocument);
|
|
||||||
responses.add(FrontendMessage::TriggerLoadPreferences);
|
responses.add(FrontendMessage::TriggerLoadPreferences);
|
||||||
|
|
||||||
|
// Tell frontend to load the current document
|
||||||
|
responses.add(FrontendMessage::TriggerLoadFirstAutoSaveDocument);
|
||||||
|
|
||||||
// Display the menu bar at the top of the window
|
// Display the menu bar at the top of the window
|
||||||
responses.add(MenuBarMessage::SendLayout);
|
responses.add(MenuBarMessage::SendLayout);
|
||||||
|
|
||||||
@@ -149,7 +151,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageContext<'_>> for Portfolio
|
|||||||
node_types: document_node_definitions::collect_node_types(),
|
node_types: document_node_definitions::collect_node_types(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Finish loading persistent data from the browser database
|
// Tell frontend to finish loading persistent documents
|
||||||
responses.add(FrontendMessage::TriggerLoadRestAutoSaveDocuments);
|
responses.add(FrontendMessage::TriggerLoadRestAutoSaveDocuments);
|
||||||
}
|
}
|
||||||
PortfolioMessage::DocumentPassMessage { document_id, message } => {
|
PortfolioMessage::DocumentPassMessage { document_id, message } => {
|
||||||
|
|||||||
Reference in New Issue
Block a user