14

Often, I my windows get automatically split until I arbitrarily decide that the current frame does not have enough real-estate for them all. When this occurs, I manually delete a window, create a frame, and switch to that deleted window. How can I write an elisp function that does this?

I tried:

(defun pop-window-into-frame ()
  (interactive)
  (delete-window)
  (make-frame-command)
  (switch-to-prev-buffer))

But for some reason this doesn't do what I think it should.

2 Answers 2

16

Try this instead:

(defun my-turn-current-window-into-frame ()
  (interactive)
  (let ((buffer (current-buffer)))
    (unless (one-window-p)
      (delete-window))
    (display-buffer-pop-up-frame buffer nil)))
5
  • 1
    Another thing I didn't know I wanted until someone else wrote it. Cool.
    – glucas
    Jan 7, 2015 at 15:19
  • Nice! +1 for being concise.
    – PythonNut
    Jan 7, 2015 at 16:43
  • In terms of (minimal) performance impact - would it make a difference if the let and unless forms are swapped?
    – Matthias
    Jan 11, 2015 at 9:08
  • @Matthias I'm not sure whether the inversion would make sense at this point, the reason I'm binding the current buffer is because deleting the window might change the notion of the current buffer. The only way I see around it would make the code more complicated by checking whether there's only one window, if yes let-binding the current buffer, deleting and popping it, if no just displaying the current buffer in a new frame. The loss of clarity isn't worth it for the miniscule performance change IMHO.
    – wasamasa
    Jan 11, 2015 at 13:08
  • @wasamasa sorry for not beeing precise. I had in mind (unless (one-window-p) (let ...
    – Matthias
    Jan 30, 2015 at 21:06
5
;; Inspired from `mouse-tear-off-window'.
(defun tear-off-window ()
  "Create a new frame displaying buffer of selected window.
    If window is not the only one in frame, then delete it.
    Otherwise, this command effectively clones the frame and window."
  (interactive)
  (let ((owin  (selected-window))
        (buf   (window-buffer))
        (fr    (make-frame)))
    (select-frame fr)
    (switch-to-buffer buf)
    (save-window-excursion 
      (select-window owin)
      (unless (one-window-p) (delete-window owin)))))

This command, as well as the following, which does nothing if the selected window is alone in its frame, are available in library frame-cmds.el.

(defun tear-off-window-if-not-alone ()
  "Move selected window to a new frame, unless it is alone in its frame.
If it is alone, do nothing.  Otherwise, delete it and create a new
frame showing the same buffer."
  (interactive)
  (if (one-window-p 'NOMINI)
      (message "Sole window in frame")
    (tear-off-window)))
2
  • This didn't give focus to the new frame here (gnome3.28). Adding (select-frame-set-input-focus fr) at the end worked.
    – olejorgenb
    Mar 29, 2018 at 10:26
  • @olejorgenb: Yes, whether a newly created frame gets the input focus can depend on your window manager. So yes, you might need to add select-frame-set-input-focus. In MS Windows, for instance, it does get the focus, so that's not needed. Also, the command description does not say that the frame becomes focused. If that's wanted then a different command can be created that calls this and then focuses the frame.
    – Drew
    Mar 29, 2018 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.