Commit graph

340 commits

Author SHA1 Message Date
Craig Barnes
e0f3703ae6
util: add streq() function and use in place of strcmp(...) == 0 2024-02-05 12:09:52 +01:00
Jan Palus
ee02e7b07d
main: correct short option case in help output for disabling syslog 2023-10-27 16:20:23 +02:00
Daniel Eklöf
58d967b2f3
Codespell fixes 2023-10-03 14:11:55 +02:00
Daniel Eklöf
698c5b54f3
wayland: cursor-shape-v1 is now always available
Since we're requiring wayland-protocols >= 1.32
2023-08-07 16:53:19 +02:00
Daniel Eklöf
7eee415b75
wayland: fractional-scale-v1 is now always available
Since we're requiring wayland-protocols >= 1.32
2023-08-07 16:53:19 +02:00
Daniel Eklöf
be22736f23
main: “title%s” -> “title=%s”
Fix regression of --title,-T option. This broken when command line
parsing was switched to using overrides, in
0b4f1b4af2.

Closes #1457
2023-08-05 07:23:11 +02:00
Daniel Eklöf
0b4f1b4af2
main: translate command line options to overrides
Instead of special casing configuration affecting command line
options (like --font, --fullscreen, --maximized etc), translate them
to overrides, and let the configuration system handle them.

This also fixes an issue where -f,--font did not set csd.font, if
csd.font were otherwise unset.
2023-07-31 16:26:17 +02:00
Daniel Eklöf
a361d7917b
main/client: add a version feature flag for cursor-shape 2023-07-03 14:36:33 +02:00
Daniel Eklöf
9db92bd942
feature: add a feature flag (for --version) for fractional scaling 2023-06-29 15:38:24 +02:00
Phillip Susi
8859e134ef
Fix non UTF-8 locale complaint
If the locale isn't UTF-8, foot tries to fall back to C.UTF-8 and
prints a warning.  The warning was garbled because the name of the
original locale is no longer valid after calling setlocale() a
second time.  Use strdup to stash the original string.

Closes #1362
2023-06-01 12:12:49 +02:00
jdevdevdev
134b54dfe0
.desktop: remove StartupWMClass from server, use distinct StartupWMClass for foot and footclient
For this to work, the default app-id of footclient has been changed
from ‘foot’ to ‘footclient’.

By using distinct StartupWMClasses, the compositor can connect a
running foot/footclient instance to the correct .desktop-file. This
ensures the correct icon is being used in e.g. docks, and that actions
like “open another window” works correctly.

Note that the user can override the app-id, either by setting app-id
in foot.ini, or with the -a,--app-id command line option.

Closes #1355
2023-05-22 18:57:54 +02:00
Joakim Nohlgård
7bb5c80d04 main: Graceful fallback if user has configured an invalid locale 2022-12-16 08:38:37 +01:00
Antoine Beaupré
b80c7f75fe
change default log level to WARNING
The default foot output looks like this, in Debian testing "bookworm"
at the time of writing:

    anarcat@angela:pubpaste$ foot true
    info: main.c:421: version: 1.13.1 +pgo +ime +graphemes -assertions
    info: main.c:428: arch: Linux x86_64/64-bit
    info: main.c:440: locale: fr_CA.UTF-8
    info: config.c:3003: loading configuration from /home/anarcat/.config/foot/foot.ini
    info: fcft.c:338: fcft: 3.1.5 +graphemes -runs +svg(nanosvg) -assertions
    info: fcft.c:377: fontconfig: 2.13.1, freetype: 2.12.1, harfbuzz: 5.2.0
    info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Regular.otf: size=8.00pt/8px, dpi=75.00
    info: wayland.c:1353: eDP-1: 2256x1504+0x0@60Hz 0x095F 13.32" scale=2 PPI=205x214 (physical) PPI=136x143 (logical), DPI=271.31
    info: wayland.c:1509: requesting SSD decorations
    info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Bold.otf: size=24.00pt/32px, dpi=96.00
    info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Regular.otf: size=24.00pt/32px, dpi=96.00
    info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Bold.otf: size=24.00pt/32px, dpi=96.00
    info: fcft.c:838: /home/anarcat/.local/share/fonts/Fira-4.202/otf/FiraMono-Regular.otf: size=24.00pt/32px, dpi=96.00
    info: terminal.c:700: cell width=19, height=39
    info: terminal.c:588: using 16 rendering threads
    info: wayland.c:859: using SSD decorations
    info: main.c:680: goodbye
    anarcat@angela:pubpaste$

That's 17 lines of output that are *mostly* useless for most use
cases. I might understand having this output during the project's
startup, when it's helpful for diagnostics, but now Foot just mostly
works everywhere, and I've never had a use for any of that stuff in
the (arguably short) time I've been using Foot so far.

And if I do, there's the `--log-level` commandline option to tweak
this. At first, I looked at tweaking the log level through the config
file. But as explained in this issue:

https://codeberg.org/dnkl/foot/issues/1142

... there's a chicken and egg problem there that makes it hard to
implement and possibly confusing for users as well.

There's also the possibility for users to change the shortcut with
which they start foot, for example a `.desktop` file so that menu
systems that support those start foot properly. But that only works in
that environment, and not through the so many things that will just
call `foot` and hope it will do the right thing.

In my case, I have `foot` hardcoded in a lot of places now, between
sway and waybar, and this is only going to grow. Others have suggested
adding the flag to a $TERMINAL global variable, but that won't help
.desktop users.

So, instead of playing whack-a-mole with the log levels, just make it
so that, by default, foot is silent. This is actually one of the
[basics of UNIX philosophy][1]:

> Rule of Silence: When a program has nothing surprising to say, it
> should say nothing.

And yes, I am aware I am severely violating that principle by writing
a way too long commit log for a one-line patch, but there you go, I
figured it was good to document the why of this properly.

[1]: https://web.archive.org/web/20031102053334/http://www.faqs.org/docs/artu/ch01s06.html
2022-11-22 10:22:22 -05:00
Daniel Eklöf
90ce4f3008
main/client: use $PWD for cwd, when $PWD is valid
If $PWD is set, and its resolved path matches the *actual* working
directory, use $PWD for cwd when instantiating the terminal.

This makes a difference when $PWD refers to a symlink; before this
patch, we’d instantiate the terminal in the *resolved* path. Now it’ll
use the symlink instead.
2022-10-02 20:11:16 +02:00
Daniel Eklöf
7e8b5f9610
main: minor rewording of non-UTF8 locale warnings and errors 2022-05-14 09:14:57 +02:00
Daniel Eklöf
24ee3dcc10
wayland: refactor: remove ‘struct config’ pointer from wayland struct
The global config doesn’t necessarily reflect the correct
configuration to use - we should *always* use the current terminal
instance’s conf pointer.

* Move selection override modifier mask to the key_binding_set struct
* Always warn if XDG activation is unavailable, not just if
  bell.urgent is set (we no longer have access to this information)
* Pass ‘bool presentation_timings’ as a parameter to wayl_init()
* Remove ‘presentation_timings’ member from the ‘terminal’ struct

Closes #932
2022-04-17 16:34:04 +02:00
Daniel Eklöf
90a2ca966f
key-binding: new API, for handling sets of key bindings
Up until now, our Wayland seats have been tracking key bindings. This
makes sense, since the seat’s keymap determines how the key bindings
are resolved.

However, tying bindings to the seat/keymap alone isn’t enough, since
we also depend on the current configuration (i.e. user settings) when
resolving a key binding.

This means configurations that doesn’t match the wayland object’s
configuration, currently don’t resolve key bindings correctly. This
applies to footclients where the user has overridden key bindings on
the command line (e.g. --override key-bindings.foo=bar).

Thus, to correctly resolve key bindings, each set of key bindings must
be tied *both* to a seat/keymap, *and* a configuration.

This patch introduces a key-binding manager, with an API to
add/remove/lookup, and load/unload keymaps from sets of key bindings.

