Commit graph

6326 commits

Author SHA1 Message Date
Daniel Eklöf
a6bc9cafaf
osc+notify: strcmp() -> streq() 2024-07-24 16:04:14 +02:00
Daniel Eklöf
f56da385fe
notify: try to read the daemon assigned notification ID from stdout
And document the things we recognize in the notification helper's
stdout.
2024-07-24 16:02:19 +02:00
Daniel Eklöf
e271027c0c
config: notify-send: it's "action=label", not "action,label" 2024-07-24 16:01:42 +02:00
Daniel Eklöf
37ab3b1603
notify: don't create icon file on disk when we're not going to use it
We always prefer the symbolic name. Thus, there's no need to write raw
PNG data to disk if we have a symbolic name.

Furthermore, keep the file open until the cache entry is evicted.
2024-07-24 15:59:52 +02:00
Daniel Eklöf
24168ed86e
osc: kitty notifications: don't include '?' in the query reply
No need to say we support queries, in the query reply...
2024-07-24 15:58:19 +02:00
Daniel Eklöf
ecbec57a47
notify: split up the ${action} template parameter
Split it up into two, ${action-name} and ${action-label}.

Dunstify, for example, has a different syntax compared to notify-send:

notify-send: default=foobar
dunstify: default,foobar
2024-07-23 19:08:21 +02:00
Daniel Eklöf
d5c773a58b
notify: bug: always adjust amount of data left in stdout buffer 2024-07-23 18:48:45 +02:00
Daniel Eklöf
70b4638a75
osc: kitty notifications: implement query 2024-07-23 18:32:23 +02:00
Daniel Eklöf
511d4817d3
doc: foot.ini: desktop-notification: remove 'notification dismissal' 2024-07-23 16:52:18 +02:00
Daniel Eklöf
79832c16e2
notify: name the activation action 'default'
This is less unique, but also works better with notification daemons
that trigger the 'default' action when e.g. clicked.
2024-07-23 16:48:15 +02:00
Daniel Eklöf
045ead985c
notify: don't focus/report on notification dismissal
Only do it when the notification was activated.

Here, activated means the 'click to activate' notification action was
triggered.

How do we tie everything together?

First, we add a new template parameter, ${action}. It's intended to be
used with e.g. notify-send's --action option.

When the action is triggered, notify-send prints its name on stdout,
on a separate line. Look for this in stdout. Only if we've seen it do
we focus/report the notification.
2024-07-23 16:41:52 +02:00
Daniel Eklöf
55a4e59ef9
notify: if there's a symbolic icon name, use it
even if there's no graphical ID set.

In other words, if there *is* a graphical ID, use the icon cache. Only
if there is no graphical ID in the notification request do we fallback
to the symbolic name. This means no icon will be displayed if there's
no matching icon in the cache.

Some examples. You can either pre-load the cache (with inline PNG
data, a symbolic name, or both):

    printf '\e]99;g=123:n=firefox:p=icon:e=1;<PNG data>\e\\'
    printf '\e]99;g=123;this is a notification\e\\'

or

    printf '\e]99;n=firefox;this is a notification\e\\'
2024-07-23 15:30:01 +02:00
Daniel Eklöf
fabfef9c82
notify: consume_stdout(): fix ASAN warning
This is an ASAN false positive; size is always 0 when we're passing a
NULL pointer.

Still, the warning is easy to avoid, so let's do that to reduce the
noise level.
2024-07-23 15:29:08 +02:00
Daniel Eklöf
e59efb1233
osc: remove unused includes 2024-07-23 15:28:47 +02:00
Daniel Eklöf
50efd9726d
pgo: updated stubs for notification functions 2024-07-23 12:15:50 +02:00
Daniel Eklöf
d0a5425155
notify: add_icon(): check return value of write() 2024-07-23 12:15:29 +02:00
Daniel Eklöf
9814cf5779
notify: clean up logging messages 2024-07-23 12:12:50 +02:00
Daniel Eklöf
efa5b9cea6
osc: cleanup 2024-07-23 12:12:38 +02:00
Daniel Eklöf
b3108e1ad2
notify: separate active notifications from unfinished kitty notifications
This fixes an issue where it wasn't possible to trigger multiple
notifications with the same kitty notification ID. This is something
that works in kitty, and there's no reason why it shouldn't work.

