Commit graph

178 commits

Author SHA1 Message Date
David Barr
4d1be7eada
menu: add brackets around minimised window titles in client-list menu (#3002) 2025-08-26 21:08:31 +01:00
John Lindgren
9d49d19cd2 include: add config/types.h 2025-08-21 16:55:25 +09:00
Johan Malm
8bcea29a1c menu: fix leak in update_client_send_to_menu() 2025-08-16 14:54:48 +01:00
Johan Malm
6fe61f8846 menu: use client-send-to-menu as 'Workspace' submenu
...because that is more flexible and how it is in openbox.

I have had in mind that we should do this since the original
implementation, and #2994 just jogged my memory.
2025-08-16 14:54:48 +01:00
John Lindgren
d9f7ccf3aa menu: fix use-after-free at exit with sub-menu selected
Sequence of events:

- menu_finish() frees the sub-menu first
- the selection.menu of the parent menu is now dangling
- menu_finish() frees the parent menu
- menu_free() calls menu_close_root() on the parent menu
- menu_close_root() tries to close the (freed) sub-menu
- boom

Extending nullify_item_pointing_to_this_menu() avoids the crash.
2025-08-15 18:46:34 +09:00
tokyo4j
72e1945a4c menu: allow overwriting submenu icon
Allow overwriting the icon of item linking to another menu like below
(the icon for "krita" should be shown):

<openbox_menu>
  <menu id="static-menu" label="Static Menu" icon="mpv" />
  <menu id="root-menu" label="Root">
    <menu id="static-menu" icon="krita" />
  </menu>
</openbox_menu>

This commit also fixes my mistake in 17d66e5 (s/parent->icon/menu->icon/)
that showed incorrect icon in an item linking to another menu.
2025-08-14 20:47:43 +01:00
tokyo4j
2a039d4f24 menu: fix client-send-to-menu
Fixes 17d66e5
2025-08-13 20:29:23 +01:00
tokyo4j
2ce3f39c1f menu: allow client-{list-combined,send-to}-menu as submenu of static menu
Also, their labels are changed to "Windows" and "Send to desktop" which
are the same as Openbox.
2025-08-13 20:29:23 +01:00
tokyo4j
17d66e5603 menu: refactor parser
...with the same approach as rcxml.c

- `If` actions now works for menus
- `name` argument no longer have to be the first argument of <action>
- `label` argument no longer have to be the first argument of <item>
2025-08-04 21:41:14 +01:00
tokyo4j
03004cf44b menu: fix segfault with toplevel <separator>
Before this patch, labwc crashed menu.xml like this:

<openbox_menu>
  <separator />
</openbox_menu>
2025-08-03 15:07:35 +01:00
John Lindgren
e1475a1e47 include: reduce global includes in labwc.h 2025-07-30 21:04:31 +01:00
John Lindgren
e21fc065c4 include: split output.h from labwc.h 2025-07-30 21:04:31 +01:00
John Lindgren
31d42b50e2 src: include primary header first
This is a common practice in C projects, which simply enforces that
each header must compile cleanly without implicit dependencies on
other headers (see also the previous commit).
2025-07-29 21:51:56 +01:00
John Lindgren
d96656ccdc menu: add struct menu_parse_context to reduce static vars
The lifetime of the "current_" variables (current_menu, current_item,
current_item_action) is very difficult to understand from reading the
code. It appears that e.g. current_menu could still point to a previous
menu when starting to parse a new one, with unpredictable results.

Let's use a context struct when parsing, and consistently initialize
it when beginning to build a new menu.

Lightly tested with:

- default menus (no menu.xml)
- example static menu from labwc.github.io/getting-started.html
- an added "client-list-combined-menu" sub-menu
- pipe menu generated by `labwc-menu-generator -p`

v2: style fix
2025-07-24 15:35:29 +09:00
John Lindgren
ac47be3019 menu: do not modify literal string constants
Mutable string literals are a "legacy" C feature best avoided.

v2: move string_truncate_at_pattern() outside fill_item()
2025-07-21 16:51:10 +02:00
Johan Malm
c749a11517 menu: add Terminal to default root-menu 2025-07-01 22:27:33 +01:00
tokyo4j
97ce4131bb Replace scaled_rect_buffer with lab_scene_rect
This fixes the gap between menu items and the menu border in an output
with a fractional scale due to the semantic gap between cairo and
wlroots's position-independent scene renderer.
2025-06-10 06:03:03 +09:00
tokyo4j
fb077c0095 Support xdg-toplevel-icon protocol
This patch also changes the semantics of scaled_icon_buffer: rather than
calling scaled_icon_buffer_set_app_id() every time an app_id is set, we
can now call scaled_icon_buffer_set_view() just once so that multiple
scaled_icon_buffers bound to a window are automatically updated when an
app_id is set or new icon is set via xdg-toplevel-icon-v1.
2025-06-07 02:12:56 +09:00
tokyo4j
f1c4720218 menu: guard against negative sizes
For example, the size of a scene_rect for a menu item background could be
negative with:

  menu.width.max: 0
  menu.width.min: 0
2025-05-19 06:51:42 +09:00
tokyo4j
34a078294e menu: refactor handle_menu_element() (part 2)
I believe !current_menu is equivalent to
is_toplevel_static_menu_definition().
2025-04-18 14:20:54 +01:00
tokyo4j
8c0bd2a7f0 menu: refactor handle_menu_element() (part 1)
Also, show an error message when <menu> without 'id' is encountered
2025-04-16 19:49:03 +01:00
tokyo4j
e517b6808d menu: show app icons in client-list-combined-menu 2025-03-11 20:25:09 +00:00
tokyo4j
54186e5152 menu: dynamically generate top-level pipemenus
This eliminates code duplications and aligns the behavior of top-level
pipemenus with sub-pipemenus.
2025-03-10 19:42:03 +00:00
tokyo4j
40dfee7bd5 menu: don't fill default items in empty menus
This is needed to prevent pipemenus which usually contains no items
from being filled with default items in follow-up commits.
2025-03-10 19:42:03 +00:00
tokyo4j
ea4ea84499 menu: use item->parent->id for client-list-combined-menu
...instead of item->id.
2025-03-10 19:42:03 +00:00
tokyo4j
12f95543f0 menu: lazily generate menu scenes
This removes the need to call update_client_list_combined_menu()
and update_client_send_to_menu() every time a root menu is opened.

This commit also fixed the incorrect menu position with following
configuration:
  <menu id="foo" label="foo">
    <item label="aaaaaa"/>
    <item label="bbbbbb"/>
  </menu>
  <menu id="root-menu">
    <menu id="foo" />
    <menu id="foo" />
  </menu>
2025-03-10 16:16:20 +09:00
tokyo4j
514f1d4fc4 menu: assert server->menu_current != NULL in menu_close_root() 2025-03-10 16:16:20 +09:00
tokyo4j
d7b5555bf8 menu: s/menu_configure/menu_reposition/ 2025-03-10 16:16:20 +09:00
tokyo4j
853d71ee6d menu: remove menu_free_from() 2025-03-10 16:16:20 +09:00
tokyo4j
fb5e85f40f menu: remove ShowMenu action from menu items
Previous commits fixed some unexpected behaviors when ShowMenu action is
executed from menu items, but that was still prone to bugs because when
calling actions_run(), we allow an inconsistent state where all menus are
closed but pipemenus must not be destroyed.

So this commit simply removes ShowMenu actions from menu items on
initialization.
2025-02-07 17:58:55 +01:00
tokyo4j
8f5217c98b menu: assert no menu is opened in menu_open_root()
66a3beb added an early-return when the menu is opened, so we can guarantee
that no menu is opened there.
2025-02-07 17:58:55 +01:00
tokyo4j
4072a80eba menu: fix unexpected behavior when a menu is opened from another menu
server->menu_current should be cleared before calling actions_run() as
it may internally call menu_open_root(). Clearing it after actions_run()
leads to an inconsistent state where a menu is opened but
server->menu_current is NULL. It even lead to a segfault when the item
opening another menu is contained in a pipemenu, because
menu_open_root() calls destroy_pipemenu() when server->menu_current is
set, which makes accessing item->actions a UAF.
2025-02-07 17:58:55 +01:00
Consolatis
ed4553fc7e src/menu: add global config for menu.showIcons 2025-02-02 15:05:37 +00:00
Consolatis
1fa4070025 src/menu: add support for scalable menu icons 2025-02-02 15:05:37 +00:00
tinyboxvk
1a6dd845a2 Fix typos
Signed-off-by: tinyboxvk <13696594+tinyboxvk@users.noreply.github.com>
2025-01-09 06:59:57 +00:00
Johan Malm
956b271f9b menu: support pipemenu with the toplevel <menu> element
For example:

    <?xml version="1.0"?>
    <openbox_menu>
      <menu id="root-menu" label="" execute="obmenu-generator"/>
    </openbox_menu>

Fixes: #2238

Co-Authored-By: @Consolatis
2025-01-03 04:41:25 +01:00
tokyo4j
bad788ccdd Clear keyboard/pointer focus on Move/Resize, window switcher and menu
The previous revert fixed the problem of stuck modifier keys with
keybinds in Blender, but made Firefox show its menu bar with Alt-*
keybinds. This is fundamentally inevitable due to the limitation of
wayland protocol, but at least for the default Alt-Tab keybind for
window switcher, we can mitigate this problem by clearing the keyboard
focus when the window switcher is activated. This is what KWin does, and
we decided to follow that.

So in this commit, keyboard and pointer focus are temporarily cleared
while Move/Resize, window switcher and menu interactions and restored
after them. We slightly deviate from KWin as KWin doesn't clear the
keyboard focus while Move/Resize, but it solves our existing problem
that Firefox shows its menu bar after dragging it with default Alt-Drag
mousebind, and this is what Mutter does.

We considered other solutions, but they don't work well:
1. Send wl_keyboard.{leave,enter} every time keybinds/mousebinds are
   triggered. This solves the Firefox's menu bar problem, but that
   sounds like a workaround and sending unnecessary events every time is
   not desirable.
2. Send release events for both modifiers and keys even when they are
   bound to keybinds. This is what Mutter is doing, but it looks like an
   implementation issue and violates wayland protocol.
2024-12-29 16:27:34 +09:00
tokyo4j
66a3beb98b Don't open menu or start window switching while other server interaction
This should make the transition of the server state more predictable and
prevent potential bugs.
2024-12-28 21:28:22 +00:00
Johan Malm
2446c46069 string-helpers.c: add str_starts_with() 2024-12-18 18:32:25 +00:00
Johan Malm
cc838e79ed s/xmlParseMemory/xmlReadMemory/
...as xmlParseMemory() is deprecated
2024-12-17 21:51:47 +00:00
tokyo4j
40c7350064 menu: improve algorithm for menu placement with xdg-positioner
This commit delegates the calculation for menu position into wlroots
utilities for xdg_positioner.

Notable functional changes are:
- Slide the menu to fit in the output when it's opened out of the output
  (e.g. top-left window menu is opened when the window is overflowing to
  the left), rather than not updating the menu at all.
- The horizontal alignment of menus is now determined based on the size of
  each (sub)menu alone rather than the total width of entire menu tree.
  This means submenus can now overlap with is parents, but this is no
  longer a problem since we recently added support for menu borders.
- Fixed that pipemenus always follow the alignment of its parent even when
  it overflows from the output.
2024-12-15 11:43:23 +09:00
tokyo4j
01032ef3bd font: remove arrow character from font buffer
Arrow signs are specific to submenu items, so they would be more natural
to be handled in menu.c rather than accepting "arrow" in
font_buffer_create().

Also I allowed non-positive numbers for max_width in font_buffer_create(),
in which case the natural font width is used as the buffer width.
2024-12-14 20:09:53 +00:00
tokyo4j
10fc656c23 menu: some refactor
- Don't store font/background buffers in menuitem struct since we no
  longer dynamically update buffers of existing menuitems.
- Factor out the duplicated codes for creating menu item scenes for each
  unselected/selected states.
2024-12-14 20:09:53 +00:00
tokyo4j
45646c694f menu: invert the y-offset of submenus applied by menu.overlap.y
This follows Openbox's behavior.
2024-11-25 21:19:59 +00:00
tokyo4j
d70040c750 menu: overlap submenus by menu.border.width
This follows Openbox's behavior that aligns the first item of a submenu
with its parent item
2024-11-25 19:41:07 +00:00
tokyo4j
da418f9720 menu: support borders
This commit adds following theme configurations:

  menu.border.width: 1
  menu.border.color: #aaaaaa
2024-11-25 19:41:07 +00:00
tokyo4j
9703c1deca src/menu.c: remove unnecessary re-renderings of font buffers
I missed that `scaled_font_buffer_update()` has `max_width` argument and
the subsequent calls to `scaled_font_buffer_set_max_width()` caused
unnecessary re-renderings.
2024-11-19 03:12:28 +01:00
tokyo4j
f8ed199197 menu: fix UAFs in menu_destroy() and item_destroy()
This fixes use-after-free when there's only 1 desktop and
menu_hide_submenu() is called to delete "Workspaces" submenu in
client-menu before menu scenes are initialized.

As menu_create() and item_create() no longer initialize scenes after
76515316, menu->scene_tree and item->tree should be null-checked.
2024-11-14 16:32:54 +01:00
tokyo4j
b96742a039 menu: eliminate dead code
The deleted lines were dead code that didn't make any sense (even if it
were not dead, it should have recreated the parent of the hidden menu
rather than the hidden menu itself).
2024-11-14 06:11:13 +00:00
tokyo4j
10ee838c3b menu: fix menus disappearing when opening pipemenu
Commit 7651531 introduced a regression: `menu_update_scene()` which
re-creates a menu scene was called for all the menus when a pipemenu is
created, so the menus (parent of the pipemenu) were always moved to (0,0)
and hidden, and the pipemenu was incorrectly positioned.

This commit fixes it by calling `menu_update_scene()` only for the
pipemenu when it's created.
2024-11-14 06:11:13 +00:00