In the API, sets are tied to a seat and terminal instance, since this
makes the most sense (we need to instantiate, or incref a set whenever
a new terminal instance is created). Internally, the set is tied to a
seat and the terminal’s configuration.

Sets are *added* when a new seat is added, and when a new terminal
instance is created. Since there can only be one instance of each
seat, sets are always removed when a seat is removed.

Terminals on the other hand can re-use the same configuration (and
typically do). Thus, sets ref-count the configuration. In other words,
when instantiating a new terminal, we may not have to instantiate a
new set of key bindings, but can often be incref:ed instead.

Whenever the keymap changes on a seat, all key bindings sets
associated with that seat reloads (re-resolves) their key bindings.

Closes #931
2022-04-17 15:39:51 +02:00
Daniel Eklöf
99db7aa7cf
config: config_free(): pass conf struct by pointer, not by-value 2022-04-12 15:21:43 +02:00
Daniel Eklöf
d02124902b
client: add -E,--client-environment
When this option is used, the child process in the new terminal
instance will inherit its environment from the footclient process,
instead of the foot server’s.

Implemented by sending (yet another) dynamic string list as part of
the client -> server setup packet. When the new option is *not* used,
the setup packet is now 2 bytes larger than before.

On the server side, the slave process now uses execvpe() instead of
execvp(). There’s plumbing to propagate a new ‘envp’ argument from
term_init() all the way down to slave_exec(). If ‘envp’ is NULL, we
use ‘environ’ instead (thus matching the old behavior of execvp()).

Closes #1004
2022-04-12 15:07:40 +02:00
Daniel Eklöf
8fa16f616c
main: --server: don’t exit with code 0 on failure
A foot --server instance would exit with code 0, even on failure, if
the number of currently open terminal instances were 0.

This is because ‘ret’ assumed failure, and then tried to set it to
‘success’ after the even loop had terminated, basted on the server’s
current state.

Fix by:

* set ‘ret’ to success just before entering the event loop
* set ‘ret’ to failure when we detect an FDM failure
* don’t try to second-guess success/failure after having exited the
  event loop

Closes #943
2022-02-16 22:44:42 +01:00
Craig Barnes
23cf80667a Explicitly initialize sigaction::sa_mask members with sigemptyset(3)
Not doing so before calling sigaction(3) is "undefined" according to
POSIX[1]:

> Applications shall call either sigemptyset() or sigfillset() at least
> once for each object of type sigset_t prior to any other use of that
> object. If such an object is not initialized in this way, but is
> nonetheless supplied as an argument to any of pthread_sigmask(),
> sigaction(), sigaddset(), sigdelset(), sigismember(), sigpending(),
> sigprocmask(), sigsuspend(), sigtimedwait(), sigwait(), or
> sigwaitinfo(), the results are undefined.

The use of designated initializers means that sa_mask members were
still being initialized, but sigset_t is an opaque type and implicit
initialization doesn't necessarily produce the same results as using
sigemptyset(3) (although it typically does on most implementations).

