Skip to content

Add full-featured Window menu with tiling window manager support#21

Merged
jdtsmith merged 2 commits intojdtsmith:emacs-mac-30_1_expfrom
rymndhng:rayh/hack-windows-management
Jul 14, 2025
Merged

Add full-featured Window menu with tiling window manager support#21
jdtsmith merged 2 commits intojdtsmith:emacs-mac-30_1_expfrom
rymndhng:rayh/hack-windows-management

Conversation

@rymndhng
Copy link
Contributor

What works:

  • native keyboard shortcuts

What's meh:

  • coding practises? first time writing obj-c.
  • placement of window vs help (non-native)
  • emacs keybinds has priority over mac bindings

@jdtsmith
Copy link
Owner

jdtsmith commented Jun 14, 2025

Thanks for your contribution. I'm a first time ObjC'er too, so no worries there. I like the idea of a "Window" menu, though it may confuse Emacs users relative to Emacs' own definition of "windows". I wonder, does it have to be called "Window"?

For shortcuts, do you mean binding these in Settings' App Shortcuts? Update: I see them under Settings>Keyboard>Keyboard Shortcuts...>Windows. I use Hammerspoon for similar.

Let me play around with this.

@rymndhng
Copy link
Contributor Author

@jdtsmith thanks, yeah, I agree that having a "Window" menubar could be confusing for emacs user. Some ideas...

Option 1 -- Change the name

I can suggest "Tiling" or symbols that represent graphical tiling: 🪟, ⊞,

Some screenshots:
Screenshot 2025-06-15 at 5 10 14 PM
Screenshot 2025-06-15 at 5 04 16 PM
Screenshot 2025-06-15 at 5 05 50 PM

Option 2 -- Nest this menu under "Emacs"

I've put up a separate PR for this: #23

By nesting this under the "Emacs" menu item, this conveys the expectation that this is an apple-specific feature. Screenshot:

Screenshot 2025-06-15 at 5 39 00 PM

I personally would lean towards Option 2 to keep the menu bar tidy.

@jdtsmith
Copy link
Owner

Thanks. On the other hand, users of MacOS apps will absolutely expect and understand what a "Window" menu is for. I just checked all my running apps, and every one has a "Window" menu item, so I think that's probably fine.

One question is about Tabs. emacs-mac supports native tabs (which I use in preference to emacs tab-bar/tabline). E.g. here is Safari's:

image

Did you come across any options for auto-enabling simple tab related commands? We could simply move the commands from the bottom of the Buffers menu to a section in the new Window menu.

@rymndhng
Copy link
Contributor Author

Out of the box, I couldn't find anything that sets this up. Here are upstream docs for configuring menus, and all the menus are already configured in macappkit.m for mainMenu, servicesMenu, windowsMenu.

I played around a bit with tabs and it appears that emacs-mac treats each tab as a separate window. You get names of tabs for free ... but you do not get any controls for changing tabs.

Screenshot 2025-06-16 at 11 10 12 PM

I looked at a few apps (Firefox, Signal). I believe the apps with extra Window items customize this explicitly. For example, here's the code for kitty that produces the menu.

Screenshot:
Screenshot 2025-06-16 at 11 07 33 PM

@jdtsmith
Copy link
Owner

jdtsmith commented Jun 17, 2025

If you look at the bottom of the "Buffers" menu you'll see some hand-created Tab commands. Maybe we can just move those over to the new "Window" menu.

image

@rymndhng
Copy link
Contributor Author

rymndhng commented Jun 18, 2025

@jdtsmith yeah, I noticed that. The configuration for these four commands are encoded in elisp, see

emacs-mac/lisp/term/mac-win.el

Lines 3092 to 3105 in 2226fd6

