Commit graph

220 commits

Author SHA1 Message Date
Daniel Eklöf
fb77637eb9
term: only scale using DPI if *all* monitors have a scaling factor or one
With dpi-aware=auto (the default), scale fonts using DPI *only*
if *all* available monitors have a scaling factor of one.

The idea is this: if a user, with multiple monitors, have enabled
scaling on *at least* one monitor, he/she has most likely done so to
match the size of his/hers other monitors.

For example, if the user has one monitor with a scaling factor of one,
and another one with a scaling factor of two, he/she expects things to
be twice as large on the second monitor.

If we (foot) scale using DPI on the first monitor, and using the
scaling factor on the second monitor, foot will *not* look twice as
big on the second monitor (this was the old behavior of
dpi-aware=auto).

Part of #714
2021-09-24 22:07:47 +02:00
Nihal Jere
52f50c556d
wayland: set scale to 1 by default
The wl_output protocol specifies that the client should assume
that scale is 1 if not set by the compositor.
2021-07-26 11:18:37 +02:00
Daniel Eklöf
bcd28311f4
wayland: prevent hang when terminating due to broken Wayland connection
If the call to fdm_wayl() with EPOLLHUP was followed by calls to
wayl_roundtrip(), foot would hang.

The reason for this is that the EPOLLHUP handler in fdm_wayl() would
call wl_display_cancel_read().

wayl_roundtrip() also calls wl_display_cancel_read() (since we
normally have called wl_display_prepare_read()), before calling
wl_display_roundtrip().

When calling wl_display_cancel_read() two times in a row, without a
wl_display_prepare_read() in between, wl_display_roundtrip() hangs.

Fix by not calling wl_display_cancel_read() in fdm_wayl(). This
ensures our invariant holds: wl_display_prepare_read() is *always* in
effect outside of fdm_wayl().

Closes #651
2021-07-24 20:38:56 +02:00
Daniel Eklöf
50f59fe575
config: add csd.font option 2021-07-24 11:02:43 +02:00
Daniel Eklöf
0cf7a19616
render: csd_title(): use a custom font, sized based on the title bar’s height
We still use the primary font, but use a custom size, based on the
title bar’s height.

This fixes an issue where the window title could be way too small, or
way too big. And changed size when the terminal font size was changed.
2021-07-24 11:02:42 +02:00
Daniel Eklöf
20fc80e57e
render: use a single backing SHM pool for CSD surface buffers 2021-07-18 16:46:43 +02:00
Daniel Eklöf
53851e13ec
shm: refactor: move away from a single, global, buffer list
Up until now, *all* buffers have been tracked in a single, global
buffer list. We've used 'cookies' to separate buffers from different
contexts (so that shm_get_buffer() doesn't try to re-use e.g. a
search-box buffer for the main grid).

This patch refactors this, and completely removes the global
list.

Instead of cookies, we now use 'chains'. A chain tracks both the
properties to apply to newly created buffers (scrollable, number of
pixman instances to instantiate etc), as well as the instantiated
buffers themselves.

This means there's strictly speaking not much use for shm_fini()
anymore, since its up to the chain owner to call shm_chain_free(),
which will also purge all buffers.

However, since purging a buffer may be deferred, if the buffer is
owned by the compositor at the time of the call to shm_purge() or
shm_chain_free(), we still keep a global 'deferred' list, on to which
deferred buffers are pushed. shm_fini() iterates this list and
destroys the buffers _even_ if they are still owned by the
compositor. This only happens at program termination, and not when
destroying a terminal instance. I.e. closing a window in a “foot
--server” does *not* trigger this.