The issue was that we track stdout, and the notification helper's PID
in the notification struct. Thus, when a notification is being
displayed, we can't re-use the same notification struct instance for
another notification.

This patch fixes this by adding a new notification list,
'active_notifications'. Whenever we detect that we need to track the
helper (notification want's to either focus the window on activation,
or send an event to the application), we add a copy of the
notification to the 'active' list.

The notification can then be removed from the 'kitty' list, allowing
kitty notifications to re-use the same ID over and over again, even if
old notifications are still being displayed.
2024-07-23 11:53:30 +02:00
Daniel Eklöf
ccb184ae64
osc: kitty notifications: updated support for icons
This implements the suggested protocol discussed in
https://github.com/kovidgoyal/kitty/issues/7657.

Icons are handled by loading a cache. Both in-band PNG data, and
symbolic names are allowed.

Applications use a graphical ID to reference the icon both when
loading the cache, and when showing a notification.

* 'g' is the graphical ID
* 'n' is optional, and assigns a symbolic name to the icon
* 'p=icon' - the payload is icon PNG data. It needs to be base64
  encoded, but this is *not* implied. I.e. the application *must* use
  e=1 explicitly.

To load an icon (in-band PNG data):

    printf '\e]99;g=123:p=icon;<base64-encoded-png-data>\e\\'

or (symbolic name)

    printf '\e]99;g=123:n=firefox:p=icon;\e\\'

Of course, we can combine the two, assigning *both* a symbolic
name, *and* PNG data:

    printf '\e]99;g=123:n=firefox:p=icon;<base64-encoded-png>\e\\'

Then, to use the icon in a notification:

    printf '\e]99;g=123;this is a notification\e\\'

Foot also allows a *symbolic* icon to be defined and used at the same
time:

    printf '\e]99;g=123:n=firefox;this is a notification\e\\'

This obviously won't work with PNG data, since it uses the payload
portion of the escape sequence.
2024-07-23 11:29:05 +02:00
Daniel Eklöf
c7cffea9ee
notify: stdout is a bad name 2024-07-23 09:42:14 +02:00
Daniel Eklöf
b319618af1
notify: XDG token is now expected to be prefixed with xdgtoken=
This patch modifies our stdout reader to consume input as we go,
instead of all at once when stdout is closed. This will make it easier
to add support for reading e.g. the daemon assigned notification ID in
the future, and also ensures we see the XDG activation token "as soon
as possible".

Furthermore, to be more future proof, require the XDG activation token
to be prefixed with 'xdgtoken=', and ignore other lines.

Thus, instead of treating *all* of stdout as the XDG activation token,
parse stdout line-by-line, and ignore everything that does not begin
with 'xdgtoken='. Everything (on that line) following 'xdgtoken=' is
treated as the activation token.
2024-07-23 09:33:18 +02:00
Daniel Eklöf
e52d6e3fb8
osc: kitty notifications: use xstrjoin() instead of xasprintf() 2024-07-23 08:05:19 +02:00
Daniel Eklöf
e88ec86c93
pgo: update notify_notify() prototype, add notify_free() 2024-07-23 07:43:56 +02:00
Daniel Eklöf
7268ee9078
pgo: update spawn() prototype 2024-07-23 07:43:42 +02:00
Daniel Eklöf
0209458cc0
changelog: new desktop-notifications config section 2024-07-23 07:17:21 +02:00
Daniel Eklöf
5905ea0d84
osc: kitty notifications: implement focus|report
This patch adds support for window focusing, and sending events back
to the client application when a notification is closed.

* Refactor notification related configuration options:
    - add desktop-notifications sub-section
    - deprecate 'notify' in favor of 'desktop-notifications.command'
    - deprecate 'notify-focus-inhibit' in favor of
      'desktop-notifications.inhibit-when-focused'
* Refactor: rename 'struct kitty_notification' to 'struct
  notification'
* Pass a 'struct notification' to notify_notify(), instead of many
  arguments.
* notify_notify() now registers a reaper callback. When the notifier
  process has terminated, the notification is considered closed, and we
  either try to focus (activate) the window, or send an event to the
  client application, depending on the notification setting.
* For the window activation, we need an XDG activation token. For now,
  assume *everything* written on stdout is part of the token.
* Refactor: remove much of the warnings from OSC-99; we don't
  typically log anything when an OSC/CSI has invalid values.
* Add icon support to OSC-99. This isn't part of the upstream
  spec. Foot's implementation:
    - uses the 'I' parameter
    - the value is expected to be a symbolic icon name
    - a quick check for absolute paths is done, and such icon requests
      are ignored.
* Added ${icon} to the 'desktop-notifications.command' template. Uses
  the icon specified in the notification, or ${app-id} if not set.
2024-07-23 07:17:21 +02:00
Daniel Eklöf
12152a8ae4
unicode-mode: disable debug logging 2024-07-23 07:17:21 +02:00
Daniel Eklöf
69f56b86b7
wayland: add wayl_activate()
wayl_activate() takes an XDG activation token and does an XDG
activation request.
2024-07-23 07:17:21 +02:00
Daniel Eklöf
a42f990818
spawn: add optional reaper callback, return pid_t
This will allow spawn() callers to do things when the spawned process
has terminated.
2024-07-23 07:17:21 +02:00
Daniel Eklöf
57af75f988
osc: kitty notifications: use body as title, if no title is set
This mirrors kitty's behavior; if the user didn't set a title, but did
set the body/text, use the body as title instead.
2024-07-23 07:17:21 +02:00
Daniel Eklöf
b0bf8ca5f7
osc/notify: add support for OSC-99, kitty desktop notifications
This adds limited support for OSC-99, kitty desktop notifications[^1]. We
support everything defined by the "protocol", except:

* 'a': action to perform on notification activation. Since we don't
  trigger the notification ourselves (over D-Bus), we don't know a)
  which ID the notification got, or b) when it is clicked.
* ... and that's it. Everything else is supported

To be explicit, we *do* support:

* Chunked notifications (d=0|1), allowing the application to append
  data to a notification in chunks, before it's finally displayed.
* Plain UTF-8, or base64-encoded UTF-8 payload (e=0|1).
* Notification identifier (i=xyz).
* Payload type (p=title|body).
* When to honor the notification (o=always|unfocused|invisible), with
  the following quirks:
    - we don't know when the window is invisible, thus it's treated as
      'unfocused'.
    - the foot option 'notify-focus-inhibit' overrides 'always'
* Urgency (u=0|1|2)

[^1]: https://sw.kovidgoyal.net/kitty/desktop-notifications/
2024-07-23 07:17:21 +02:00
Daniel Eklöf
45c7cd3f74
input: allow mouse selections to start inside the margins
Before this, margins were special cased:

* The mouse cursor was always a pointer, and never an I-beam (thus
  signaling selections cannot be made).
* The internal mouse coords where set to -1 when the cursor was inside
  the margins, causing:
    - text selections from being made
    - mouse events being passed to mouse grabbing applications

In particular, even with a one-pixel margin, making selections was
unnecessarily hard in e.g. fullscreen mode, where you'd expect to be
able to throw the cursor into the corner of the screen and then start
a selection.

With this patch, the cursor is treated as if it was in the first/last
column/row, when inside the margin(s).

An unintended side-effect of this, initially, was that auto-scrolling
selections where way too easy to trigger, since part of its logic is
checking if the cursor is inside the margins.

That problem has been reduced by two things:

* auto-scrolling does not occur unless a selection has been
  started. That is, just holding down the mouse in the margins and
  moving up/down doesn't cause scrolling. You have to first select at
  least one cell in the visible viewport.
* A selection isn't fully started (i.e. a cell is actually selected)
  unless the cursor is inside the actual grid, and *not* in the
  margins.

What does the last point mean? We now allow a selection to be
_started_ when clicking in the margin. What this means internally is
we set a start coordinate for a selection, but *not* and end
coordinate. At this point, we don't have an actual selection. Nothing
is selected, and no cells are highlighted, graphically.

This happens when we set an end coordinate. Without the last bullet
point, that would happen as soon as the cursor was _moved_, even if
still inside the margins. Now, we require the cursor to leave the
margins and touch an actual cell before we set an end coordinate.