(define-key-after global-buffers-menu-map [mac-next-tab]
'(menu-item "Show Next Tab" mac-next-tab-or-toggle-tab-bar
:enable (mac-frame-multiple-tabs-p)))
(global-set-key [(control tab)] 'mac-next-tab-or-toggle-tab-bar)
(define-key-after global-buffers-menu-map [mac-previous-tab]
'(menu-item "Show Previous Tab" mac-previous-tab-or-toggle-tab-bar
:enable (mac-frame-multiple-tabs-p)))
(global-set-key [(control shift tab)] 'mac-previous-tab-or-toggle-tab-bar)
(define-key-after global-buffers-menu-map [mac-move-tab-to-new-frame]
'(menu-item "Move Tab to New Frame" mac-move-tab-to-new-frame
:enable (mac-frame-multiple-tabs-p)))
(define-key-after global-buffers-menu-map [mac-merge-all-frame-tabs]
'(menu-item "Merge All Frames" mac-merge-all-frame-tabs
:enable (mac-send-action 'mergeAllWindows t))))
.

I think this is doable, however I'd tackle it differently from what I have now. I will try the following:

  1. Create a new global menu map similar to global-buffers-menu-map, named global-windows-menu-map.
  2. Assign these four commands to that window map.
  3. In mapappkit.m, add code to find the "Window" menu, and call setWindowMenu on that menu. This is similar to how the existing code detects "Help".

I can give this a try

@jdtsmith
Copy link
Owner

Excellent, thank you for looking into this. Also, if you discover things about the interface between system-provided menus and elisp-defined menus (like how that works in general), it would be great to take some notes about it in the devel_update_notes.org file.

@jdtsmith jdtsmith changed the title hack: tiling windows manager working Add full-featured Window menu with tiling window manager support Jun 22, 2025
@rymndhng
Copy link
Contributor Author

@jdtsmith ready for another round of review.

Here's a screenshot of this the new Window menu with this patch:

Screenshot 2025-06-25 at 12 13 48 AM

@rymndhng rymndhng marked this pull request as ready for review June 25, 2025 07:14
Copy link
Owner

@jdtsmith jdtsmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good, thanks, just a few things to look at. I notice many Window menus have an item "Bring All to Front". That would be good to have too, if it's straightforward. Thanks again for your work on this.

@what-the-functor
Copy link

This is really cool!

@jdtsmith
Copy link
Owner

jdtsmith commented Jul 5, 2025

@rymndhng any progress? Would be great to land this and then port to our master-branch tracking build.

@rymndhng
Copy link
Contributor Author

rymndhng commented Jul 5, 2025

Been a bit busy recently. I’ll try to get back to it sometime this weekend.

I can rebase this off the base branch before applying your feedback.

@jdtsmith
Copy link
Owner

jdtsmith commented Jul 5, 2025

No worries, thanks for working on it. Shouldn't be any changes to worry about.

@rymndhng rymndhng force-pushed the rayh/hack-windows-management branch from cae800a to ca5b262 Compare July 10, 2025 06:47
@rymndhng rymndhng requested a review from jdtsmith July 10, 2025 06:52
@rymndhng
Copy link
Contributor Author

rymndhng commented Jul 10, 2025

@jdtsmith This is ready for review again. I also fixed up a bug with localizing the Edit menu.

On a mac, you can test the localization on individual apps under "Languages & Region > Applications".

Here's a screenshot of Emacs Menubar in German ... also see that "Edit" is translated now.

Screenshot 2025-07-09 at 11 55 08 PM

@rymndhng
Copy link
Contributor Author

This is looking good, thanks, just a few things to look at. I notice many Window menus have an item "Bring All to Front". That would be good to have too, if it's straightforward. Thanks again for your work on this.

I haven't figured out what enables this. I see it on many apps, but I also don't see it universally -- I don't see this on Firefox.

@jdtsmith
Copy link
Owner

I've tested this and it works great. I also figured out there's a responder action called arrangeInFront that raises windows, so it was easy to add a menu item for that; see 65eace4. (Well, I discovered this after I had implemented a full command in macfns.c and method in macappkit.m — good learning exercise).

If you give this a test and it works for you, I think we're ready to merge. Could you please squash all your commits but mine into one with a good commit message, and force push to this PR? Thanks again for working on this.

rymndhng and others added 2 commits July 13, 2025 00:02
The Window menu bar holds commands for managing window & tabs. Adopts
commands found in most mac apps such as Fill, Center, Move &
Resize. This allows Emacs to respond to native MacOS tiling keyboard
shortcuts, see https://support.apple.com/en-ca/guide/mac-help/
mchl9674d0b0/mac.

Additionally, we move custom tab actions from the 'Buffer' menu
here. This is accomplished by placing these keybindings under the new
`mac-window-menu-map`.

Finally, we noticed the "Edit" menu item did not localize. This PR
contains a fix for this.

See jdtsmith#22
@rymndhng rymndhng force-pushed the rayh/hack-windows-management branch from 65eace4 to 20f8646 Compare July 13, 2025 07:03
@rymndhng
Copy link
Contributor Author

@jdtsmith looks good! I've squashed it down.

@jdtsmith
Copy link
Owner

Thanks again for your work on this! @simmsb would be good to merge this into the master tracking branch too.

@jdtsmith jdtsmith merged commit 4136734 into jdtsmith:emacs-mac-30_1_exp Jul 14, 2025
@rymndhng rymndhng deleted the rayh/hack-windows-management branch July 14, 2025 15:31
@jdtsmith
Copy link
Owner

Hi @rymndhng. In case you missed it, users on older MacOS versions are encountering a crash due to the new Window menu (#64). Please take a look if you have a moment.

@rymndhng
Copy link
Contributor Author

@jdtsmith thanks for the ping, I’ll take a look at it sometime this week. I have an older Ventura mac to test on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants