Opening org-capture in a new frame

emacselisporgmicro

I wanted to simply have a way of opening org-capture in a new frame.11This is good for the cases where you want it to be available from other programs without switching into Emacs. There is also something called org-protocol which may replace/aid your need of opening org-capture outside of Emacs. Just wanted to let you know about this, too. When I searched for a solution I found a lot of, what I believe is, outdated information and misuse of Emacas Lisp. Here is a simple alternative that you can put into your Emacs configuration. When you invoke im-org-capture this takes care of opening the capture selection window on a new Emacs frame, no split windows whatsoever. I've also disabled system window decorations, made the frame a bit more compact, handles quitting properly etc.

(defun im-org-capture ()
  "Select a template and capture in a new frame."
  (interactive)
  (let ((frame (make-frame '((name . "org-capture")
                             ;; Optional configuration, change it as you like
                             (width . 80)
                             (height . 20)
                             (undecorated . t)
                             (internal-border-width . 5)
                             (left-fringe . 0)
                             (right-fringe . 0)
                             (menu-bar-lines . 0)
                             (tool-bar-lines . 0)
                             (vertical-scroll-bars . nil)
                             (horizontal-scroll-bars . nil)
                             (tab-bar-lines . 0)))))
    (select-frame-set-input-focus frame)
    (condition-case err
        (let ((display-buffer-overriding-action
               '(display-buffer-same-window
                 (inhibit-same-window . nil))))
          (org-capture))
      ((quit user-error)
       (when (frame-live-p frame)
         (delete-frame frame))
       (signal (car err) (cdr err))))))

(defun im-delete-frame-after-capture ()
  "Delete the current frame after org-capture is finished."
  (when (equal (frame-parameter nil 'name) "org-capture")
    (delete-frame)))

(add-hook 'org-capture-after-finalize-hook #'im-delete-frame-after-capture)

Just bind any key globally to emacsclient --eval "(im-org-capture)". For example I use Sway and here is a binding example for it:

bindsym $mod+c exec emacsclient --eval "(im-org-capture)"

Also if you want to make it floating on Sway:

for_window [app_id="emacs$" title="^org-capture$"] floating enable

Same idea probably works for other WM's too, we set the frame's name to org-capture and you need to mark it floating in your configuration.

Similar stuff