Each terminal instatiates a number of chains, and these chains are
destroyed when the terminal instance is destroyed. Note that some
buffers may be put on the deferred list, as mentioned above.
2021-07-17 19:14:42 +02:00
Daniel Eklöf
5d7b729ac5
wayland: win_destroy: unmap URL labels 2021-07-15 18:45:25 +02:00
Daniel Eklöf
a9872aac5a
wayland: explicitly purge all SHM pixmaps when destroying window
All SHM pixmap cookies depend on the terminal instance’s memory
address. Thus, after a terminal instance has been destroyed, shm
pixmaps that belonged to it will never be purged automatically.
2021-07-11 10:01:22 +02:00
Daniel Eklöf
b5950d9b27
wayland: purge CSD pixmaps when destroying the CSDs
CSDs aren’t typically toggled on and off. Thus, when disabled,
immediately purge their corresponding pixmap buffers, to free up some
memory, and release file descriptors.
2021-07-11 09:59:25 +02:00
Daniel Eklöf
0a6e7e6167
url-mode: purge SHM pixmaps when destroying URLs
Unlike other surface types, the SHM cookie depends on the address of
each URL instance. This means if we enable, disable, and then enable
URL mode again (thus showing exactly the same URLs as the first time),
the URLs will have new addresses, and thus the old SHM pixmaps will
not get purged automatically.

So, manually purge them when destroying the URLs.
2021-07-11 09:59:17 +02:00
Daniel Eklöf
20c0650dfd
wayland: regression: properly instantiate CSDs when there’s no decoration manager
* Set win->configure.csd_mode, not win->csd_mode. Otherwise our
  ‘configure’ handler will swap out the CSD_YES we set, for
  CSD_UNKNOWN(?), resulting in no CSDs at all.

* Don’t instantiate the CSDs in wayl_win_init(), let the ‘configure’
  event handler do that. Just like it does when we have a decoration
  manager emitting decoration configure events.
2021-06-24 23:02:40 +02:00
Daniel Eklöf
2a83202fdd
wayland: apply CSD/SSD changes in the surface configure event
The configure event asks the client to change its decoration
    mode. The configured state should not be applied immediately.
    Clients must send an ack_configure in response to this event.
    See xdg_surface.configure and xdg_surface.ack_configure for
    details.

In particular, ”the configured state should *not* be applied
immediately”.

Instead, treat CSD/SSD changes like all other window dimension related
changes: store the to-be mode in win->configure, and apply it in the
surface configure event.

This fixes an issue where foot incorrectly resized the window when the
server switched between CSD/SSD at run-time.
2021-06-23 12:37:56 +02:00
Daniel Eklöf
c3c2ff7398
wayland: fdm callback: check return value of wl_display_dispatch_pending()
Since it’s inside a while-loop, we’d better handle failures, or we
risk getting stuck.
2021-05-25 17:50:17 +02:00
Daniel Eklöf
7bdecaae3b
wayland: roundtrip: log error and abort when wl_display_roundtrip() fails
ayl_roundtrip() has the following code:

    wl_display_roundtrip(wayl->display);

    while (wl_display_prepare_read(wayl->display) != 0)
        wl_display_dispatch_pending(wayl->display);
    wayl_flush(wayl);

If the first wl_display_roundtrip() fails, for example because the
Wayland socket has been closed, we may get stuck in the while-loop.

This happens if the read queue isn’t empty, in which case
wl_display_prepare_read() will return -1 and we’ll continue trying to
dispatch the pending events forever, never succeeding since the socket
is gone.

Closes #542
2021-05-25 17:50:17 +02:00
Daniel Eklöf
2afc678236
term: get rid of term->font_scale, use term->scale only
We only needed term->font_scale to be able to detect scaling factor
changes (term->font_scale != term->scale).

But, we already have the old scaling factor in all places where
term_font_dpi_changed() is called, so let’s pass the old scaling
factor as an argument instead.
2021-05-17 17:55:49 +02:00
Daniel Eklöf
584d2cacf1
wayland: workaround epoll-shim defining the macro close 2021-05-14 13:26:13 +02:00
Daniel Eklöf
03e1b906ab
meson: add xdg-activation-v1.xml conditionally
Only enable XDG activation when compiling against wayland-protocols
1.21. Older versions don’t have this protocol.

When available, define HAVE_XDG_ACTIVATION.