[1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html
2022-02-12 12:26:42 +00:00
Daniel Eklöf
844563a791
main: remove debug logging 2022-02-05 17:22:01 +01:00
Daniel Eklöf
e0227266ca
fcft: adapt to API changes in fcft-3.x
Fcft no longer uses wchar_t, but plain uint32_t to represent
codepoints.

Since we do a fair amount of string operations in foot, it still makes
sense to use something that actually _is_ a string (or character),
rather than an array of uint32_t.

For this reason, we switch out all wchar_t usage in foot to
char32_t. We also verify, at compile-time, that char32_t used
UTF-32 (which is what fcft expects).

Unfortunately, there are no string functions for char32_t. To avoid
having to re-implement all wcs*() functions, we add a small wrapper
layer of c32*() functions.

These wrapper functions take char32_t arguments, but then simply call
the corresponding wcs*() function.

For this to work, wcs*() must _also_ be UTF-32 compatible. We can
check for the presence of the  __STDC_ISO_10646__ macro. If set,
wchar_t is at least 4 bytes and its internal representation is UTF-32.

FreeBSD does *not* define this macro, because its internal wchar_t
representation depends on the current locale. It _does_ use UTF-32
_if_ the current locale is UTF-8.

Since foot enforces UTF-8, we simply need to check if __FreeBSD__ is
defined.

Other fcft API changes:

* fcft_glyph_rasterize() -> fcft_codepoint_rasterize()
* font.space_advance has been removed
* ‘tags’ have been removed from fcft_grapheme_rasterize()
* ‘fcft_log_init()’ removed
* ‘fcft_init()’ and ‘fcft_fini()’ must be explicitly called
2022-02-05 17:00:54 +01:00
Daniel Eklöf
8ca0eaa94c
main: reset signal mask and signal handlers at startup
This ensures processes spawned by us (e.g. the shell, new terminal
instances etc) don’t inherit a flawed signal mask, or having signals
unknowingly ignored.

Closes #854
2022-02-04 18:13:21 +01:00
Daniel Eklöf
d85feb02ed
main: log locale errors (in addition to adding a user notification) 2022-01-13 11:47:43 +01:00
Daniel Eklöf
2bc77ebf09
main: display warning only, when we succeed in enabling a fallback locale 2022-01-13 11:47:42 +01:00
Daniel Eklöf
827bfef550
main: try to force an UTF-8 locale if user’s locale isn’t UTF-8 2022-01-13 11:47:42 +01:00
Daniel Eklöf
9873d2732f
main: present invalid locale errors as a user-notification
Foot does not support running under non-UTF8 locales. If we detect a
non-UTF8 locale, we log this and exit with an error.

However, it appears a fairly common situation is this:

user (knowingly or unknowingly) only configures his/hers locale in
e.g. the shell RC files. These aren’t sourced when the compositor is
started via a display manager.

Thus, compositor key binds will fail to launch, and the user typically
has no way of seeing foot’s output.

So, the user proceeds to start another terminal, and from that one
tries launching foot. And it works... (because the shell in the other
terminal sourced the locale configuration).

User is left confused and often don’t know how to debug.

This patch is somewhat hackish; in addition to logging the locale
error, it also pushes a user notification. For this to be visible, we
need to actually start a terminal window.

So, we ignore the configured shell, and we ignore any custom command
line, and instead spawns “/bin/sh -c ‘’”. This allows us to get
something running (that hopefully doesn’t produce too much output we
can’t decode due to the non-UTF8 locale). But, it will exit
immediately. So we also set the --hold flag.

This works, and may be a good enough “solution”. However, it only
works for standalone foot instances, not footclients.
2022-01-13 11:47:33 +01:00
Daniel Eklöf
9f26b250bb
foot{,client}: handle argc == 0
Our getopt_long() based argument parser would (correctly) break out of
the while loop immediately. However, we would then proceed and
decrement ‘argc’ by 1, resulting in it being -1.

This was then passed to the terminal constructor, which passed it on
to the client application fork+exec logic. That finally resulted in an
exec(3) failure:

   err: slave.c:339: SHELL=/bin/zsh: failed to execute: No such file or directory
   err: fdm.c:215: no such FD: 7
  info: main.c:604: goodbye
2022-01-01 21:17:32 +01:00
Daniel Eklöf
521bd84a99
config: csd.border_width now always reflects the full/total width 2021-12-22 20:21:46 +01:00
Daniel Eklöf
e67639a682
main: ignore SIGPIPE
We want to handle SIGPIPEs without crashing... One way to trigger this
was to use e.g.

  pipe-visible=[cat /foo/bar] Control+Shift+q

That is, pipe output to something that did not consume it. This led
to a SIGPIPE when we tried to write the terminal contents to the pipe,
and crashed the whole foot instance.
2021-12-11 20:19:11 +01:00
Craig Barnes
0e5e68d82e main: improve handling of setlocale(3) return value
There's no need to call setlocale() twice, since the first call
returns the same value as the second.

We also handle a NULL return value explicitly and show a distinct
error message for that case, since it typically indicates a
misconfigured locale and not just a non-UTF8 locale.
2021-11-10 17:41:48 +00:00
Ronan Pigott
99d5bf64bc foot/client: implement xdga client activation
This is an application of the xdg activation protocol that will allow
compositors to associate new foot toplevels with the command that
launched them.

footclient receives an activation token from the launcher which the
compositor can use to track application startup. It passes the token
to the foot server, which then activates the new window with the token
to complete the startup sequence.
2021-10-31 18:52:29 -07:00
Daniel Eklöf
3155ab45fe
foot/client: version info: add +/- assertions 2021-10-23 15:40:54 +02:00
Craig Barnes
ef7919e64d main/client: add no-op "-e" command-line option 2021-09-18 23:40:40 +01:00
Craig Barnes
537cd9b367 main/client: replace some uses of printf() with puts() in print_usage()
FOOT_DEFAULT_TERM is a string literal passed as a -D argument to
the compiler, so it can just be concatenated with the other string
literals, instead of being formatted with printf().
2021-09-18 19:44:04 +01:00
Daniel Eklöf
8ffc556d44
main: verify primary font is monospaced at startup
Load a couple of ASCII glyphs and check if their advance widths
matches. If not, warn the user that the font is probably not
monospaced.

This can be disabled by setting tweak.font-monospace-warn=no.

Closes #704.
2021-08-31 19:58:35 +02:00
Daniel Eklöf
7639186865
terminfo: install to $datadir/foot/terminfo by default, append to TERMINFO_DIRS
As of 2021-07-31, ncurses ships its own version of foot’s terminfo.

Since:

* It doesn’t have the non-standard Sync,Tc,setrgbf,setrgbb
  capabilities.
* It doesn’t set hs,fsl,dsl (statusbar).
* We want to be able to update our termminfo without waiting for an
  ncurses release.
* Foot should be installable and usable on Linux systems that doesn’t
  have the latest ncurses.

we still want to ship our own version. We can however not install it
to the default terminfo location (e.g. /usr/share/terminfo), since it
will collide with the ncurses provided files.

Our options are to either rename our terminfo to something else, or to
keep the name, but install our terminfo files somewhere else.

The first option would be the easy one. However, I think it makes
sense to use the same name. For example, a user that SSH’s into a
remote system that does *not* have our own version installed,
but *does* have the ncurses one, will gracefully fall back to that
one, which is better than manually having to set
e.g. TERM=xterm-256color.

Now, if we want to use the same name, we need to install it somewhere
else. But where? And how do we ensure our version is preferred over
the ncurses one?

I opted to $datadir/foot/terminfo (e.g. /usr/share/foot/terminfo) by
default. It makes it namespaced to foot (i.e. we’re not introducing a
new “standard” terminfo location), thus guaranteeing it wont collide
with ncurses.

To enable applications to find it, we export TERMINFO_DIRS. This is a
list of *additional* directories to search for terminfo files. If it’s
already defined, we *append* to it.

The nice thing with this is, if there’s no terminfo in that
location (e.g. when you SSH into a remote), the default terminfo
location is *also* searched. But only *after* having searched through
TERMINFO_DIRS.

In short: our version is preferred, but the ncurses one (or an older
version of our terminfo package!) will be used if ours cannot be
found.

To enable packagers full control over the new behavior, the existing
meson command line options have been modified, and a new option added:

-Dterminfo=disabled|enabled|auto: *build* and *install* the terminfo
files.

-Dcustom-terminfo-install-location=<path>: *where* the terminfo files
are expected to be found.

This *needs* to be set *even* if -Dterminfo=disabled. For example, if
the packaging script builds and packages the terminfo files separate
from the regular foot build. The path is *relative to $prefix*, and
defaults to $datadir/foot/terminfo.

This is the value that will be appended to TERMINFO_DIRS. Note that
you can set it to ‘no’, in which case foot will *not* set/modify
TERMINFO_DIRS. Only do this if you don’t intend to package foot’s
terminfo files at all (i.e. you plan on using the ncurses ones only).

-Ddefault-terminfo=foot. Allows overriding the default TERM
value. This should only be changed if the target platform doesn’t
support terminfo files.

Closes #671
2021-08-17 21:04:30 +02:00
Craig Barnes
5dca0458a0 log: add LOG_CLASS_NONE and use as initializer for log_level
This means that logging will be completely disabled until log_init()
has been called, which is useful to prevent log spam when running
UNITTEST{} blocks in debug builds.

Note that this doesn't change the default log level at runtime, which
was already being set to LOG_CLASS_INFO in main.c and client.c.

The new log level is also exposed to the command-line interface as
`--log-level=none`, which allows disabling logging entirely.
2021-06-26 22:15:09 +01:00
Daniel Eklöf
a319ddf094
foot: add +/-graphemes to version output 2021-06-24 17:50:30 +02:00
Daniel Eklöf
c6b5ac9299
main: usage: add ‘=’ between --override and its value
This is how all other long options are documented in the usage.
2021-06-23 15:12:08 +02:00
Daniel Eklöf
495c730487
config: don’t use tllist where it isn’t necessary
tllists are great when dealing with dynamically changing lists. They
are also very easy to use when building lists/arrays where the final
size is unknown.

However, this ease of use comes at a price: code size. tll-macros
expand to a lot of code.

Since things in the config are static, once the config has been
loaded, using tllists for configuration data structures doesn’t make
much sense.

This patch replaces nearly all tllists used by the configuration, with
dynamically allocated arrays.
2021-06-18 15:35:57 +02:00
Ryan Farley
f379ffb8ed Override options from command line
Allow any configuration option to be overridden with -o/--override
'section.key=value' arguments, as suggested in #554

update completitions for override

slight refactoring to ease footclient support
2021-06-12 03:05:15 -05:00
Daniel Eklöf
da923100ca
main/client: change exit code
* foot exits with -26/230
* footclient exits with -36/220

This is to give each application a range of exit codes. Currently
unused, but we may want to change this in the future.
2021-05-04 10:41:22 +02:00
Daniel Eklöf
a1b41bd186
foot/footclient: use a custom exit code when foot/footclient fail to run
Normally, foot and footclient uses the exit code from the client
application (i.e. the shell).

However, foot (or footclient) itself may fail to run; if run outside
of a Wayland session, or no fonts are installed, or the client
application/shell cannot be found (“foot lsdjfldsjf”) etc.

Up until now, there has been no way to differentiate these kind of
failures from the client application exiting with code 1.

This patch changes foot’s failure exit code to -27/229, and
footclient’s to -28/228. Note that footclient will exit with foot’s
-27/229 if footclient ran successfully, but the foot server failed to
instantiate a new window.

Closes #466.
2021-05-04 10:40:38 +02:00
Daniel Eklöf
40686303ef
main: explicitly cast log_colorize to enum fcft_log_colorize
Fixes error in Clang builds:

  ../../foot/main.c:376:19: error: implicit conversion from enumeration type 'enum log_colorize' to different enumeration type 'enum fcft_log_colorize' [-Werror,-Wenum-conversion]
      fcft_log_init(log_colorize, as_server && log_syslog, log_level + 1);
      ~~~~~~~~~~~~~ ^~~~~~~~~~~~
2021-04-17 20:09:39 +02:00
Daniel Eklöf
353c2f012a
main: call fcft_log_init(). Note that this requires fcft >= 2.3.90 2021-04-17 19:31:17 +02:00
Daniel Eklöf
9b20764f35
features: --version now logs +/-pgo
That is, whether the binary was compiled with PGO or not.
2021-03-26 20:30:13 +01:00
Chloe Kudryavtsev
80b95eeb7e
config: reuse HAVE_TERMINFO via DEFAULT_TERM
add detection in --help output
also make it more easily accessible for other locations to change
2021-02-26 15:15:05 +01:00
Daniel Eklöf
c600e131e2
main: initialize pseudo-random generator 2021-02-21 20:14:51 +01:00