Closes #1702
2024-07-19 06:55:28 +02:00
Daniel Eklöf
38461eef6f
csi: in-band window resize notifications, private mode 2048
This implements
https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83,
in-band window resize notifications.

When user enables private mode 2048 (in-band resize
notifications), *always* send current size, even if the mode is
already active.

This ensures applications can rely on getting a reply from the
terminal.
2024-07-19 06:54:32 +02:00
Daniel Eklöf
e11a4ab6af
wayland: #ifdef guard code related to wl_shm_release() 2024-07-18 14:27:40 +02:00
Daniel Eklöf
87aac8708d
foot.info: add setal (colored underlines)
This is an alias to Setulc. Upstream (ncurses) terminfo uses setal
instead of Setulc :/
2024-07-18 09:04:39 +02:00
Daniel Eklöf
065eb05e3e
meson/pgo: fix PGO build errors with recent meson(?) versions
The back-reference to 'tokenize.c' in the parent directory causes PGO
build failures, where gcc can't find the PGO data. Likely due to
path/naming issues caused by meson's generated build directories.
2024-07-18 09:02:42 +02:00
Daniel Eklöf
36e4435bbf
log: respect the NO_COLOR environment variable
http://no-color.org/

Closes #1771
2024-07-18 08:44:30 +02:00
Daniel Eklöf
4f25e1ba9f
wayland: use wl_shm v2 if available 2024-07-18 08:23:25 +02:00
abs3nt
1fd4076082
themes: catppuccin: replace with updated flavors
Pulled from https://github.com/catppuccin/foot
2024-07-18 08:21:14 +02:00
Daniel Eklöf
1136108c97
input: don't map wheel events to BTN_{BACK,FORWARD}
BTN_BACK and BTN_FORWARD are separate buttons. The scroll wheel don't
have any button mappings in libinput/wayland, so make up our own
defines.

This allows us to map them in mouse bindings.

Also expose BTN_WHEEL_{LEFT,RIGHT}. These were already defined, and
used, internally, to handle wheel tilt events. With this, they can
also be used in mouse bindings.

Finally, fix encoding used for BTN_{BACK,FORWARD} when sending mouse
button events to the client application. Before this, they were mapped
to buttons 4/5. But, button 4/5 are for the scroll wheel, and as
mentioned above, BTN_{BACK,FORWARD} are not the same as scroll wheel
"buttons".

Closes #1763
2024-07-13 10:41:10 +02:00
Daniel Eklöf
15c0078c2d
changelog: remove entry for change that hasn't yet been merged 2024-07-13 10:40:37 +02:00
Daniel Eklöf
56556e5f23
render: hollow-cursor: use correct cursor color 2024-07-13 10:37:21 +02:00
Daniel Eklöf
c46c124363
render: cursor: use default fg/bg if cell fg/bg are the same
When deciding which colors to use for the cursor, and the cursor text
and background colors are the same, use the default fg/bg instead.

Closes #1761
2024-07-13 10:30:23 +02:00
Nicolas Kolling Ribas
f066fe47f0 themes: add nvim-dark and nvim-light themes
Both based on the new "Nvim branded" default color scheme in
Neovim 0.10.
2024-07-09 01:22:37 -03:00
Daniel Eklöf
85b2fb1e32
doc: foot.ini: line-height: add warning about runtime font size changes 2024-07-07 16:31:40 +02:00
Daniel Eklöf
22c8637610
osc: extend damage-cells-by-color to default fg/bg as well
When changing part of the color palette, through either OSC-4, or
OSC-10 and OSC-11 (and the corresponding reset OSCs: 104, 110 and
111), only dirty affected cells.

We've always done this, but only for OSC-4.

This patch breaks out that logic, and extends it to handle default
fg/bg too.

It also fixes a bug where cells with colored underlines were not
dirtied if the underline was the only part of the cell that was
affected by a OSC-4 change.
2024-07-03 10:53:33 +02:00
Daniel Eklöf
e5ed387426
Merge branch 'color-stack'
Closes #856
2024-07-03 09:59:56 +02:00
Daniel Eklöf
dd58dad15a
csi: redraw margins after restoring the palette 2024-07-03 09:47:51 +02:00
Daniel Eklöf
d440d5aa2c
osc: 10/11/12/17/19: don't apply overly much damage 2024-07-03 09:47:51 +02:00