Handle appkit's cancelOperation: message to allow binding `cmd-.`

Max Brunsfeld created

Change summary

crates/gpui/src/platform/mac/window.rs | 32 ++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)

Detailed changes

crates/gpui/src/platform/mac/window.rs 🔗

@@ -107,6 +107,10 @@ unsafe fn build_classes() {
             sel!(scrollWheel:),
             handle_view_event as extern "C" fn(&Object, Sel, id),
         );
+        decl.add_method(
+            sel!(cancelOperation:),
+            cancel_operation as extern "C" fn(&Object, Sel, id),
+        );
 
         decl.add_method(
             sel!(makeBackingLayer),
@@ -538,6 +542,34 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) {
     }
 }
 
+// Allows us to receive `cmd-.` (the shortcut for closing a dialog)
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=300620#c6
+extern "C" fn cancel_operation(this: &Object, _sel: Sel, _sender: id) {
+    let window_state = unsafe { get_window_state(this) };
+    let mut window_state_borrow = window_state.as_ref().borrow_mut();
+
+    let chars = ".".to_string();
+    let keystroke = Keystroke {
+        cmd: true,
+        ctrl: false,
+        alt: false,
+        shift: false,
+        key: chars.clone(),
+    };
+    let event = Event::KeyDown {
+        keystroke: keystroke.clone(),
+        chars: chars.clone(),
+        is_held: false,
+    };
+
+    window_state_borrow.last_fresh_keydown = Some((keystroke, chars));
+    if let Some(mut callback) = window_state_borrow.event_callback.take() {
+        drop(window_state_borrow);
+        callback(event);
+        window_state.borrow_mut().event_callback = Some(callback);
+    }
+}
+
 extern "C" fn send_event(this: &Object, _: Sel, native_event: id) {
     unsafe {
         let () = msg_send![super(this, class!(NSWindow)), sendEvent: native_event];