Make all usages of xdg_activation_v1 and xdg_activation_token_v1
conditional.
2021-05-14 13:26:13 +02:00
Daniel Eklöf
f5f1bc8dd9
wayland: set xdg activation token surface to our top-level 2021-05-14 13:26:13 +02:00
Daniel Eklöf
3e92361534
xdg-activation: initial support for setting urgency using XDG activation 2021-05-14 13:26:04 +02:00
Daniel Eklöf
1501d36470
wayland: codespell: pre-empt -> preempt 2021-05-11 08:02:46 +02:00
Daniel Eklöf
2e8bea0a5d
wayland: add comment describing the configure preempt workaround 2021-05-10 17:57:14 +02:00
Daniel Eklöf
44a166dde8
wayland: {xdg_,}output_*(): free old strings before assigning new ones
Defensive programming; output_geometry() etc are typically only called
once for an output instance. But let’s ensure we’re not leaking memory
if it’s called more than once.
2021-04-07 08:04:24 +02:00
Daniel Eklöf
e8ffb05bc7
ime: move preedit state from terminal struct to the seat struct
This ensures different seat’s don’t step on each others IME pre-edit
state.

It also removes most dependencies on having a valid term pointer for
many IME operations.

We’re still not all the way, since we support disabling IME with a
private mode, which is per terminal, not seat.

Thus, we still require the seat to have keyboard focus on one of our
windows.

Closes #324. But note that *rendering* of multiple seat’s IME pre-edit
strings is still broken.
2021-03-25 09:36:07 +01:00
Daniel Eklöf
3149ef16c3
wayland: rename variable ‘main’ to ‘main_surface’
Some compilers don’t think we know what we’re doing:

  ../wayland.c:1554:24: error: ‘main’ is usually a function
2021-02-25 07:46:21 +01:00
Daniel Eklöf
7b5a43bcbd
wayland: csd_instantiate(): remove TODO
The sub-surfaces are working just fine without the initial commit.
2021-02-17 21:48:39 +01:00
Daniel Eklöf
5c8579043d
wayland: drop ‘_surface’ suffix from subsurface struct instances 2021-02-17 21:48:08 +01:00
Daniel Eklöf
438853a2d8
render-timer: use wayl_win_subsurface_new/destroy() 2021-02-17 21:48:08 +01:00
Daniel Eklöf
c8324943de
scrollback-indicator: use wayl_win_subsurface_new/destroy() 2021-02-17 21:48:08 +01:00
Daniel Eklöf
e049124f6d
search: use wayl_win_subsurface_new/destroy() 2021-02-17 21:48:07 +01:00
Daniel Eklöf
587f04f2e1
csd: use wayl_win_subsurface_new/destroy() 2021-02-17 21:48:07 +01:00
Daniel Eklöf
9d362158e3
url-mode: convert struct wl_url to use wayl_win_subsurface_new() 2021-02-17 21:48:07 +01:00
Daniel Eklöf
bb4d9a5fd3
wayland: add wayl_win_subsurface_new() and wayl_win_subsurface_destroy()
These are utility functions to create a Wayland subsurface associated
with the window.
2021-02-17 21:47:57 +01:00
Daniel Eklöf
79e054faff
Merge branch 'refactor-key-bindings' 2021-02-08 18:57:17 +01:00
Daniel Eklöf
4bad85b593
misc: when free:ing tll lists, prefer tll_remove() over tll_free()
In many places we have the following pattern:

  tll_foreach(list, it)
     free(it->item.thing);
  tll_free(list);

Since all tll functions are macros, and thus inlined, and since
tll_free in itself expands to a tll_foreach(), the above pattern
expands to more native code than necessary.

This is somewhat smaller:

  tll_foreach(list, it) {
      free(it->item.thing);
      tll_remove(list, it);
  }
2021-02-08 10:09:59 +01:00
Daniel Eklöf
03bac9dada
key-bindings: refactor: use a single type for all key bindings
Up until now, the various key binding modes (“normal”, “search” and
“url”) have used their own struct definitions for their key bindings.

The only reason for this was to have a properly typed “action” (using
the appropriate “action” enum).

This caused lots of duplicated code. This patch refactors this to use
a single struct definition for the “unparsed” key bindings handled by
the configuration, and another single definition for “parsed” bindings
used while handling input.

This allows us to implement configuration parsing, keymap translation
and so on using one set of functions, regardless of key binding mode.
2021-02-08 10:09:14 +01:00
Daniel Eklöf
2cc84db979
urls: initial support for detecting URLs and rendering jump-labels
The jump labels work, but is currently hardcoded to use xdg-open
2021-02-07 16:33:31 +01:00
Daniel Eklöf
b255aea3ed
config: free URL bindings 2021-02-07 16:33:31 +01:00
Daniel Eklöf
b4f1f72585
render: don’t center content while doing an interactive resize 2021-01-26 19:32:07 +01:00
Daniel Eklöf
9a1df7bb03
render: delay TIOCSWINSZ while doing an interactive resize
Instead of disabling content centering, delay the TIOCSWINSZ (a.k.a
delay sending the new dimensions to the client) by a small amount
while doing an interactive resize.

Non-interactive resizes are still immediate.

For now, force a resize when the user stops the interactive
resize. This ensures the client application receives the new
dimensions immediately.

It still works without the last, forced, resize, but there typically
be a small delay until the client application receives the final
dimensions.

Closes #301
Closes #283
2021-01-26 19:32:06 +01:00
Daniel Eklöf
773b61eb79
wayland: force a resize on the final configure event after an interactive resize
This is needed to apply content centering after an interactive resize,
as otherwise we’d just ignore the last configure event since the only
difference between that event and the next to last event is that the
is-resizing bit has been cleared. I.e. the window size is identical to
what we already have, and our resize code would thus ignore the event.
2021-01-26 19:32:06 +01:00
Daniel Eklöf
4ebd58e388
wayland: track is-resizing state 2021-01-26 19:32:06 +01:00
Craig Barnes
e56136ce11 debug: rename assert() to xassert(), to avoid clashing with <assert.h> 2021-01-16 20:16:00 +00:00
Daniel Eklöf
deaff095c6
wayland: take rotation into account when calculating the logical PPI 2021-01-11 17:53:27 +01:00
Daniel Eklöf
218ce4ab87
wayland: log warning when compositor does not implement text-input 2020-12-26 12:09:24 +01:00
Daniel Eklöf
ff96ce1e91
input: rework mouse button/motion handling
Store a list of currently pressed buttons, and which surface they
belong to (i.e. which surface that received the press).

Then, in motion events (with a button pressed, aka drag operations),
send the event to the “original” surface (that received the press).

Also send release events to the originating surface.

This means a surface receiving a press will always receive a
corresponding release. And no one will receive a release event without
a corresponding press event.

Motion events with a button pressed will *always* use the *first*
button that was pressed. I.e. if you press a button, start dragging,
and then press another button, we keep generating motion events for
the *first* button.
2020-12-12 19:05:24 +01:00
Daniel Eklöf
05083110c3
ime: make IME compile-time optional 2020-12-07 20:44:10 +01:00
Daniel Eklöf
8c3d48c5cd
ime: render pre-edit text
This is done by allocating cells for the pre-edit text when receiving
the text-input::done() call, and populating them by converting the
utf-8 formatted pre-edit text to wchars.

We also convert the pre-edit cursor position to cell positions (it can
cover multiple cells).

When rendering, we simply render the pre-edit cells on-top off the
regular grid. While doing so, we also mark the underlying, “real”,
cells as dirty, to ensure they are re-rendered when the pre-edit text
is modified or removed.
2020-12-07 20:44:10 +01:00
Daniel Eklöf
5745c610ac
ime: wip: commit all changes in ‘done()’ 2020-12-07 20:44:10 +01:00
Daniel Eklöf
148bb1ff13
ime: wip: add text-input object to seat 2020-12-07 20:44:09 +01:00