1
0
forked from mirrors/i3

Compare commits

...

1478 Commits
4.15 ... next

Author SHA1 Message Date
Michael Stapelberg
853b0d9161 i3bar: fix clang compilation error by using const size_t (#6349)
Thanks to Shouη (@Shoun2137 on GitHub) for the suggestion.
2024-12-30 08:29:29 +01:00
Emeric Planet
9dc5230000 Update meson setup command to remove warning (#6338)
This is a very easy fix, to remove the following warning:
```
WARNING: Running the setup command as `meson [options]` instead of `meson setup [options]` is ambiguous and deprecated.
```
The fix is to just run `meson setup` instead and it works like a charm.

Related PRs: i3/i3lock#365 and i3/i3status#538.
2024-12-29 19:50:09 +01:00
Michael Stapelberg
2746e0319b i3bar: work around weird clang compiler behavior
clang used to not warn (= error, with -Werror) about this line. Oh well.
2024-11-06 19:22:15 +01:00
Michael Stapelberg
e107254f1e GitHub Actions: update actions/upload-artifact to v4
The older versions are now deprecated and result in failing GitHub Actions runs.
2024-11-06 19:22:15 +01:00
Michael Stapelberg
2f9ffa3178 debian: update changelog 2024-11-06 18:34:21 +01:00
Michael Stapelberg
d64e5df5b4 Merge branch 'release-4.24' 2024-11-06 18:27:13 +01:00
Michael Stapelberg
454fb63392 Restore non-git version suffix 2024-11-06 18:27:13 +01:00
Michael Stapelberg
4a42eb085c release i3 4.24 2024-11-06 18:26:52 +01:00
Malix
4661e74b5e Fix: remove "dynamic" TWM (#6193)
related to https://github.com/i3/i3.github.io/issues/137
2024-08-05 18:23:55 +02:00
Orestis Floros
d05eed3c01 Consider fullscreen windows maximized (#6153)
Fixes #6148
2024-07-12 09:17:25 +02:00
Orestis Floros
45d8f98fd5 complete-run.pl: Un-set I3SOCK (#6139)
This causes test breakage when the developer/tester is running the tests
in i3, as the actual active instance socket is used instead of the test
instance.

Besides breaking tests, this is quite dangerous as tests like 319-gaps.t
will replace the **actual** config of the user (i.e.
~/.config/i3/config) instead of the current test config.

Broken after #5987
2024-07-10 08:40:50 +02:00
Orestis Floros
05feaecf8a Remove v3 to v4 automatic migration logic (#6144)
Closes https://github.com/i3/i3/issues/6131
2024-07-09 18:03:57 +00:00
Orestis Floros
5413c15e97 Fix crash when reloading config with invalid criteria (#6142)
Came up in https://github.com/i3/i3/discussions/6141
2024-07-09 17:41:11 +02:00
Orestis Floros
be840af45c tiling_drag: Allow swapping containers (#6084)
This was originally mentioned in #3085 but left for a future PR.

One of the noticeable limitations is that pressing the modifier while
the drag is already initiated, will not swap the containers but instead
cancel the drag. This is because of how `drag_pointer()` is written and
would be quite an involved case to handle it.
2024-07-04 21:44:41 +02:00
Orestis Floros
4215998929 GH action: Upload built htmls (#6070) 2024-06-20 07:05:50 +02:00
Orestis Floros
1ee963ede9 Fix crash with focus output and scratchpad (#6079)
The crash was brought up in a comment in
https://github.com/i3/i3/discussions/6076#discussioncomment-9536969

The cause is that the command criteria are matching a window in the
scratchpad. In that case, the assertion in get_output_for_con() fails.
That happens because there is no `Output` for the `Con` output of a
scratchpad window.

I've decided to *not* remove the offending assertion but rather rely on
the caller not using the function with internal containers. My reasoning
is:
1. If get_output_for_con can return NULL then the caller will either
segfault (which is worse) or needs to check the return for NULL.
2. The case where the return can be NULL is already known, it happens
for internal containers.
3. Therefore, the caller should already prevent the situation with a
call to con_is_internal(). Thus, the `assert`ion can remain.

There is also the potential fix of con_get_workspace returning some
arbitrary output (e.g. first in the list or currently focused one)
instead of NULL. This can lead to more tricky to catch bugs.
2024-06-03 17:00:47 +02:00
colona_
11c0a9567f docs/ipc: Add more elaborate description to workspace events (#6089)
This adds some detail to the workspace events documentation and is
written along the same lines as the window events documentation. This
was brought up in [#4392 (issue)](https://github.com/i3/i3/issues/4392).
2024-06-01 09:57:12 +00:00
Orestis Floros
822477cb35 Add popup_during_fullscreen all option (#6068)
Fixes #6062
2024-05-21 17:19:11 +02:00
Orestis Floros
cd6573493c docs/ipc: Fix enumerated list (#6069) 2024-05-21 17:16:23 +02:00
Orestis Floros
1993b7e318 Add popup_during_fullscreen all option 2024-05-20 21:26:27 +02:00
Orestis Floros
3b1747a107 Add tests for popup_during_fullscreen 2024-05-20 21:13:41 +02:00
Tasos Sahanidis
9a69c1eecf Fix size_t format specifiers on 32 bit systems (#6065)
This fixes the following warnings on 32 bit systems

```
[60/108] Compiling C object i3.p/src_regex.c.o
In file included from ../include/all.h:40,
                 from ../src/regex.c:10:
../src/regex.c: In function ‘regex_new’:
../include/log.h:29:33: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 2 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=]
   29 | #define ELOG(fmt, ...) errorlog("ERROR: " fmt, ##__VA_ARGS__)
      |                                 ^~~~~~~~~
../src/regex.c:35:9: note: in expansion of macro ‘ELOG’
   35 |         ELOG("PCRE regular expression compilation failed at %lu: %s\n",
      |         ^~~~
[93/108] Compiling C object i3-input.p/i3-input_main.c.o
../i3-input/main.c: In function ‘finish_input’:
../i3-input/main.c:173:29: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=]
  173 |     printf("occurrences = %ld\n", cnt);
      |                           ~~^     ~~~
      |                             |     |
      |                             |     size_t {aka unsigned int}
      |                             long int
      |                           %d 
```
2024-05-20 13:13:26 +02:00
Orestis Floros
82a1c101fd i3bar: Fix clicks with horizontal padding (#6064)
Fixes #5476
2024-05-20 09:17:16 +02:00
Orestis Floros
093e3cf1f7 docs/ipc: Update information on IPC socket 2024-05-20 09:15:57 +02:00
Orestis Floros
00aaa84ab0 ipc_connect: Delete outdated path 2024-05-20 09:15:57 +02:00
Nikolay Nechaev
caf5b32d5c Reap zombie children on i3 start (#5909)
One case when this might be useful is when i3 is restarted and there are
children that terminate after the previous i3 instance shut down but
before the new one set things up.

Fixes #5756
2024-05-17 21:49:54 +02:00
Theo Buehler
854696cfb5 Remove pledge() support for OpenBSD (#6048)
While this initially worked fine, at some point these patches broke
because libcairo started calling shmget(2) - a syscall not covered by
any pledge promise - and a common pitfall when using pledge with
graphics-oriented applications.

Various attempts were made to fix them, but at some time they were
simply disabled in the OpenBSD port:


a4a9f41dd7
5a03c386ba

This seems pointless and creates needless friction both for the i3 team
who was willing to carry ugly code and for the OpenBSD ports maintainers
who had to disable that code again.

Let's abandon this experiment.
2024-05-17 21:41:45 +02:00
Bimba Laszlo
c06ac08aab docs: Fix "Focus the next output" example (#6054)
The "Focus the next output" example was misleading, fixed the code and
added another comment to the previous code.
2024-05-17 21:38:15 +02:00
Junicchi
1597ec27ee add WINDOW_TYPE_NOTIFICATION to floating list (#6017)
as explained in this discussion:
https://github.com/i3/i3/discussions/5966#discussioncomment-8961295
2024-05-16 07:50:06 +00:00
Orestis Floros
6094944345 testsuite docs: Update instructions (#6034)
- Only recommend local perl library installation
- Update build instructions to match hacking-howto
2024-05-05 10:47:17 +02:00
Orestis Floros
d54a10b200 i3bar-workspace-protocol: Make examples (more) POSIX compliant (#6029)
See https://unix.stackexchange.com/a/581410, `read` needs a variable
name.

Came up in #5939
2024-04-30 13:41:45 +02:00
Orestis Floros
e020701df1 errorlog: Check errorfile exists (#6028)
Fixes #6027
2024-04-30 13:39:54 +02:00
Wesley Schwengle
5834b7e824 Use I3SOCK environment variable for path in AnyEvent::I3 (#5987)
Commit 3ae5f31d0 introduced the I3SOCK environment variable. This
prevents us from having to call `i3 --get-socketpath'. In case the
variable doesn't exist, fall back to the old ways.

Signed-off-by: Wesley Schwengle <wesleys@opperschaap.net>
2024-04-19 19:12:11 +02:00
Michael Stapelberg
91ce3bdbd5 AnyEvent::I3: rip out taint mode compatibility (#5999)
I suspect nobody actually uses Perl’s taint mode with AnyEvent::I3.

See https://github.com/i3/i3/pull/5987 for discussion.
2024-04-19 08:45:34 +02:00
yuvallangerontheroad
ffbbbf3477 Add a newline at the end of the version option output. (#5980)
If there is no newline character at the end of the version option's
output, the next command line prompt is written left to the version,
rather than under it.
2024-04-16 11:38:23 +00:00
Michael Stapelberg
051d3537e3 AnyEvent-I3: bump to 0.19 (#5990)
fixes https://github.com/i3/i3/issues/5986
2024-04-09 17:43:02 +02:00
Wesley Schwengle
d91597b1c1 Check if subscribe event type is supported in AnyEvent::I3 (#5988)
Add simple `if exists' construct in the subscribe function. This
prevents a somewhat cryptic warnings such as these:

Use of uninitialized value $type in hash element at
/usr/share/perl5/AnyEvent/I3.pm line 309.

We still warn the user, but it is much clearer as to what the cause is.

It now shows something like this:

Could not subscribe to event type 'foo'. Supported events are _error
barconfig_update binding mode output shutdown tick window workspace

Signed-off-by: Wesley Schwengle <wesleys@opperschaap.net>
2024-04-09 08:28:40 +02:00
systec-awe
47cab33aa8 Fix missing SIGUSR2 posix signal handling (#5960)
Since there is no separate error handling the `SIGUSR2` signal is
registered to get the write return code after exiting the program.

Fixes #5958

---------

Signed-off-by: Andre Werner <andre.werner@systec-electronic.com>
2024-03-20 12:58:56 +00:00
Orestis Floros
910e58585f Support multiple _NET_WM_STATE changes in one ClientMessage (#5910) 2024-02-12 08:40:39 +01:00
rsgowman
6a530de220 Create new workspaces to the right of existing ones with the same number
i.e. creating workspaces named "1", "2:a", "2:b", "3" should result in
that same order rather than "1", "2:b", "2:a", "3".
2024-02-06 20:28:20 +01:00
rsgowman
0639167185 Don't skip identically numbered workspaces when moving to next/prev (#4578)
eg if you have workspaces: { 1, 2:a, 2:b, 3 } and are on workspace 1,
then 'workspace next' should traverse 1 -> 2:a -> 2:b -> 3 -> 1 instead
of 1 -> 2:a -> 3 -> 1.

Fixes #4452
2024-02-06 20:07:21 +01:00
Orestis Floros
60cc6ce174 Use new GitHub issue templates (#5900)
Biggest benefit is that the users are presented with a set of editable
fields instead of having to edit markdown directly in a text box, which
is less friendly. Links to userguide and IPC docs are clickable in the
description.

See
https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository
2024-02-05 08:27:31 +01:00
Harimbola Santatra
b9a796b24a doc: update meson build instruction (#5899)
The [official build instruction][1] are deprecated on Meson 1.3.1.
These command:

    mkdir -p build && cd build
    meson ..
    ninja

... work but will yield the following warning:

> WARNING: Running the setup command as `meson [options]` instead of `meson setup [options]` is ambiguous and deprecated.

Here's the correct way, according to the [meson documentation][2]:

    mkdir -p build
    meson setup build
    meson compile -C build
    meson install -C build


[1]: https://i3wm.org/docs/hacking-howto.html#_building_i3
[2]: https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project
2024-02-04 15:50:36 +01:00
Orestis Floros
f8befe378a Avoid creating redundant containers when switching between tabbed/stacked and split layouts (#5469)
Fixes #3001
2024-01-31 08:14:32 +01:00
Orestis Floros
230147c815 smart_borders: Deprecate option (#5889)
This had pretty much identical behaviour to hide_edge_borders which made
it confusing. The `hide_edge_borders smart_no_gaps` implementation has an extra check
which fixes #5406.
2024-01-30 08:53:32 +01:00
Orestis Floros
c3173af2f1 Merge pull request #5787 from elebow/userguide-default_border-title-layout-note
docs: Add note to `default_border` about title bar in stacking/tabbed
2024-01-28 13:00:16 +01:00
Alessandro Vinciguerra
ca510e5e0f Shrinking on a per-block basis (#5818)
Co-authored-by: Orestis Floros <orestisflo@gmail.com>
2024-01-28 11:30:28 +01:00
Orestis Floros
f169624560 clang-format: enable InsertBraces (#5882)
Enforces a rule that we have followed for years now. Yes, the diff is
quite big but we get it over with once and we prevent having to nit-pick
future PRs.
2024-01-27 11:37:05 +01:00
Orestis Floros
5fdfb14530 con_is_maximized: Fix case where parent is workspace (#5880)
See added test for simple example.
2024-01-26 08:51:28 +01:00
Seth Pollen
a56670bca8 split up compound test assertions 2024-01-24 14:29:01 +01:00
sethpollen
b660d6a902 Add support for _NET_WM_STATE_MAXIMIZED_{HORZ, VERT} (#5840)
If a window occupies the entirety of its workspace vertically and/or horizontally, pass it the _NET_WM_STATE_MAXIMIZED_{HORZ, VERT} atoms. This helps applications like Google Chrome draw the tab bar correctly and handle tab clicks correctly (see https://crbug.com/1495853).

This change is based on work from @yshui in #2380.
2024-01-22 20:34:40 +01:00
Yonas Yanfa
9aba43119b Make raphamorim/rio one of i3's sensible terminals. 2023-12-13 12:45:14 +02:00
Eddie Lebow
96d3762712 docs: Add note to default_border about title bar in stacking/tabbed
See <https://github.com/i3/i3/issues/2664>.
2023-11-26 02:38:02 -05:00
Orestis Floros
69f68dcd74 focus workspace: consider workspace_auto_back_and_forth (#5754)
Additionally, adds some tests for the command.

Fixes #5744
2023-11-05 11:08:44 +01:00
Orestis Floros
a36618f96c Clean up old release notes (#5753) 2023-11-05 11:08:10 +01:00
Orestis Floros
b42dc21068 bindings: Do not grab pointer when executing bindings (#5755)
Grabing the pointer produces a `GrabFrozen` error in applications that
are run from key bindings. Since we don't need the pointer in such
cases, we can change the call to use ASYNC. This seems to be a
historical leftover.

I've tested locally that these still work:
- bindsym $mod+x ...
- bindsym --release $mod+x ...
- bindsym $mod+button1 ...
- bindsym --release $mod+button1 ...
- bindsym --release $mod+x exec program that grabs the keyboard
  now works (see original issue)

Even in the main branch, I actually couldn't get `import` and `xdotool`
to fail with the pointer being frozen, potentially because these
programs wait a bit for the pointer to be unfrozen like i3lock does.

This patch came up in
https://github.com/i3/i3/issues/5735#issuecomment-1781321011

I wonder why the pointer is actually grabbed.

The argument I change in `xcb_grab_key` there, is `pointer_mode`, from
https://www.x.org/releases/X11R7.7/doc/man/man3/xcb_grab_key.3.xhtml:
```
pointer_mode

One of the following values:
XCB_GRAB_MODE_SYNC

The state of the keyboard appears to freeze: No further keyboard events are generated by the server until the grabbing client issues a releasing AllowEvents request or until the keyboard grab is released.

XCB_GRAB_MODE_ASYNC

Keyboard event processing continues normally.
```

I traced via `git blame` the usage of `xcb_grab_key` throughout 14 years
of i3 development and it seems that `pointer_mode` was always set to
`XCB_GRAB_MODE_SYNC`, going all the way back to
b664456706.

Fixes #5735
2023-11-05 11:04:04 +01:00
a-kenji
f1f2282947 docs: fix typo in i3bar-workspace-protocol 2023-11-04 12:18:03 +01:00
Michael Stapelberg
1da50c4ae0 debian: update changelog 2023-10-29 15:42:25 +01:00
Michael Stapelberg
06b3137bd7 Merge branch 'release-4.23' 2023-10-29 09:58:05 +01:00
Michael Stapelberg
ee12c2d1e1 Restore non-git version suffix 2023-10-29 09:58:05 +01:00
Michael Stapelberg
f844de8e66 release i3 4.23 2023-10-29 09:57:51 +01:00
Sergey Zhmylove
26608b74d9 Fix failing testcase when the font exists (#5679)
When the font from testcase's config exists on the system,
load_configuration() does not fallback to a 'fixed' one resulting in a
fail of this case.
The fallback scenario is added as well.
2023-09-23 17:06:54 +02:00
Orestis Floros
5489db6bc8 motif hints: respect maximum border style in append_layout 2023-09-21 18:55:01 +02:00
Orestis Floros
f4959d5da4 Update to clang-format-15 2023-09-21 18:55:01 +02:00
Orestis Floros
bffa4a543c userguide: Add an example for negative lookeaheads (#5665) 2023-09-13 08:42:52 +02:00
Orestis Floros
908c86544b remanage_window: Refactor to make clearer when a swallowing happens 2023-09-06 17:24:53 +02:00
Orestis Floros
82b9821204 Remanage window after urgency flag change
Fixes #5658
2023-09-06 17:24:53 +02:00
Orestis Floros
c1c405f4fc Update to actions/checkout@v4 (#5653)
Update to [actions/checkout@v4](https://github.com/actions/checkout/releases/tag/v4.0.0)

According to https://github.com/actions/checkout/issues/1448 it might fix the issue we are encountering. Even if it doesn't, no apparent harm from using the latest version.
2023-09-05 17:18:38 +02:00
Wesley Schwengle
c6befec0fd Fix dead links for Modern Perl book
Closes: #5523

Signed-off-by: Wesley Schwengle <wesleys@opperschaap.net>
2023-09-04 16:09:05 +02:00
Orestis Floros
c6f62f4695 Fix crashes when using machine criterion (#5650)
Fixes #5616
2023-09-03 19:32:42 +02:00
Uli Schlachter
d6e2a38b5c Share graphics context globally (#4376)
Instead of creating a graphics context for every surface_t, this commit
adds a cache that allows to "remember" up to two GCs. Thus, the code
uses less GCs. When a GC from the cache can be used, this also gets rid
of a round-trip to the X11 server. Both of these are tiny, insignificant
savings, but so what?

Since GCs are per-depth, this code needs access to get_visual_depth().
To avoid a code duplication, this function is moved to libi3.

Fixes: https://github.com/i3/i3/issues/3478
Signed-off-by: Uli Schlachter <psychon@znc.in>
2023-07-22 10:24:13 +02:00
slyshot
6fe98f7847 Remove focus workaround 2023-07-21 13:52:44 +02:00
Orestis Floros
9947890472 Fix gcc false-positive warning 2023-07-15 21:27:11 +02:00
Orestis Floros
cf2ea348c7 debugging docs: Add note about ptrace
Also remove outdated section about IRC
2023-07-15 21:27:11 +02:00
Orestis Floros
e6b41172da Regrab buttons on mode change (#5554)
Unfortunately, grabbing / ungrabbing doesn't seem to work correctly in
xvfb so we can't really test this.

I also fixed the deduplication code in bindings_get_buttons_to_grab().
2023-06-30 08:57:19 +02:00
Harm te Hennepe
866e3dd909 Improve documentation regarding tiling drag (#5541) 2023-06-26 14:43:33 +02:00
Nikolay Nechaev
3ae5f31d04 Remove the double forking in start_application (#5510)
Having just a single fork is beneficial, as it preserves the approprate
parent information for the children of i3, which is useful in some
scenarious e.g. when a child wants to do something on the wm's exit
(possible via `prctl(PR_SET_PDEATHSIG, ...)`).

Moreover, this is a zero-cost benefit: i3 is already using libev with
the default loop, which automatically reaps all the zombie children even
when there is no corresponding event set.

Resolves #5506
2023-06-15 08:38:35 +02:00
Orestis Floros
a95870120c fix workspace not being focused on title bar scroll (#5518) 2023-05-29 14:08:46 +02:00
Orestis Floros
fde43a078b Merge pull request #5378 from slyshot/next
Fix top border resizing registered on tiled windows
2023-05-05 14:15:47 +02:00
slyshot
a715c03d30 Fix top border resizing registered on tiled windows 2023-04-27 20:20:41 -04:00
Orestis Floros
fae2b637ee i3-input: Avoid compiler warning (#5480)
Also updates the function to use proper types, const and style.

The warning:

../i3/i3-input/main.c: In function ‘finish_input’:
../i3/i3-input/main.c:187:13: warning: ‘__builtin_strncat’ specified bound depends on the length of the source argument [-Wstringop-overflow=]
  187 |             strncat(dest, command, inputlen);
      |             ^
../i3/i3-input/main.c:175:20: note: length computed here
  175 |     int inputlen = strlen(command);

Which is triggered because gcc thinks it's bad that `input_len` (the
length of the source in the copy) is used instead of a length that is
inside the limits of the allocated size for the destination. However, in
practice, `full_len` is always than `input_len`.
2023-04-22 18:59:03 +02:00
Orestis Floros
d06f97c4d4 GH Actions: Check for gcc before deploying (#5483)
Fixes #5482
2023-04-11 20:11:30 +02:00
Orestis Floros
13474ff787 man page: Update outdated information (#5478)
Instead of correcting some of them, I completely deleted them since the
userguide is always more up-to-date.

Fixes #5477
2023-04-10 18:36:02 +02:00
Orestis Floros
74785f4795 Allow switching workspaces when in global fullscreen mode (#5398)
Fixes #2974
2023-04-02 18:55:21 +02:00
Orestis Floros
d7583fbc17 Update some of the hacking docs (#5464) 2023-04-02 16:28:06 +02:00
Orestis Floros
fbb6bf666f hacking-howto: Update build instructions for meson (#5463) 2023-04-02 16:27:16 +02:00
Orestis Floros
892ae730cb Update ubuntu & clang-format in builds (#5467) 2023-04-02 16:24:15 +02:00
Orestis Floros
ecb9b895c7 docker: fix missing address sanitizer dependency (#5466) 2023-04-02 15:39:13 +02:00
Orestis Floros
a5da4d54f3 GitHub Actions: revert changes and use if on each step (#5393) 2023-01-23 19:50:28 +01:00
Orestis Floros
3702960a87 Actions: Fix BASENAME env vars (#5392) 2023-01-23 18:57:08 +01:00
Orestis Floros
6911c116e7 GitHub Actions: push artifacts only on next branch (#5388) 2023-01-23 17:39:55 +01:00
Orestis Floros
bfbe73f665 Merge pull request #5390 from nikitabobko/bobko/userguide
Fix "default binding" mistake in userguide
2023-01-23 13:20:31 +01:00
Nikita Bobko
0f64420281 Fix "default binding" mistake in userguide
Default binding to move window down is $mod+Shift+k, not $mod+Shift+j.
Proof: https://github.com/i3/i3/blob/next/etc/config#L45
This commit reverts this pull request https://github.com/i3/i3/pull/4146
2023-01-23 11:49:37 +01:00
Orestis Floros
26990d90f2 Merge pull request #4311 from i3/i3bar-ws-protocol
i3bar: Add protocol for workspace buttons
2023-01-22 19:05:01 +01:00
Orestis Floros
ba1f40f45f i3bar: Add protocol for workspace buttons
Closes #3818 (parent issue)
Fixes #1808
Fixes #2333
Fixes #2617
Fixes #3548
2023-01-22 18:59:58 +01:00
Orestis Floros
c52f13900d Add focus workspace command 2023-01-22 18:33:23 +01:00
Michael Stapelberg
8d64937054 Bump -D_FORTIFY_SOURCE=2 to -D_FORTIFY_SOURCE=3 (#5379)
Arch Linux is discussing increasing to 3, so we should probably keep up:

https://gitlab.archlinux.org/archlinux/rfcs/-/merge_requests/17
2023-01-19 08:37:46 +01:00
Orestis Floros
9c8746c00f Merge pull request #5355 from orestisfl/5346/do-not-canonicalize-nonprimary
Do not canonicalize "nonprimary" output for i3bar
2023-01-07 10:02:45 +01:00
Orestis Floros
fa25afedd2 Do not canonicalize "nonprimary" output for i3bar
Fixes #5346
2023-01-06 22:30:56 +01:00
Michael Stapelberg
46de32eedd GitHub Actions: remove i386 autobuild packages (#5345)
They are newly failing since the previous commit (upgrading to Ubuntu focal),
so instead of debugging what the issue is, let’s just remove them entirely.
Not many i386 users are left, as the world is on amd64 and arm64 these days.
2023-01-02 12:24:54 +01:00
Michael Stapelberg
944a262688 GitHub Actions: build Ubuntu packages using Ubuntu focal (#5344)
This is required to satisfy our meson.build minimal Meson version.
2023-01-02 12:10:36 +01:00
Michael Stapelberg
aaee2b3eae free some heap allocations to satisfy LeakSanitizer 2023-01-02 11:36:37 +01:00
Michael Stapelberg
dfb3850989 fix reload binding memory issue: copy current_binding_mode 2023-01-02 11:36:37 +01:00
Michael Stapelberg
90d7b9769c meson: specify check: false on run_command
We use run_command for conditionals, meaning meson execution should not stop
when the command returns false. This change keeps our meson setup working
throughout the upcoming change of default behavior (check: true).
2023-01-02 11:36:37 +01:00
Michael Stapelberg
16f83396b4 GitHub Actions: switch to meson setup subcommand
Using “meson” instead of “meson setup” results in a warning.
2023-01-02 11:36:37 +01:00
Michael Stapelberg
8fe28d1a95 fix -Wmaybe-unused and -Wstringop-truncation warnings 2023-01-02 11:36:37 +01:00
Michael Stapelberg
d06e87eb8d GitHub Actions: build with -D_FORTIFY_SOURCE=2
This requires --buildtype=debugoptimized (or --buildtype=release, but
optimizations need to be enabled), and will allow us to keep the i3 build free
of warnings during development.

Distributions like Debian build with -D_FORTIFY_SOURCE=2.
2023-01-02 11:36:37 +01:00
Michael Stapelberg
3e184daf29 release.sh: update after 4.22 release 2023-01-02 11:36:37 +01:00
Michael Stapelberg
7d3a3ae0fb clean up old release notes 2023-01-02 09:49:20 +01:00
Michael Stapelberg
6984dff01a debian: update changelog 2023-01-02 09:46:32 +01:00
Michael Stapelberg
47b2caa116 Merge branch 'release-4.22' 2023-01-02 09:39:12 +01:00
Michael Stapelberg
57f984ae67 Restore non-git version suffix 2023-01-02 09:39:12 +01:00
Michael Stapelberg
b85da284a7 release i3 4.22 2023-01-02 09:39:00 +01:00
Michael Stapelberg
ab6f1fd160 fix focus <direction> with negative gaps (#5333)
fixes #5293
2022-12-21 08:11:51 +01:00
Orestis Floros
ed690c7ba0 Merge pull request #5324 from orestisfl/5323/mode-in-binding-event
Add "mode" field in binding event
2022-12-14 14:24:05 +01:00
Orestis Floros
d5c8319b6c Add "mode" field in binding event
This does *not* go in the binding object to reflect the same hierarchy
of the config file: a mode is a collection of bindings.

Fixes #5323
2022-12-14 13:23:12 +01:00
Demian
1786b13f0d i3-dmenu-desktop: Allow more than one --entry-type (#5294)
Unlike in the man page, only one --entry-type is reasonable possible.
On using multiple --entry-types and a command offers multiple, duplicates are removed i3-dmenu-desktop.
See more at #5291

added --show-duplicates flag for this
2022-12-06 17:23:10 +01:00
Michael Stapelberg
fd95a47183 Update to clang-format-12 (as 10 is no longer installable) (#5317)
No changes to the code are needed.
2022-12-06 11:06:18 +01:00
Orestis Floros
30131ed697 Support nonprimary output keyword (#5273)
Fixes #4878
2022-11-19 18:11:26 +01:00
Orestis Floros
a1e4b44955 command.spec: Put cmd_border stuff together (#5266) 2022-11-13 16:22:41 +01:00
Orestis Floros
029cb8af19 Use mask to determine workspace gaps assignments (#5283)
Fixes #5282
2022-11-13 16:03:58 +01:00
Orestis Floros
60c3fedb73 window_update_motif_hints: Do not assert that the property will always be there (#5281)
Fixes #5280
2022-11-13 10:48:26 +01:00
Michael Stapelberg
96614a2f32 apply updated workspace gap assignments after reload (#5279)
Fixes https://github.com/i3/i3/issues/5257
2022-11-12 17:32:30 +01:00
Michael Stapelberg
1ba0eaca22 Make floating_from and tiling_from criterion work in commands, too (#5278)
Fixes https://github.com/i3/i3/issues/5258
2022-11-12 16:44:08 +01:00
Michael Stapelberg
2ac6180b90 gaps: position graphical resize bar in the middle between windows (#5277)
Fixes https://github.com/i3/i3/issues/5256
2022-11-12 15:48:07 +01:00
Michael Stapelberg
170a322cc2 fix: prevent gaps inside floating split containers (#5276)
Fixes https://github.com/i3/i3/issues/5272
2022-11-12 14:58:13 +01:00
Michael Stapelberg
d130126204 gaps: fix inner gaps for stacked/tabbed containers in splith/splitv (#5275)
Fixes https://github.com/i3/i3/issues/5261
2022-11-12 14:08:13 +01:00
Michael Stapelberg
2b236955bd use con_border_style() to fix titles in stacked/tabbed containers (#5274)
Previously, the code was directly accessing con->border_style, which circumvents
the special-casing for stacked/tabbed containers that forces window titles even
for title-less containers.

Fixes https://github.com/i3/i3/issues/5269
2022-11-12 12:43:55 +01:00
Orestis Floros
be27a2f50d userguide: gaps: mention minimum version (#5265) 2022-11-08 17:14:22 +01:00
Michael Stapelberg
804bca3a9a gaps: make workspace gap assignments order-independent (#5259)
This commit moves subtracting the global gaps from the workspace gaps:
previously, this calculation was done while parsing the configuration
(order dependent), now it’s done at workspace assignment evaluation time.

related to https://github.com/i3/i3/issues/3724

fixes https://github.com/i3/i3/issues/5253
2022-11-07 19:02:57 +01:00
Michael Stapelberg
14795c303c fix title bar rendering with hide_edge_borders smart (#5260)
related to https://github.com/i3/i3/pull/5245

fixes https://github.com/i3/i3/issues/5254
2022-11-07 19:01:58 +01:00
Michael Stapelberg
e6a28b9475 gaps: change workspace rendering to fix sizes with large outer gaps (#5252)
Currently, containers only consider their neighbors and screen edges.

If >2 containers are in a line, the outer containers adjust from outer gaps, but
the middle containers know nothing of this and only consider the inner gaps.

When the outer gaps differ substantially from the inner gaps, the left-most and
right-most containers are smaller as only they adjust for the larger outer gaps.

This commit changes the rendering: containers are now always inset by their
inner gap settings, and workspace containers is now inset by the outer gap
settings.

The result is that many tiled containers have the same size, and the gaps
overall work as the user might expect them to previous combinations of
outer/inner gap settings still produce the same result, albeit with fixed
outer-most sizes.

fixes https://github.com/Airblader/i3/issues/22

related to https://github.com/i3/i3/issues/3724

Co-authored-by: Cameron Leger <contact@cameronleger.com>
2022-11-06 21:22:21 +01:00
Michael Stapelberg
69e13d7821 Revert "gaps: use logical_px() to work correctly on hi-dpi monitors" (#5251)
This reverts commit 6b658f88be.

The commit was misguided: the pixel values are already run through logical_px()
when parsing the configuration directive or command, so they should not be run
through another logical_px() pass at rendering time.
2022-11-06 19:42:30 +01:00
Michael Stapelberg
2a91514a31 t/548-motif-hints: add missing $x->flush after $x->change_property
I noticed the test was flaky before, possibly this fixes it.

related to #3009
2022-11-06 18:18:23 +01:00
Orestis Floros
9dcf37b428 Fix motif behavior according to spec
See https://linux.die.net/man/3/vendorshell
The important part is:
> MWM_DECOR_ALL
> All decorations *except* those specified by other flag bits that are set
2022-11-06 18:18:23 +01:00
Michael Stapelberg
9e3a9e8225 Allow text drawing to use the alpha channel. (#5246)
This is the last remaining diff from the i3-gaps tree.

related to https://github.com/i3/i3/issues/3724

Tested using the following config with picom:

bar {
	i3bar_command i3bar -t
	status_command i3status
	colors {
		# fully	transparent text on opaque background:
		statusline #ffffff00
		background #000000ff
	}
}
2022-11-06 12:43:37 +01:00
Michael Stapelberg
c8fd8eff21 userguide: document smart_borders 2022-11-06 12:43:01 +01:00
Michael Stapelberg
6fe625f469 userguide: document hide_edge_borders smart_no_gaps
related to https://github.com/i3/i3/issues/3724
2022-11-06 12:43:01 +01:00
Michael Stapelberg
d26ddcbfe5 draw leaf window decorations on ->frame instead of ->parent->frame
related to https://github.com/i3/i3/issues/3724
fixes https://github.com/i3/i3/issues/1966
2022-11-05 15:58:15 +01:00
Michael Stapelberg
6e6af01b7a draw_util: refactor surface_initialized macro into function
This makes it possible to set a breakpoint in gdb on a line in the function and
get a backtrace of un-initialized surface access.
2022-11-05 15:58:15 +01:00
Michael Stapelberg
a59423df81 check-spelling: add another false positive (#5247) 2022-11-05 15:56:36 +01:00
Michael Stapelberg
2bfa06b7df meson.build: include new gaps1920.png file in dist tarball (#5242) 2022-11-01 18:26:57 +01:00
Michael Stapelberg
9c9b110ed1 config.spec: add missing smart_gaps inverse_outer comment 2022-11-01 17:55:46 +01:00
Michael Stapelberg
588cc4c79c refactor cmd_gaps to get rid of all #define
I’m still not 100% happy with how the function turned out (it still does too
many things at once), but this seems like an improvement — at least reading and
navigating the code with LSP now works better.
2022-11-01 17:55:46 +01:00
Michael Stapelberg
4d0323fa9e t/319-gaps.t: also test the gaps command 2022-11-01 17:55:46 +01:00
Michael Stapelberg
3f400b8ad0 move gaps-specific logic out of con.c and render.c into gaps.c 2022-11-01 17:55:46 +01:00
Michael Stapelberg
a5791b2e64 gaps: allow optional px suffix 2022-11-01 17:55:46 +01:00
Michael Stapelberg
b2c696f680 add basic gaps test 2022-11-01 17:55:46 +01:00
Michael Stapelberg
b82b3e85da userguide: document gaps config directive and gaps command 2022-11-01 17:55:46 +01:00
Michael Stapelberg
6b658f88be gaps: use logical_px() to work correctly on hi-dpi monitors 2022-11-01 17:55:46 +01:00
Michael Stapelberg
5b0f848a40 Fix config.spec comment 2022-11-01 17:55:46 +01:00
Michael Stapelberg
9ac027234b refactor render_con() global parameter into should_inset_con()
This bundles the logic all in one place and thereby makes it a little easier to
understand.
2022-11-01 17:55:46 +01:00
Michael Stapelberg
2fbb36b95f remove dead code: window_rect is overwritten a few lines below 2022-11-01 17:55:46 +01:00
Michael Stapelberg
b825dc124a Merge gaps support as-is
This code was copied over unmodified from https://github.com/Airblader/i3-gaps.

I have split out the differences between i3-gaps and i3 into three areas:
1. Gaps
2. i3bar height
3. rgba colors
2022-11-01 17:55:46 +01:00
Michael Stapelberg
0b89d4b2a7 implement bar { padding } config directive
related to https://github.com/i3/i3/issues/3724
related to https://github.com/i3/i3/pull/4288
fixes https://github.com/i3/i3/issues/3721
2022-10-30 22:22:08 +01:00
Michael Stapelberg
327bca26d8 add test for bar { height } 2022-10-30 22:22:08 +01:00
Michael Stapelberg
c45342e74f Merge support for the bar { height } option as-is from i3-gaps
related to https://github.com/i3/i3/issues/3724
related to https://github.com/i3/i3/issues/3721

In a follow-up commit, we can evolve this into the padding directive as
discussed on issue #3721.
2022-10-30 22:22:08 +01:00
Michael Stapelberg
62eb0033b1 docs/userguide: fix asciidoc block syntax (for asciidoctor)
asciidoctor is a bit stricter in what it accepts: the leading and trailing lines
need to have the exact same number of characters, and apparently there needs to
be a blank line after the trailing delimiter line.
2022-10-30 22:22:08 +01:00
Michael Stapelberg
a68eb3a71e delete old release notes 2022-10-30 22:22:08 +01:00
Orestis Floros
080c73d1a4 i3-dmenu-desktop: ignore SIGPIPE when writing to dmenu (#5228)
Fixes broken test
2022-10-29 08:20:09 +02:00
Michael Stapelberg
1f53ae4614 debian: update changelog 2022-10-24 21:33:43 +02:00
Michael Stapelberg
23bc304477 Update debian/changelog 2022-10-24 21:23:07 +02:00
Michael Stapelberg
c6bfd05276 Merge branch 'stable' into next 2022-10-24 21:23:07 +02:00
Michael Stapelberg
85252a3bd1 Merge branch 'release-4.21.1' 2022-10-24 21:23:06 +02:00
Michael Stapelberg
9ffcc51183 Restore non-git version suffix 2022-10-24 21:23:06 +02:00
Michael Stapelberg
39afa033e4 release i3 4.21.1 2022-10-24 21:22:50 +02:00
Michael Stapelberg
3b9d70af41 tiling drag: only start when there are drop targets (#5213)
This prevents potentially confusing drag & drop on fullscreen containers and
only-containers on workspaces.

fixes https://github.com/i3/i3/issues/5184
2022-10-24 21:13:03 +02:00
Michael Stapelberg
c55b52a7cc tiling drag: ignore scratchpad windows when locating drop targets (#5211)
fixes https://github.com/i3/i3/issues/5170
2022-10-24 21:13:00 +02:00
Michael Stapelberg
131b0c5b3d make tiling drag configurable
fixes https://github.com/i3/i3/issues/5155
2022-10-24 21:12:58 +02:00
Michael Stapelberg
aa876585e8 tiling drag: left-click needs threshold, mod-click doesn’t
related to https://github.com/i3/i3/issues/5155
2022-10-24 21:12:56 +02:00
Michael Stapelberg
f1754e12c0 increase drag threshold, run it through logical_px()
related to https://github.com/i3/i3/issues/5155
2022-10-24 21:12:53 +02:00
Michael Stapelberg
e12d2f6a1d tiling drag: fix cursor (wrong argument passed) (#5207)
Currently, the cursor is XCURSOR_CURSOR_TOP_RIGHT_CORNER (== BORDER_TOP),
but the intended cursor was XCURSOR_CURSOR_MOVE.

noticed this as part of https://github.com/i3/i3/issues/5198
2022-10-24 21:12:51 +02:00
Michael Stapelberg
b88ca36a5a tiling drag: allow click immediately, to focus on decoration click (#5206)
With the introduction of tiling drag, i3’s click behavior in window decorations
changed: before tiling drag, in a tabbed or stacked container, a window would be
focused/raised on mouse down. After tiling drag, on mouse up.

This commit sends XCB_ALLOW_REPLAY_POINTER before running the tiling drag code,
thereby restoring the focus/raise-on-mouse-down behavior without affecting the
tiling drag operation.

fixes https://github.com/i3/i3/issues/5169
2022-10-24 21:12:48 +02:00
bodea
7abd58abf2 Escape ~ to prevent interpretation as subscript. (#5168) 2022-10-24 21:12:43 +02:00
Matias Goldfeld
d62183a2b8 Fix segfault during config validation (#5167) (#5173)
Configs with bar blocks will segfault during validation since they
copy the i3 font which is not set during validation.
2022-10-24 21:12:38 +02:00
Tudor Brindus
9d6a8735eb Raise floating windows when their border is clicked (#5196)
This logic already existed for `floating_drag_window`, but we need it
for `floating_resize_window` too.

Fixes #5195.
2022-10-24 21:12:30 +02:00
Michael Stapelberg
decc37eba1 Fix i3-dmenu-desktop quoting (#5162)
Commit 70f23caa9a introduced new issues.

Instead of distinguishing " and \, as that commit attempted,
let’s instead keep the level of escaping by escaping each backslash,
just like each double quote.

I tested this with:

    # recommended way to quote $ and " in quoted arguments, not ambiguous
    Exec=/tmp/logargs "hello \\$PWD \\"and\\" more"

    # permitted way to quote $ and " in quoted arguments, but ambiguous
    Exec=/tmp/logargs "hello \$PWD \"and\" more"

    # permitted way to quote arguments, slightly unusual to quote first arg
    Exec="/tmp/logargs" hey

    # a complicated shell expression, not ambiguous
    Exec=sh -c "if [ -n \\"\\$*\\" ]; then exec /tmp/logargs --alternate-editor= --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec /tmp/logargs --alternate-editor= --create-frame; fi" placeholder %F

related to https://github.com/i3/i3/issues/4697 (electrum, original)
related to https://github.com/i3/i3/issues/5152 (phpstorm, breakage)
related to https://github.com/i3/i3/issues/5156 (emacsclient, breakage)
2022-10-24 21:12:27 +02:00
Orestis Floros
3f58d51ec6 Fix motif logic for new floats
- manage.c still used wrong `motif_border_style == BS_NORMAL`
- container must be set to floating first for correct code path and
  correct max_user_border_style to be used in con_set_border_style
- Motif test now includes default_floating_border
2022-10-24 21:12:25 +02:00
Orestis Floros
304e815ed4 Motif hints: Respect maximum border style configuration set by user
Context:
Motif hints [1] allow applications to request specific window manager
frame decorations. Most applications like alacritty, chromium, and
godot, use the hints as a binary flag, setting or un-setting
`MWM_DECOR_ALL`.
Previously [2], we had disallowed applications to set the "normal"
border style through motif hints. This effectively meant that users that
had set `default_border pixel` would not see applications spawning with
normal decorations [3].
However, that meant that applications like godot [4] could not toggle
their border between none and normal so the behaviour changed with
v4.21 [5].
That change however also allowed applications to override the default
none/pixel border style the user set. For example, alacritty can be
configured to either have all or no decorations [6] and they always set
the motif hint on startup, completely overriding i3 user's preference:
1. If decorations are disabled with alacritty's config then they will
   override `default_border normal` and no title will be used.
2. If decorations are enabled (also the default behavior) with
   alacritty's config then they will override `default_border pixel` and
   a title will be used.

This patch redefines how we interpret motif hints. When a client sets
`MWM_DECOR_ALL`, we interpret it as "the maximum decoration the user has
allowed for this window". I.e., if a client was all decorations and the
user expects the window to not have a title, we don't include the title
in "all" decorations.

The user's preference is determined by these:
1. For new tiling windows, as set by `default_border`
2. For new floating windows, as set by `default_floating_border`
3. For all windows that the user runs the `border` command, whatever is
   the result of that command for that window.
Example:
- User opens new tiling window with `default_border pixel` => maximum
  decoration = PIXEL
- Window requests all/title decorations => i3 enforces the user maximum
  decoration, PIXEL (no change)
- Window requests no decorations => i3 accepts it and sets border to
  NONE, maximum decoration remains PIXEL
- User toggles the border, next style is NORMAL => maximum decoration is
  now NORMAL
- Window requests no decorations => i3 accepts it and sets border to
  NONE
- Window requests all/title decorations => i3 accepts it and sets the
  maximum border, NORMAL
- User toggles the border, next style is NONE => maximum decoration is
  now NONE
- Window requests all/title decorations => i3 enforces the user maximum
  decoration, NONE (no change)

With this, we will still allow behaviour where windows can toggle their
border style with motif hints [4][7].

Reference/footnotes:
[1]: https://linux.die.net/man/3/vendorshell
[2]: https://github.com/i3/i3/pull/2386
[3]: Notice how there is apparently a gap because `default border none`
settings would not be respected if an application wanted just "border"
decorations but this was never reported, probably because of the rare
conjunction of applications requesting that and users defaulting to none
borders.
[4]: https://github.com/godotengine/godot/issues/40037
[5]: https://github.com/i3/i3/pull/5135
[6]: Set by an underlying library here:
fafdedfb7d/src/platform_impl/linux/x11/util/hint.rs (L113-L142)
called by alactitty here:
4ddb608563/alacritty/src/display/window.rs (L341)
[7]: https://github.com/i3/i3/issues/3678

Closes #3678
Fixes #5149
2022-10-24 21:12:23 +02:00
Orestis Floros
0af2bac9ed Order border_style_t enum according to amount of decoration
The only place where this matters is with command `border toggle` which
cycles through them. Luckily, the behaviour does not change because the
order is the same with the new enum.
2022-10-24 21:12:20 +02:00
Erich Heine
5e4ed2fc75 Adds sticky field to get_tree reply in ipc doc 2022-10-24 21:12:00 +02:00
Orestis Floros
de3fc07123 Update actions/checkout to v3 (#5226)
Fixes #5225
2022-10-24 21:01:23 +02:00
Orestis Floros
b18b80ca40 i3-dmenu-desktop test: Do not autostart i3 (#5224)
This actually fixes a hang that happens on my machine for some reason.
Regardless, starting i3 is not necessary for this test.
2022-10-24 19:57:07 +02:00
Michael Stapelberg
5e759ed424 tiling drag: only start when there are drop targets (#5213)
This prevents potentially confusing drag & drop on fullscreen containers and
only-containers on workspaces.

fixes https://github.com/i3/i3/issues/5184
2022-10-18 22:10:03 +02:00
Michael Stapelberg
941229ee62 tiling drag: ignore scratchpad windows when locating drop targets (#5211)
fixes https://github.com/i3/i3/issues/5170
2022-10-16 22:12:45 +02:00
Michael Stapelberg
55d400b17d make tiling drag configurable
fixes https://github.com/i3/i3/issues/5155
2022-10-16 18:21:08 +02:00
Michael Stapelberg
2ba393f084 tiling drag: left-click needs threshold, mod-click doesn’t
related to https://github.com/i3/i3/issues/5155
2022-10-16 18:21:08 +02:00
Michael Stapelberg
6479cb7deb increase drag threshold, run it through logical_px()
related to https://github.com/i3/i3/issues/5155
2022-10-16 18:21:08 +02:00
Michael Stapelberg
8128774386 tiling drag: fix cursor (wrong argument passed) (#5207)
Currently, the cursor is XCURSOR_CURSOR_TOP_RIGHT_CORNER (== BORDER_TOP),
but the intended cursor was XCURSOR_CURSOR_MOVE.

noticed this as part of https://github.com/i3/i3/issues/5198
2022-10-16 16:53:15 +02:00
Michael Stapelberg
a6c86fd794 tiling drag: allow click immediately, to focus on decoration click (#5206)
With the introduction of tiling drag, i3’s click behavior in window decorations
changed: before tiling drag, in a tabbed or stacked container, a window would be
focused/raised on mouse down. After tiling drag, on mouse up.

This commit sends XCB_ALLOW_REPLAY_POINTER before running the tiling drag code,
thereby restoring the focus/raise-on-mouse-down behavior without affecting the
tiling drag operation.

fixes https://github.com/i3/i3/issues/5169
2022-10-16 15:21:22 +02:00
bodea
4f3d4c26f6 Escape ~ to prevent interpretation as subscript. (#5168) 2022-10-11 18:09:26 +02:00
Matias Goldfeld
c5dc0d8c93 Fix segfault during config validation (#5167) (#5173)
Configs with bar blocks will segfault during validation since they
copy the i3 font which is not set during validation.
2022-10-10 18:52:55 +02:00
Tudor Brindus
06e31ece8f Raise floating windows when their border is clicked (#5196)
This logic already existed for `floating_drag_window`, but we need it
for `floating_resize_window` too.

Fixes #5195.
2022-10-10 14:22:55 +02:00
Michael Stapelberg
812ec43d46 Fix i3-dmenu-desktop quoting (#5162)
Commit 70f23caa9a introduced new issues.

Instead of distinguishing " and \, as that commit attempted,
let’s instead keep the level of escaping by escaping each backslash,
just like each double quote.

I tested this with:

    # recommended way to quote $ and " in quoted arguments, not ambiguous
    Exec=/tmp/logargs "hello \\$PWD \\"and\\" more"

    # permitted way to quote $ and " in quoted arguments, but ambiguous
    Exec=/tmp/logargs "hello \$PWD \"and\" more"

    # permitted way to quote arguments, slightly unusual to quote first arg
    Exec="/tmp/logargs" hey

    # a complicated shell expression, not ambiguous
    Exec=sh -c "if [ -n \\"\\$*\\" ]; then exec /tmp/logargs --alternate-editor= --display=\\"\\$DISPLAY\\" \\"\\$@\\"; else exec /tmp/logargs --alternate-editor= --create-frame; fi" placeholder %F

related to https://github.com/i3/i3/issues/4697 (electrum, original)
related to https://github.com/i3/i3/issues/5152 (phpstorm, breakage)
related to https://github.com/i3/i3/issues/5156 (emacsclient, breakage)
2022-09-28 18:29:26 +02:00
Orestis Floros
8ec41334ec Fix motif logic for new floats
- manage.c still used wrong `motif_border_style == BS_NORMAL`
- container must be set to floating first for correct code path and
  correct max_user_border_style to be used in con_set_border_style
- Motif test now includes default_floating_border
2022-09-24 20:46:47 +02:00
Orestis Floros
f6097d4a37 Motif hints: Respect maximum border style configuration set by user
Context:
Motif hints [1] allow applications to request specific window manager
frame decorations. Most applications like alacritty, chromium, and
godot, use the hints as a binary flag, setting or un-setting
`MWM_DECOR_ALL`.
Previously [2], we had disallowed applications to set the "normal"
border style through motif hints. This effectively meant that users that
had set `default_border pixel` would not see applications spawning with
normal decorations [3].
However, that meant that applications like godot [4] could not toggle
their border between none and normal so the behaviour changed with
v4.21 [5].
That change however also allowed applications to override the default
none/pixel border style the user set. For example, alacritty can be
configured to either have all or no decorations [6] and they always set
the motif hint on startup, completely overriding i3 user's preference:
1. If decorations are disabled with alacritty's config then they will
   override `default_border normal` and no title will be used.
2. If decorations are enabled (also the default behavior) with
   alacritty's config then they will override `default_border pixel` and
   a title will be used.

This patch redefines how we interpret motif hints. When a client sets
`MWM_DECOR_ALL`, we interpret it as "the maximum decoration the user has
allowed for this window". I.e., if a client was all decorations and the
user expects the window to not have a title, we don't include the title
in "all" decorations.

The user's preference is determined by these:
1. For new tiling windows, as set by `default_border`
2. For new floating windows, as set by `default_floating_border`
3. For all windows that the user runs the `border` command, whatever is
   the result of that command for that window.
Example:
- User opens new tiling window with `default_border pixel` => maximum
  decoration = PIXEL
- Window requests all/title decorations => i3 enforces the user maximum
  decoration, PIXEL (no change)
- Window requests no decorations => i3 accepts it and sets border to
  NONE, maximum decoration remains PIXEL
- User toggles the border, next style is NORMAL => maximum decoration is
  now NORMAL
- Window requests no decorations => i3 accepts it and sets border to
  NONE
- Window requests all/title decorations => i3 accepts it and sets the
  maximum border, NORMAL
- User toggles the border, next style is NONE => maximum decoration is
  now NONE
- Window requests all/title decorations => i3 enforces the user maximum
  decoration, NONE (no change)

With this, we will still allow behaviour where windows can toggle their
border style with motif hints [4][7].

Reference/footnotes:
[1]: https://linux.die.net/man/3/vendorshell
[2]: https://github.com/i3/i3/pull/2386
[3]: Notice how there is apparently a gap because `default border none`
settings would not be respected if an application wanted just "border"
decorations but this was never reported, probably because of the rare
conjunction of applications requesting that and users defaulting to none
borders.
[4]: https://github.com/godotengine/godot/issues/40037
[5]: https://github.com/i3/i3/pull/5135
[6]: Set by an underlying library here:
fafdedfb7d/src/platform_impl/linux/x11/util/hint.rs (L113-L142)
called by alactitty here:
4ddb608563/alacritty/src/display/window.rs (L341)
[7]: https://github.com/i3/i3/issues/3678

Closes #3678
Fixes #5149
2022-09-24 20:46:47 +02:00
Orestis Floros
eddced6b45 Order border_style_t enum according to amount of decoration
The only place where this matters is with command `border toggle` which
cycles through them. Luckily, the behaviour does not change because the
order is the same with the new enum.
2022-09-24 20:46:47 +02:00
Orestis Floros
8e9b29419f Merge pull request #5151 from orestisfl/release-notes
Clean up 4.21 release notes
2022-09-22 15:37:03 +02:00
Orestis Floros
016d0b5f07 Clean up 4.21 release notes 2022-09-22 15:28:53 +02:00
Michael Stapelberg
4ab34d5042 GitHub Actions: skip build + test steps in meson dist (#5148)
Originally I thought we should remove the build and test steps in favor of the
“meson dist” step. But, then we lose verbose build command lines and access
to the test logs, and having the failing test logs readily available is
critical.

So, instead, let’s make the “meson dist” step not repeat the work that was
already done in earlier steps. The Meson manual even documents the --no-tests
flag precisely for our use case:

> The meson dist command has a --no-tests option to skip build and tests steps
> of generated packages. It can be used to not waste time for example when done
> in CI that already does its own testing.

From https://mesonbuild.com/Creating-releases.html

fixes https://github.com/i3/i3/issues/5145
2022-09-21 22:19:57 +02:00
Michael Stapelberg
28671a622b release.sh: re-add warning about debian/changelog changes
As long as we push auto builder packages from our CI, we need to update the
version number via the changelog.
2022-09-21 21:58:41 +02:00
Michael Stapelberg
3e434ba0ce release.sh: latest released version numbers 2022-09-21 21:58:41 +02:00
Michael Stapelberg
6ae232a323 release.sh: fix Debian source repository configuration
Debian switched to deb822 sources.list:

https://twitter.com/zekjur/status/1572622368492888065
2022-09-21 21:58:41 +02:00
Michael Stapelberg
5caf49323c release.sh: fix regexp for updating version in index.html 2022-09-21 21:58:41 +02:00
Michael Stapelberg
12cdf435aa release.sh: update website branch name 2022-09-21 21:58:41 +02:00
Michael Stapelberg
d7b9a45ff3 release.sh: remove dput instruction
Package maintenance is done by sur5r these days (thanks!)
2022-09-21 21:58:41 +02:00
Erich Heine
0967021858 Adds sticky field to get_tree reply in ipc doc 2022-09-21 19:27:32 +02:00
Michael Stapelberg
f0856c285c debian: update changelog 2022-09-21 18:38:54 +02:00
Michael Stapelberg
ac95dffd6b Update debian/changelog 2022-09-21 18:26:55 +02:00
Michael Stapelberg
2bdcae8149 Merge branch 'release-4.21' 2022-09-21 18:26:55 +02:00
Michael Stapelberg
c0ef3caec8 Merge branch 'next' into stable 2022-09-21 18:26:55 +02:00
Michael Stapelberg
d7f4707e05 Restore non-git version suffix 2022-09-21 18:26:55 +02:00
Michael Stapelberg
5bc4280a48 release i3 4.21 2022-09-21 18:26:43 +02:00
Michael Stapelberg
8ade46bdf0 unflake t/289-ipc-shutdown-event.t (#5144)
Before this commit, the test was flaky: it relied on the Perl test process
sending the kill() system call before i3 exited. This can easily be triggered
by adding a sleep(1) after the “cmd 'exit'” line.

This is because with i3_autostart => 1 (the default), i3test.pm kills i3
or bails out if it can’t.

So, we instead set i3_autostart => 0 and launch i3 ourselves.
This will unfortunately still make the code kill i3 and bail out,
because launch_with_config updates the $i3_pid variable that i3test.pm
uses for tracking whether it should clean up i3.
The solution is to exit i3 by calling exit_gracefully,
which will make the i3test.pm state correct.

related to https://github.com/i3/i3/issues/3009
2022-09-21 17:47:40 +02:00
Orestis Floros
227c1538be Add some release notes (#5138) 2022-09-20 09:13:34 +02:00
Orestis Floros
516d442e9a tiling_drag: Correctly switch to workspace when dragging across outputs (#5141)
Fixes #5089
2022-09-20 09:13:14 +02:00
viri
8252144cc3 motif: restore BS_NORMAL correctly (#5135)
motif hints: restore BS_NORMAL correctly
2022-09-19 20:12:15 +02:00
Orestis Floros
0ac5e248f2 tiling_drag: con_rect_plus_deco_height: Fix underflow (#5129)
Fixes #5069
2022-09-17 13:00:29 +02:00
zhrvn
5ce8e3241b Fix crash in parse_file() when parsing nested variables (#5003)
Count extra_bytes correctly

If there is a variable with the same name as the rest of another
variable after removing $, then it will be counted twice. Therefore,
we need to completely replace it with spaces (variable names cannot
contain spaces) in order to correctly calculate the length of a new
string.

fixes https://github.com/i3/i3/pull/5002

Co-authored-by: Ivan Zharov <zhiv.email@gmail.com>
Co-authored-by: Michael Stapelberg <stapelberg@users.noreply.github.com>
2022-09-12 09:03:50 +02:00
zhrvn
e48b9aa284 Fix segfault with mode "default" key bindings (#5007)
ignore bindings when not in a valid mode

Co-authored-by: Ivan Zharov <zhiv.email@gmail.com>
Co-authored-by: Michael Stapelberg <stapelberg@users.noreply.github.com>
2022-09-11 15:22:01 +02:00
Michael Stapelberg
f795c2c8da testsuite: catch i3 SIGSEGV by installing SIGCHLD handler (#5123)
The testsuite already contains quite a number of SIGCHLD handler
installation/un-installations. Here is my attempt at an inventary.

1. complete-run.pl installs a SIGCHLD handler in the `start_xserver()` function
   call, which prints an error and exits when all x server processes have exited.

2. In the TestWorker child process, a SIGCHLD handler is installed to reap dead
   test child processes.

3. The TestWorker child process forks another child process for running the test
   file, where the previously installed SIGCHLD handler (point 2) is unset.

   This is where this commit comes in: it installs a SIGCHLD handler in the test
   file child process, which will trigger when the i3 subprocess dies.

4. (For completeness: i3test.pm defines an END block where it unsets the
    previous SIGCHLD handler before it kills the subprocesses.)

With this commit, when i3 segfaults, the output will look like this:

    Writing logfile to 'testsuite-2022-09-10-21-14-46-4.20-103-gb242bceb/complete-run.log'...
    [:100] /home/michael/i3/testcases/t/167-workspace_layout.t: BAILOUT
    completed 0 of 1 tests
    test /home/michael/i3/testcases/t/167-workspace_layout.t bailed out:
    could not kill i3: No such process

fixes https://github.com/i3/i3/issues/4437
2022-09-10 21:29:04 +02:00
Michael Stapelberg
4b5ead023e open_logbuffer: avoid overflow by comparing (long long) (#5113)
I tested this on a machine with 256 GB of RAM.

fixes #4906
2022-09-09 10:26:17 +02:00
Michael Stapelberg
ac368e7916 config_parser: prevent trailing whitespace in output (string → word) (#5117)
fixes https://github.com/i3/i3/issues/5064
2022-09-09 10:23:55 +02:00
Michael Stapelberg
6fb58eb841 config: set bar block font to i3-wide font *after* parsing (#5118)
Otherwise, the font directive needs to come before bar blocks,
which is surprising to users.

fixes https://github.com/i3/i3/issues/5031
2022-09-09 10:21:33 +02:00
paperluigis
4db383e430 man/i3-input: fix a typo: chose → choose (#5087) 2022-09-06 20:30:23 +02:00
mariano
e9c63d3001 Add wezterm to i3-sensible-terminal (#5107) 2022-09-06 20:23:56 +02:00
bodea
b242bcebcf i3-sensible-pager: sanitize LESS environment variable (#5111)
When an error is encountered such as "The configured command for this shortcut
could not be run successfully", the "show errors" button on i3-nagbar doesn't
work if $PAGER is less, and $LESS contains either the -E or -F flag (the
window pops up, but immediately disappears).

Strip these flags from the LESS environment variable before invoking $pager.
2022-09-06 08:42:02 +02:00
Orestis Floros
ebcd1d43ea Allow dragging tiled windows with the mouse. (#3085)
Fixes #2643

Inner drop region behaves like move to mark.
The outer region is close to the edge (currently 30px from the edge).
This will place the container as a sibling in the given direction within
the parent container. If the move direction goes against the orientation
of the parent container, tree_move() is called.

Contributors:
Co-authored-by: Orestis Floros <orestisflo@gmail.com>
See #3085
- Inner drop region behaves like move to mark
- Handle workspaces
- Fix crash when target closes
- Initiate tiling drag from titlebar
- Hide indicator until container is dragged outside of original position
- Calculate outer_threshold using percentages instead of fixed pixel
values
- Emit 'move' event properly
- Don't focus previously unfocused containers
- Use tree_split() on different orientation
- Fix redundant split containers
- DT_PARENT
- Readability & optimizations
- Limit parent threshold by render_deco_height()
- Tests
- Fullscreen container handling
- Initiate drag from title bar
- Fix issue of EnterNotify events still triggering after drag_callback
  is called
- Include decorations for drop target calculation

Co-authored-by: Michael Forster <email@michael-forster.de>
See #2178
- Original implementation of tiling drag + indicator window
> A container can be dragged by the title bar to one of the four sides
> of another container. That container will then be split either
> horizontally or vertically.

Co-authored-by: Tony Crisci <tony@dubstepdish.com>
See #2653
- Original implementation of outer/inner drop region indicator:
> There are two drop regions per direction.
>
> The inner region is closer to the center of the window. Dropping on
> this region will split the target container and put the container
> within the split at the given direction beside the target container.
>
> The outer region is close to the edge (currently 30px from the edge).
> This will place the container as a sibling in the given direction within
> the parent container.
>
> Dropping into the outer region moves the con beside the target. If the
> move direction goes against the orientation of the parent container, the
> con moves out of the row.
- Fix crash: Ignore containers without a managed window (eg i3bar)
2022-07-28 12:03:16 +02:00
Orestis Floros
807e972330 Fix Wbitwise-instead-of-logical warnings
> error: use of bitwise '|' with boolean operands
2022-07-28 09:25:55 +02:00
Michael Stapelberg
103dc7b55d fix travis/check-spelling.pl for recent Lintian changes 2022-07-28 09:25:55 +02:00
Jay Ta'ala
ddc587933d Split container parents should be redrawn when swapping child containers (within parent) (#4765)
Redraw split container parents when swapping child containers

Split container parents should be redrawn when swapping child containers  so they show the correct window ordering (note without this higher level split parent container titles will only update when changing layout or moving child cons in/out.
2022-06-30 20:21:14 +02:00
Josh Soref
458c148934 cleanup-bintray: remove remaining bintray references (#5038)
* The `cleanup-bintray.pl` script is just unused
* The `dh_builddeb` override is no longer necessary as bintray is no longer used
2022-06-30 08:21:54 +02:00
Kjetil Torgrim Homme
3597cc636e highlight the difference between "workspace N" and "workspace number N" commands 2022-06-28 00:25:06 +02:00
zhiv-git
ce2665ca96 Fix segfault when bindsym command is empty (#5001)
Remove end token from BINDCOMMAND

fixes i3/i3#5000: bindsym command cannot be empty, because NULL string
causes i3 to segfault when copied in configure_binding()
2022-06-08 22:38:21 +02:00
George Rodrigues
6ab64aa5b7 Fix typos (#4989) 2022-06-01 09:49:05 +02:00
Michael Stapelberg
612a9317b0 GitHub Actions: declare /usr/src/i3 as safe directory (#4992) 2022-05-31 18:29:36 +02:00
André Silva
dba30fc987 clear surface on x_push_node (#4577) 2022-03-28 10:18:55 +02:00
takelley1
41cd852f2f Fix typo in comment (#4936)
* Fix typo in comment

* Fix other typo in comment
2022-03-28 10:14:52 +02:00
Ingo Bürk
c822eff1bf Remove Xlib references (#4845)
* remove Xlib import from i3bar

* remove unused Xlib declarations
2022-02-10 10:25:20 +01:00
Gergely Risko
bd5cbbb010 Use proper WM_Sx registration for i3 (#4843)
i3's WM ownership is registered with the X Atom WM_S_S0 (for screen0),
instead of the correct WM_S0.  The relevant xcb-util API didn't
change, this is simply a bug in i3 that has always been there:
https://gitlab.freedesktop.org/xorg/lib/libxcb-util/-/blob/0.4.0/src/atoms.c#L65
2022-02-07 17:43:55 +01:00
Orestis Floros
70288d7b68 Merge pull request #4710 from pstray/title_window_icon-toggle
Implement title_window_icon toggle
2021-12-11 14:33:23 +01:00
Peder Stray
813336e068 Implement title_window_icon toggle
A feature described in i3/i3#4709
2021-12-11 14:20:07 +01:00
Orestis Floros
b17117190d Merge pull request #4717 from orestisfl/janitorial
Remove outdated //-style commented-out code
2021-12-06 22:55:38 +01:00
Orestis Floros
a4ac843cca Remove outdated //-style commented-out code
This makes the whole code-base have zero changes with clang-format
(v13).
2021-12-06 22:14:41 +01:00
sergio
70f23caa9a fix #4697, adds backslashes quotation for exec (#4699)
Signed-off-by: Sergio E. Nemirowski <sergio@outerface.net>
2021-12-06 09:53:50 +01:00
Chris Templin
729452448b docs: change IPC window_type value (#4668) 2021-12-01 20:38:00 +01:00
Michael Stapelberg
07ea5019c9 debian: bump to libpcre2-dev for autobuilds (#4705)
related to https://github.com/i3/i3/issues/4682
2021-11-29 23:41:07 +01:00
Uli Schlachter
6c7efc4de8 Switch from pcre to pcre2 (#4684)
The issue at [0] was opened and I just took a stab at it. I have no
prior experience with pcre and pcre2, but using [1,2] I hacked together
something that seems to work. Next, Michael told me to turn that
patch/hack into a PR, so here we are.

The dependency in meson.build now uses version:'>=10', but this is more
a random guess than actual knowledge.

There was a while loop in regex_new() that dealt with an error when pcre
was not compiled with UTF-8 support. This loop uses a magic constant of
32 for the error code. I just dropped this loop, because I was just
writing a hack and did not intend to turn this into a PR. Also, a quick "grep
32 /usr/include/pcre.h" does not find anything useful, so... *shrug*

pcre_study() was removed without replacement, so the corresponding code
is also simply removed.

Testing done: The test suite passes for me. YMMV.

[0]: https://github.com/i3/i3/issues/4682
[1]: https://www.pcre.org/current/doc/html/pcre2api.html
[2]: https://www.pcre.org/current/doc/html/pcre2demo.html

Signed-off-by: Uli Schlachter <psychon@znc.in>
Fixes: https://github.com/i3/i3/issues/4682
2021-11-29 18:20:54 +01:00
Ingo Bürk
298c3aede9 Merge pull request #4698 from orestisfl/user_output_names_find_next
user_output_names_find_next: Always initialize target_output
2021-11-27 23:38:13 +01:00
Orestis Floros
854616ed2e user_output_names_find_next: Always initialize target_output
This way, if the user has provided a valid, existing output in the list
of outputs, the focus & move workspace to output commands will not
report a misleading failure.

Side-effect is that the command code will try to execute a no-op e.g. by
moving the workspace to the output it already is on. But that's what the
user is actually requesting in this case and it shouldn't be a problem.

Fixes #4691
2021-11-27 22:52:48 +01:00
Ingo Bürk
d44e1442c2 Merge pull request #4485 from ToxicGLaDOS/long_commands_crash
Fix bug where long commands crash i3
2021-11-18 22:35:23 +01:00
Ingo Bürk
46bdd537a8 Merge pull request #4622 from orestisfl/focus-output-next
Focus output next
2021-11-18 22:33:13 +01:00
Ingo Bürk
52c831ca22 Merge pull request #4651 from orestisfl/docs-ipc-socket
docs: Make more clear that an IPC socket is always created
2021-11-18 22:31:35 +01:00
Ingo Bürk
b7056a82f4 Merge pull request #4667 from orestisfl/transient_for-loop
Fix transient_for endless loop
2021-11-18 22:31:19 +01:00
Orestis Floros
e1d3e6b2f6 Fix transient_for endless loop
Other approaches would be:
- Slow/fast pointer technique.
- Using a set/associative map to save 'seen' nodes. i3 does not have
  such data structure.

Counting the total amount of windows is the simpler to implement.

I've also extracted the logic in a function and re-used it in render.c.

Fixes #4404
2021-11-11 20:29:02 +01:00
Orestis Floros
43e805a00d Merge pull request #4656 from stapelberg/flaky
Fix flaky tests: sync after kill
2021-11-07 13:51:55 +01:00
Michael Stapelberg
673185a63b t/219-ipc-window-focus.t: sync after kill 2021-11-07 11:56:06 +01:00
Michael Stapelberg
c4fdcc5dbc fix flaky testcases/t/185-scratchpad.t: sync after kill command 2021-11-07 11:47:42 +01:00
Orestis Floros
8e9da491f4 Merge pull request #4648 from orestisfl/formatting-new-action
Move clang-format and safe-wrappers check in new job
2021-11-06 14:16:09 +01:00
Orestis Floros
7f3316269d Release notes script fixes (#4652)
* release-notes: Sort filenames

* release-notes: Fix print-urls
2021-11-06 14:13:18 +01:00
Orestis Floros
93b2b44893 cmd_focus_output: Multiple outputs 2021-11-05 18:34:54 +01:00
Orestis Floros
34ef7f8c33 tests: Extract focused_output in library 2021-11-05 18:33:14 +01:00
Orestis Floros
bc4f35a6bb Extract common functions out of cmd_move_con_to_output 2021-11-05 18:33:14 +01:00
Orestis Floros
680ddc7e10 Move clang-format, safe-wrappers, release notes check in new job
Benefits:
- Faster feedback in case of error
- More checks run in parallel
- Removes stuff from Dockerfiles
- Uses newest available clang-format (in ubuntu repos)
2021-11-05 18:29:42 +01:00
Ingo Bürk
20d0591e77 Merge pull request #4604 from orestisfl/fix-focus-warp
Fix focus issue when moving windows across outputs
2021-11-05 15:32:07 +01:00
Orestis Floros
117fb13177 Merge pull request #4650 from orestisfl/focused_tab_title
Add title tab color
2021-11-05 15:24:25 +01:00
Anton Älgmyr
863a9eada4 Fix focus issue when moving windows across outputs
Fixes #3518

This fix avoids the issue of consuming our own warp events by never
calling warp on the wrong container.

Tried to add a test but it also succeeds with version before patch,
see #4604 for discussion

Co-Authored-By: Orestis <orestisflo@gmail.com>
2021-11-05 15:21:59 +01:00
Orestis Floros
f36050b303 Add title tab color
Fixes #4575
2021-11-05 15:19:18 +01:00
Orestis Floros
3c81e8ddaa Merge pull request #4610 from orestisfl/release-notes-next
Keep each release note in a single file
2021-11-05 10:36:24 +01:00
Orestis Floros
38cf8a21ef Update release notes
https://github.com/i3/i3/pull/4638
https://github.com/i3/i3/pull/4647
2021-11-05 10:13:30 +01:00
Orestis Floros
c083e023b6 Keep each release note in a single file
To avoid annoying merge conflicts.

Perl script is provided for convenience and simple format checking in
PRs.
2021-11-05 10:13:22 +01:00
Orestis Floros
220144361a userguide: Make more clear that an IPC socket is always created
Follow-up from #4647
2021-11-04 21:47:55 +01:00
Orestis Floros
3e0fc25b6b Merge pull request #4649 from orestisfl/fix-errno
Fix compilation error on debian
2021-11-04 19:31:44 +01:00
Orestis Floros
ce0d08cc6d Fix compilation error on debian 2021-11-04 19:27:40 +01:00
Uli Schlachter
445cea8e3a Do not replace existing IPC socket (#4638)
Imagine you are a happy i3 user and want to also write patches for i3.
You use "Xephyr :1" to get another X11 server and then start your newly
build i3 in it with "DISPLAY=:1 ./i3". You test your changes and
everything seems fine. You are happy. Later that day, you try to log
out, but the $mod+Shift+e key binding from the default config no longer
works. i3-msg cannot connect to the IPC socket because "No such file or
directory". What is going on?

The problem boils down to $I3SOCK having something like two meanings.
When i3 starts, it sets the environment variable $I3SOCK to the path of
its IPC socket. That way, any process started from i3 inherits this and
i3-msg knows how to talk to i3. However, when this variable is already
set when i3 starts, then i3 will replace the existing socket. Thus, in
the earlier experiments, the "separate i3" that was used for
experimenting stole the "main i3"'s socket and replaced it with its own.
When it exited, it deleted that socket.

This commit adds half a work around to this problem: When creating the
IPC socket, i3 will now first try to connect() to the socket. If this
succeeds, it will complain and refuse to use this socket. If the
connect() call fails, it will proceed as usual and create the socket.

Note that trying to connect() to a socket that no process listens on
will fail. Thus, this new code only really "triggers" when some process
is actively listening on this socket and accepting connections.

Example output for when the socket is already in use:

$ I3SOCK=/tmp/sdfdsf DISPLAY=:2 ./i3
31.10.2021 17:03:55 - [libi3] ERROR: Refusing to create UNIX socket at /tmp/sdfdsf: Socket is already in use
31.10.2021 17:03:55 - ERROR: Could not create the IPC socket, IPC disabled

This commit sadly only provides part of the solution. i3 will still
delete the socket when shutting down, even if it failed to create the
IPC socket. Thus, the ipc socket will still break, but now only later.
This will be fixed separately.

First-step-towards-fixing: https://github.com/i3/i3/issues/4381
Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-11-04 17:22:22 +01:00
Michael Stapelberg
d83940a8fc Merge branch 'release-4.20.1' 2021-11-03 09:23:23 +01:00
Michael Stapelberg
53f52beb09 Update debian/changelog 2021-11-03 09:23:23 +01:00
Michael Stapelberg
63aec362c9 Restore non-git version suffix 2021-11-03 09:23:23 +01:00
Michael Stapelberg
f97268dbd8 Merge branch 'stable' into next 2021-11-03 09:23:23 +01:00
Michael Stapelberg
b952e74145 release i3 4.20.1 2021-11-03 09:23:07 +01:00
Michael Stapelberg
6fe33394e1 post-release release.sh changes 2021-11-03 09:14:58 +01:00
Baptiste Daroussin
c6ea9bbace portability: use getcwd() instead of get_current_dir_name() (#4645) 2021-11-03 09:03:33 +01:00
Baptiste Daroussin
058ebb0d42 portability: add missing headers
libi3.h defins a macors with the default modes to create a directory.
Those modes are defined in sys/stat.h, so include the necessary header
2021-11-03 09:03:28 +01:00
lycurgus
884717489f Correct short form of raw option in i3-msg manpage 2021-11-03 09:03:14 +01:00
Jakob Haufe
b895d9d3cc Extend title length for xmlto
man.th.title.max.length defaults to 20 which leads to a broken .TH line
for i3-migrate-config-to-v4.1:

.TH "I3\-MIGRATE\-CONFIG\" "1" "02/01/2021" "i3 4\&.19\&.1" "i3 Manual"
2021-11-03 09:03:09 +01:00
rvalieris
39ff5699d6 check for both arguments NULL on strings_differ 2021-11-03 09:03:03 +01:00
Orestis Floros
ecc4f91fb4 Merge pull request #4647 from psychon/refuse-start-without-ipc-socket
Refuse to start without IPC socket
2021-11-02 23:13:52 +01:00
Uli Schlachter
03a0375e7f Refuse to start without IPC socket
This change was (basically) suggested by @orestisfl in
https://github.com/i3/i3/pull/4638#issuecomment-958093518

Testing done:

$ I3SOCK=/dev/null DISPLAY=:2 LC_ALL=C build/i3
bind(): Address already in use
i3: Could not create the IPC socket: /dev/null

Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-11-02 21:08:42 +01:00
Baptiste Daroussin
aceb36ae60 portability: use getcwd() instead of get_current_dir_name() (#4645) 2021-11-02 20:14:24 +01:00
Orestis Floros
e4d3ec9217 Merge pull request #4644 from bapt/portability-nits
portability: add missing headers
2021-11-02 19:50:58 +01:00
Baptiste Daroussin
e4a3f6e4cd portability: add missing headers
libi3.h defins a macors with the default modes to create a directory.
Those modes are defined in sys/stat.h, so include the necessary header
2021-11-02 10:43:27 +01:00
Orestis Floros
40b0c8e5b8 Merge pull request #4618 from Jonta/patch-3
Docs: Testsuite: Grammar
2021-11-01 21:42:49 +01:00
Orestis Floros
b0632bddfc Merge pull request #4637 from lycurgus/patch-1
Correct short form of raw option in i3-msg manpage
2021-10-31 09:36:30 +01:00
lycurgus
8e46943985 Correct short form of raw option in i3-msg manpage 2021-10-31 19:01:32 +11:00
Ingo Bürk
36f9f86714 Merge pull request #4629 from sur5r/xmlto-titlelength
Extend title length for xmlto
2021-10-28 08:40:08 +02:00
Jakob Haufe
a352cecc6a Extend title length for xmlto
man.th.title.max.length defaults to 20 which leads to a broken .TH line
for i3-migrate-config-to-v4.1:

.TH "I3\-MIGRATE\-CONFIG\" "1" "02/01/2021" "i3 4\&.19\&.1" "i3 Manual"
2021-10-27 19:15:01 +00:00
Jonta
9cc9cc2be0 Docs: Testsuite: Grammar
Incorporating orestisfl's suggestion, and expanding a little
2021-10-24 17:38:14 +02:00
Orestis Floros
b7af69cba8 Merge pull request #4617 from rvalieris/fix
check for both arguments NULL on strings_differ
2021-10-22 17:40:27 +02:00
Jonta
19252515bc Docs: Testsuite: Grammar 2021-10-22 14:21:16 +02:00
rvalieris
64021b6143 check for both arguments NULL on strings_differ 2021-10-22 07:51:07 -03:00
Orestis Floros
e938cae8a0 Merge pull request #4609 from stapelberg/post-release
post-release release.sh changes
2021-10-19 20:05:27 +02:00
Michael Stapelberg
93e8ccd792 post-release release.sh changes 2021-10-19 18:16:34 +02:00
Michael Stapelberg
46f4fe4ecc debian: update changelog 2021-10-19 08:45:28 +02:00
Michael Stapelberg
d854dc597b Update debian/changelog 2021-10-19 08:38:14 +02:00
Michael Stapelberg
1d05918961 Merge branch 'release-4.20' 2021-10-19 08:38:14 +02:00
Michael Stapelberg
533b76378a Merge branch 'next' into stable 2021-10-19 08:38:14 +02:00
Michael Stapelberg
2472f8b8b4 Restore non-git version suffix 2021-10-19 08:38:14 +02:00
Michael Stapelberg
d216a5c9d3 release i3 4.20 2021-10-19 08:37:58 +02:00
Ingo Bürk
e05af2650e Merge pull request #4599 from stapelberg/docs-release
Docs and release notes prep for the next release
2021-10-18 08:10:30 +02:00
Michael Stapelberg
b37c3e3d25 release notes: plug headline features, order and clarify changelog 2021-10-17 20:01:54 +02:00
Michael Stapelberg
b04f206e39 userguide: use “all” criterion in title_window_icon examples 2021-10-17 20:01:41 +02:00
Orestis Floros
ab389e1d76 Merge pull request #4565 from stapelberg/skip
i3-dmenu-desktop: ignore duplicate files and directories
2021-10-07 23:38:47 +02:00
Michael Stapelberg
25bf911537 i3-dmenu-desktop: ignore duplicate files and directories
This is required when e.g. mpv is installed in the NixOS global system
environment *and* in the user environment.

Standalone reproducer:

mkdir -p test1/share/applications test2/share
ln -svf /usr/share/applications/i3.desktop test1/share/applications
ln -svf $PWD/test1/share/applications test2/share
export XDG_DATA_DIRS='test1/share:test2/share'
i3-dmenu-desktop

fixes #4522
2021-10-07 23:22:23 +02:00
Orestis Floros
8323108ca1 Merge pull request #4566 from stapelberg/spelling
fix travis/check-spelling.pl for updated API
2021-10-07 16:01:02 +02:00
Michael Stapelberg
b3d4281b8b fix travis/check-spelling.pl for updated API 2021-10-06 18:23:46 +02:00
Orestis Floros
eada44be1e Merge pull request #4538 from psychon/log-focus-out
Log FocusOut events
2021-09-25 13:53:22 +02:00
Uli Schlachter
16b09672c8 Log FocusOut events
Currently, i3 only logs FocusIn events. Thus, a debug log tells us when
some window gets the focus. However, we don't know when it loses the
focus. This commit remedies this by adding some log messages for this.

Since I had no idea what to log, this just logs all the fields from the
event plus tries to find a name for the window.

Signed-off-by: Uli Schlachter <psychon@znc.in>
Idea-in-context-of: https://github.com/i3/i3/issues/4532
2021-09-25 13:47:36 +02:00
Michael Stapelberg
535da94536 GET_CONFIG: add raw/variable-processed contents of all config files (#4528)
We do this by adding to included_files as i3 processes the configs.

This should allow for easy debugging, without having to change how i3 processes
config files.

related to #4192
2021-09-22 08:54:37 +02:00
Orestis Floros
d3ff9afbb5 Merge pull request #4436 from psychon/check-cairo-status
Check cairo status in draw_util_surface_free()
2021-09-16 19:07:07 +02:00
Uli Schlachter
d2f5e7e46e Fix a minor memory leak
When xcb_request_check() returns an error, something has to clean up and
free this error.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-09-15 18:14:37 +02:00
Uli Schlachter
2e500f0817 Check cairo status in draw_util_surface_free()
When "something goes wrong" in cairo-land, the corresponding cairo
object goes into an error state. These errors are sticky. Thus, it is
enough to check for errors before destroying the context.

This commit adds a check in draw_util_surface_free() to check the cairo
context's status and print a log message if anything is wrong.

The idea here is to help debugging drawing issues. Instead of "nothing
visible", the corresponding log message hopefully helps debugging.

This code would have saved me lots of time in figuring out why my pull
request #4379 did not work.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-09-15 18:14:37 +02:00
Ingo Bürk
a0938bd606 Update docs to Discussions (#4503) 2021-09-10 09:18:01 +02:00
Ingo Bürk
3686cef63c Merge pull request #4469 from vincentbernat/fix/handler-xrandr
handlers.c: send an "output" event on monitor configuration change
2021-09-10 08:09:32 +02:00
Vincent Bernat
381d7e6a98 doc: fix version number in release notes 2021-09-10 08:04:59 +02:00
Vincent Bernat
f9e6d5dd7a handlers.c: send an "output" event on monitor configuration change
When adding/removing a monitor, the outputs are likely to be modified.
Send an IPC event "output", like when there is a screen configuration
change.

Signed-off-by: Vincent Bernat <vincent@bernat.ch>
2021-09-10 08:04:38 +02:00
Ingo Bürk
3d2a1ef80a Merge pull request #4502 from orestisfl/discussion-template
Add option to start a new discussion in the templates
2021-09-10 07:18:58 +02:00
Ingo Bürk
570138eb72 Merge pull request #4501 from orestisfl/window-logs
Make window id logging hex everywhere
2021-09-10 07:17:27 +02:00
Orestis Floros
e1ca00d164 Add option to start a new discussion in the templates 2021-09-10 00:51:19 +02:00
Orestis Floros
af23c0febf Make window id logging hex everywhere
Right now some logs use %d and some use %08x and it can be confusing to
follow.
2021-09-09 21:05:24 +02:00
Orestis Floros
ce2c21885d Merge pull request #4497 from orestisfl/icons-title-align
Make window icons follow title alignment
2021-09-09 09:27:30 +02:00
Orestis Floros
cc44d9a999 Make window icons follow title alignment
Fixes #4464.

Inspired by changes from #4453 but I didn't end up using the original
code.

For ALIGN_LEFT and ALIGN_CENTER icon offset is calculated first and then
title offset is based on that. For ALIGN_RIGHT title offset is
calculated first but we make sure that the icon fits in the window.

Additionally, icons will now hide if there is not enough space to render
them + their padding. Realistically, this won't happen in normal
usecases.

Effectively, icons have higher precedence over text: draw_util_text will
hide text when it exceeds the max width and the code takes this into
consideration. Icons will only hide when they can't fit at all, not in
order to assure that the text can be displayed fully.
2021-09-09 08:51:14 +02:00
Ingo Bürk
579973b1ef Merge pull request #4499 from orestisfl/gh-actions-logs
GH actions: Archive complete logs on test failure
2021-09-08 07:26:20 +02:00
Ingo Bürk
f45d5d1a53 Merge pull request #4498 from orestisfl/memleak
Free window role & machine
2021-09-08 06:41:30 +02:00
Orestis Floros
3ba7599aa4 GH actions: Archive complete logs on test failure
https://docs.github.com/en/actions/reference/usage-limits-billing-and-administration#artifact-and-log-retention-policy

> By default, the artifacts and log files generated by workflows are
> retained for 90 days before they are automatically deleted.
2021-09-08 00:05:11 +02:00
Orestis Floros
8649a7e229 Free window role & machine 2021-09-07 22:52:14 +02:00
Ingo Bürk
3bdea50548 Merge pull request #4495 from kgilmer/config-directives-no-file-no-error
Lower severity of missing include path specified from error to info.
2021-09-06 12:18:34 +02:00
Ken Gilmer
46cffcc059 Lower severity of missing include path specified from error to info. Addresses https://github.com/i3/i3/issues/4494. 2021-09-05 22:14:25 -07:00
Ingo Bürk
986292c662 Merge pull request #4491 from i3/orestisfl-patch-1
Add #4409 to release notes
2021-09-01 07:48:40 +02:00
Orestis Floros
603e26baa8 Add #4409 to release notes 2021-08-31 23:58:10 +02:00
Orestis Floros
9a02399cee Merge pull request #4454 from vincentbernat/feature/i3-notify
main: signal readiness by notifying systemd
2021-08-30 15:26:58 +02:00
Vincent Bernat
5b6a564190 main: signal readiness by notifying systemd
This is useful if we want to be able to start some services depending
on i3, notably some script using the socket or third-party bars like
polybar. To make use of this change, user is expected to use the
following stanza:

```
[Unit]
Description=i3 window manager
PartOf=graphical-session.target

[Service]
Type=notify
ExecStart=/usr/bin/i3
ExecStopPost=/bin/systemctl --user stop graphical-session.target
Restart=on-failure
```

Something similar is already possible using socket activation. For
example, we could use:

```
[Unit]
Description=i3 window manager socket
PartOf=graphical-session.target

[Socket]
ListenStream=%t/i3.sock
ExecStartPost=/bin/systemctl --user set-environment I3SOCK=%t/i3.sock
```

And other units could `Requires=i3.socket`. Unfortunately, not
everything is using I3SOCK. Notably, `i3 --get-socketpath` does not
and that's what i3ipcpp is doing. An alternative would be to patch `i3
--get-socketpath` to use I3SOCK if present, however, this may be a bit
risky. Should we check the environment variable first or the root
attribute?

Another alternative not requiring any modification is to have a
dedicated `i3-session.target`:

```
[Unit]
Description=i3 session
BindsTo=graphical-session.target
Wants=wallpaper.service
Wants=wallpaper.timer
Wants=polybar.service
Wants=i3-companion.service
```

And trigger it from i3:

```
exec_always --no-startup-id systemctl --user start --no-block i3-session.target
```

The proposed change being quite small, it seems harmless and
low-maintenance.

Signed-off-by: Vincent Bernat <vincent@bernat.ch>
2021-08-30 15:20:04 +02:00
Uli Schlachter
7b6e864823 Implement support for the WM_Sn selection (#4374)
Closes #536

When the WM_Sn selection is already owned at startup, this now either
errors out or waits for the old selection owner to exit.
2021-08-28 01:01:38 +02:00
Jeff Smith
01ba240272 Fix bug where long commands crash i3
Commands with more than 10 words would result in i3 crashing. The root
cause is that the stack which holds arguments with identifiers is
only 10 big, but generate-command-parser.pl was giving every word an
identifier of "".
2021-08-24 16:34:30 -05:00
Michael Stapelberg
36ba1043d5 ipc: document scratchpad_state (#4466)
fixes https://github.com/i3/i3/issues/4465
2021-07-30 22:48:40 +02:00
Ingo Bürk
fee005bc87 Merge pull request #4460 from iscgar/isaac/all-criterion
Implement 'all' matching criterion
2021-07-26 08:05:25 +02:00
Isaac Garzon
3a818c0f20 Implement 'all' matching criterion
This criterion matches all open windows, as a more readable (and
correct) version of the 'class=".*"' criterion (more correct because
it'll also match windows which don't have WM_CLASS set yet).
2021-07-24 22:18:58 +03:00
tomty89
fc65ca36b1 Use mkdirp() in get_process_filename() (#4397)
Avoids race condition in case multiple i3 instances are started in parallel with e.g. systemd user units for multiple X(vfb) servers.
2021-07-05 17:21:21 +02:00
Michael Stapelberg
abbf6a85d7 Implement showing window icons in titlebar (#4439)
This feature defaults to off, and can be turned on for individual windows,
or (with for_window) for all new windows. See the userguide change.

This commit is partially based on work by:

• Marius Muja
• mickael9
• Esteve Varela Colominas
• Bernardo Menicagli
2021-06-13 08:35:52 +02:00
Michael Stapelberg
eaa5e636f9 Implement include config directive (#4420)
The implementation uses wordexp(3) just like sway:
https://github.com/i3/i3/issues/1197#issuecomment-226844106

Thanks to jajm for their implementation at
bb55709d0a

This required refactoring the config parser to be re-entrant
(no more global state) and to return an error instead of dying.

In case a file cannot be opened, i3 reports an error but proceeds with the
remaining configuration.

Key bindings can be overwritten or removed using the new --remove flag of the
bindsym/bindcode directive.

All files that were successfully included are displayed in i3 --moreversion.

One caveat is i3 config file variable expansion, see the note in the userguide.

fixes #4192
2021-06-02 21:01:43 +02:00
Ingo Bürk
4c93f61353 Merge pull request #4430 from stapelberg/actions
README: update build status badge for GitHub Actions
2021-05-23 16:35:38 +02:00
Michael Stapelberg
e4b3f46366 README: update build status badge for GitHub Actions 2021-05-23 16:06:13 +02:00
Michael Stapelberg
c94f41b2da switch from Travis to GitHub actions for continuous integration (CI) (#4428) 2021-05-23 15:44:28 +02:00
Vladimir Panteleev
e44aa7a9a9 docs/ipc: Explicitly state null as a possible type
This helps write correct descriptions of the JSON schema for strongly
typed languages that support deserializing to native types (and
require a different type for null).
2021-05-20 21:47:43 +02:00
Vladimir Panteleev
d4c23ec24b docs/ipc: Add descriptions of all message payloads
These seemed to be inconsistently specified.

Particularly, the "SYNC" message payload was not described anywhere.

Even when the payload is empty, it is helpful to specify that
explicitly, as it prevents the reader from having to guess whether if
it's really empty, or otherwise somehow implicitly obvious.

The "Reply format" section is now "Messages and replies", and covers
both the reply format and the format of sent messages.
2021-05-20 21:47:43 +02:00
Vladimir Panteleev
8db3bef66d docs/ipc: Explicitly state that reply types correspond to message types
Help avoid some squinting to make sure everything actually matches.
2021-05-20 21:47:43 +02:00
Vladimir Panteleev
63099f7a83 docs/ipc: Fix inconsistent whitespace 2021-05-20 21:47:43 +02:00
Vladimir Panteleev
1f75e8d321 docs/ipc: Re-order and clarify reply format
- Make sure to place the description of the packet before the
  description of the payload.

- Describe the relationship of messages and replies.

- Add note on pipelining.
2021-05-20 21:47:43 +02:00
Vladimir Panteleev
73bcbbe1b1 docs/ipc: Fix grammar
Add missing "it". Also add two instances of "a", which sounds more
correct to me.
2021-05-20 21:47:43 +02:00
Vladimir Panteleev
bb6ee88440 docs/ipc: Clarify i3 --get-socketpath text 2021-05-20 21:47:43 +02:00
Kjetil Torgrim Homme
2245db63ab add cross reference to directive default_border from command border (#4273)
Added a couple of examples to make usage clearer with a cursory glance.
2021-05-20 21:47:20 +02:00
Uli Schlachter
d65a7ed250 Drop xcb_flush() before xcb_aux_sync() (#4378)
xcb_flush() flushes xcb's output buffer. Thus, after this call, all
previous requests are surely written to the connection with the X11
server.

xcb_aux_sync() synchronises with the X11 server. It makes sure all
previous requests were sent to the X11 server and already processed. It
does this via free(xcb_get_input_focus_reply(xcb_get_input_focus())): It
sends a request and waits for its reply. It is guaranteed that the X11
server processes requests in-order.

This means that the sequence xcb_flush(); xcb_aux_sync() first writes
whatever is in the output buffer and then does another write for the
four bytes of the GetInputFocus request from xcb_aux_sync().

Put differently: xcb_flush(); xcb_aux_sync() doesn't do anything more
than just xcb_aux_sync(). In fact, it has slightly more overhead for the
same result.

Thus, this commit drops all calls to xcb_flush() immediately after
xcb_aux_sync().

Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-05-20 21:44:13 +02:00
Uli Schlachter
60542da091 Do not "set" the wallpaper during startup (#4373)
"Set" the wallpaper during startup only sometimes

Since commit 4f5e0e7, i3 would take a screenshot and set that as the
background pixmap of the root window during startup. This is the easy
part of setting a proper X11 wallpaper.

The code in question was added because something either set the
background pixmap of the root window to NONE or the X11 server was
started with "-background none". This is apparently done by default by
e.g. gdm to avoid some flickering while the X11 server starts up.

This commit makes this code conditional: Only when no wallpaper is
detected is a screenshot taken.

Since I could not find any way to query the background of a window, a
more direct approach is taken to detect this situation: First, we find
some part of the root window that is not currently covered. Then we open
a white window there, close it again and grab a screenshot. If a
wallpaper is set, the X11 server will draw this wallpaper after the
window is closed and something else will be visible in the screenshot.

However, the wallpaper could have a white pixel at the tested position.
Thus, this procedure is repeated with a black window.

Only when this procedure produces two different pixel values is a
screenshot taken and set as the wallpaper.

Fixes: https://github.com/i3/i3/issues/4371
Fixes: https://github.com/i3/i3/issues/2869
Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-05-20 21:37:35 +02:00
j-jzk
fcae64f7fd Increase test timeout (#4416)
Default of 30 seconds can time-out on slower hardware
2021-04-29 15:59:23 +02:00
Ingo Bürk
91e751d5a2 Merge pull request #4411 from alarsyo/fix-broken-pango-link
docs: fix broken link to Pango documentation
2021-04-26 16:29:32 +02:00
Antoine Martin
00d4836ee4 docs: fix broken link to Pango documentation 2021-04-26 16:13:27 +02:00
Michael Stapelberg
9db03797da fix crash with “layout default”: ipc.c won’t dump L_DEFAULT layout (#4409)
fixes #4408
2021-04-20 09:04:07 +02:00
Michael Stapelberg
c8158875b4 default config: use dex for XDG autostart (#4405)
fixes #4402
2021-04-17 15:26:45 +02:00
Ingo Bürk
9bf9cb9926 Merge pull request #4377 from lbonn/signed-container-positions
ipc: return signed int for container positions
2021-04-10 16:24:43 +02:00
lbonn
496364fdbf ipc: return signed int for container positions
If we use json as a language-agnostic representation, it makes sense to
use proper signed integers here.
2021-04-10 14:17:00 +02:00
Orestis Floros
fcf4c235d2 Merge pull request #4394 from jaykhandkar/fix-userguide
docs/userguide - comment out TODO line
2021-04-06 12:59:17 +02:00
Jay Khandkar
e150b99ba8 docs/userguide - comment out TODO line
commented out TODO line in userguide which was showing up in the
online documentation.
2021-03-28 15:34:59 +05:30
Ingo Bürk
39376a94ab Merge pull request #4387 from ivanmilov/milov/ipc-floating-doc
Added floating field to _tree_reply in ipc documentation
2021-03-16 16:52:15 +01:00
Ivan Milov
52afb16391 Added floating field to _tree_reply in ipc documentation 2021-03-15 10:42:39 +01:00
Uli Schlachter
1c67683406 Make this sound less "X11 is horrible"
Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-03-12 10:18:07 +01:00
Uli Schlachter
fd500ee99d Add a section on the sync IPC command
Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-03-12 10:18:07 +01:00
Uli Schlachter
8a5eac3457 Improve the docs for I3_SYNC
I was confused by the previous state of the docs since I imagined that
there is still a race possible. Thus, the images are updated to
explicitly include the IPC reply from i3 (since that is an important
synchronisation component). I also tried to clarify some of the text.

Fixes: https://github.com/i3/i3/issues/4365
Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-03-12 10:18:07 +01:00
Ingo Bürk
af2171d01d Merge pull request #4363 from psychon/more-prefetch
Prefetch some information through xcb
2021-03-06 19:06:16 +01:00
Uli Schlachter
db5a7dc22a Only prefetch xinerama if it is likely needed
Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-03-06 18:43:46 +01:00
Ingo Bürk
42c3dbe025 Merge pull request #4362 from psychon/no-temp-cairo-surface2
Some follow-up to
2021-03-06 11:10:57 +01:00
Uli Schlachter
f8bc7052ea Remove unused member from surface_t
Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-03-06 09:27:15 +01:00
Uli Schlachter
bae1f4b354 Prefetch some information through xcb
This commit makes libxcb prefetch some information that will be needed
later anyway. This avoids some round-trips to the X11 server since the
information is already present when needed.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-03-05 14:16:52 +01:00
Ingo Bürk
757b3dd573 Merge pull request #4361 from psychon/no-temp-cairo-surface
No temporary cairo surface for font drawing
2021-03-05 14:06:57 +01:00
Uli Schlachter
b23c8875f7 font: Get rid of temporary cairo surface
i3 actually manages to have two different cairo surfaces referring to
the same drawable. One comes from the code in draw_util. The second is
temporarily created while rendering text via draw_text(). No idea how
well cairo handles this case.

This commit instead changes the code to pass the already existing cairo
surface from the caller through.

This might or might not fix https://github.com/i3/i3/pull/4357. My
thinking here is that cairo now knows the actual size of the drawable
and thus does not clip the drawing to a smaller size.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-03-05 11:37:03 +01:00
Uli Schlachter
8d645d0de6 Remove draw_text_ascii()
This function is unused since commit fa488d721d from 2017.

Signed-off-by: Uli Schlachter <psychon@znc.in>
2021-03-05 11:36:09 +01:00
Michael Stapelberg
46bc841162 Merge branch 'release-4.19.2' 2021-02-27 10:38:13 +01:00
Michael Stapelberg
7da136dca4 Update debian/changelog 2021-02-27 10:38:13 +01:00
Michael Stapelberg
4ef47087d4 Restore non-git version suffix 2021-02-27 10:38:13 +01:00
Michael Stapelberg
98e0a07f15 Merge branch 'stable' into next 2021-02-27 10:38:13 +01:00
Michael Stapelberg
ddebebd26b release i3 4.19.2 2021-02-27 10:37:57 +01:00
Michael Stapelberg
0e1a828003 cherry-pick release.sh changes into stable branch
related to https://github.com/i3/i3/issues/4350
2021-02-27 10:20:16 +01:00
Michael Stapelberg
b95bab0e34 mark travis/push-balto.sh as executable (#4347)
related to https://github.com/i3/i3/issues/4340
2021-02-13 10:10:59 +01:00
Michael Stapelberg
521949b567 travis: push i3 autobuild packages to balto instead of bintray (#4345)
related to https://github.com/i3/i3/issues/4340
2021-02-13 09:56:15 +01:00
Orestis Floros
5df0b4b571 Merge pull request #4336 from tbgiles/next
Clear framebuffer for containers with visible windows
2021-02-07 19:10:23 +01:00
Orestis Floros
e8949c7df1 Merge pull request #4338 from orestisfl/move-workspaces-to-multiple-outputs
Move workspaces to multiple outputs
2021-02-06 12:52:08 +01:00
Orestis Floros
8ff8db3c36 Accept multiple outputs in move container|workspace to output
Fixes #4337
2021-02-06 11:00:16 +01:00
Orestis Floros
f2243a7a90 Tests: Fix get_output_for_workspace
In the case of more than one workspaces in an output
2021-02-06 10:59:16 +01:00
Michael Stapelberg
36b6fef990 Merge branch 'release-4.19.1' 2021-02-01 09:04:01 +01:00
Michael Stapelberg
ab2a22a78b Update debian/changelog 2021-02-01 09:04:01 +01:00
Michael Stapelberg
001577c58c Set non-git version to 4.19.1-non-git. 2021-02-01 09:04:01 +01:00
Michael Stapelberg
33bbce6c38 Merge branch 'stable' into next 2021-02-01 09:04:01 +01:00
Michael Stapelberg
0fb9123da9 release i3 4.19.1 2021-02-01 09:03:45 +01:00
Imran Virani
77d5bbb9b5 Properly quote rofi call in i3 config 2021-02-01 08:54:48 +01:00
Orestis Floros
b35be84131 Comment-out duplicate i3-dmenu-desktop bindcode
Fixes #4304
2021-02-01 08:54:26 +01:00
Anaël Beutot
0c09bc24ff Fix workspace assignements after output changes
Fix #4261

The previous method was modifying the same list it was iterating upon
causing an erronous iteration and thus not every workspace got assigned
back to were they should (only the first one).
2021-02-01 08:53:36 +01:00
Tristan Giles
09e2bdaeba Clear framebuffer on containers that are visible windows 2021-01-30 22:44:43 -08:00
Orestis Floros
ef12e9a5ab Merge pull request #4331 from ImranVirani/patch-1
Properly quote rofi call in i3 config
2021-01-29 16:20:15 +01:00
Imran Virani
60213accae Properly quote rofi call in i3 config 2021-01-29 14:01:51 +01:00
Orestis Floros
62367c686d Merge pull request #4007 from xzfc/3981-client-machine
Match WM_CLIENT_MACHINE
2021-01-28 14:52:50 +01:00
Albert Safin
32c10a19f2 Add "machine" criterion to match WM_CLIENT_MACHINE
Closes #3981

Add "%machine" title_format placeholder
Add "machine" to the IPC and layout saving/restoring
2021-01-28 12:52:10 +01:00
Orestis Floros
921226783f Merge pull request #4330 from orestisfl/revert-clear-framebuffer
Revert "Clear framebuffer before drawing borders (#4308)"
2021-01-26 10:37:49 +01:00
Orestis Floros
8c8d5dc019 Revert "Clear framebuffer before drawing borders (#4308)"
This reverts commit 057a635279.
2021-01-25 08:13:15 +01:00
Michael Stapelberg
dcd6079c9b i3-dump-log -f: switch from pthreads to UNIX sockets
fixes #4117
2021-01-20 21:40:24 +01:00
Michael Stapelberg
131a6158c8 move set_nonblock, create_socket and path_exists to libi3 2021-01-20 21:40:24 +01:00
Orestis Floros
e4f12ac349 Merge pull request #4322 from orestisfl/i3bar-version
i3bar log version & correct exit code
2021-01-17 00:52:37 +01:00
Orestis Floros
ba134d3c7c i3bar: Exit with 1 on wrong argument 2021-01-15 23:35:31 +01:00
Orestis Floros
6668d03157 i3bar: LOG version on startup 2021-01-15 23:28:33 +01:00
Orestis Floros
9c7616cc98 Merge pull request #4315 from orestisfl/i3bar-fixes
I3bar fixes
2021-01-12 09:10:22 +01:00
Orestis Floros
1a29b28fa5 i3bar: No reason to get_workspaces after output event
got_output_reply() requests this information anyway and if it is
received before the output reply, the information will be erased by
get_output_reply().
2021-01-12 08:56:38 +01:00
Orestis Floros
6e0b29a65b i3bar: properly restart status command after config change 2021-01-12 08:56:38 +01:00
Orestis Floros
0370c5e297 i3bar: Properly close FDs 2021-01-12 08:35:41 +01:00
Orestis Floros
31580ddc7f Merge pull request #4231 from orestisfl/i3bar-default-bar_id
i3bar: Add default bar_id
2021-01-03 19:49:25 +01:00
Orestis Floros
052c4bea5c Merge pull request #4309 from i3/orestisfl-patch-1
Add release note for framebuffer fix
2021-01-03 10:26:55 +01:00
Orestis Floros
c1ec2ad19b i3bar: Add default bar_id
Instead of erroring, request the list of bar configs from i3 and use the
first one.
2021-01-03 10:17:43 +01:00
Orestis Floros
fb5d2a05c2 i3bar: Update manpage/help with options 2021-01-03 10:17:39 +01:00
Orestis Floros
2a2c350eb6 Add release note for framebuffer fix
#4308
2021-01-03 09:48:27 +01:00
Tristan Giles
057a635279 Clear framebuffer before drawing borders (#4308)
Clear framebuffer before copying surface to prevent visual garbage

Fixes #3481
Corrects problems of #4280
2021-01-03 09:36:43 +01:00
Ingo Bürk
d3d2612eba Merge pull request #4307 from i3/revert-4280-next
Revert "Clear pixmap to black before starting to draw"
2021-01-03 08:18:03 +01:00
Orestis Floros
5bf58a4c87 Revert "Clear pixmap to black before starting to draw" 2021-01-03 01:11:21 +01:00
Orestis Floros
bfa22cafea Merge pull request #4280 from tbgiles/next
Clear pixmap to black before starting to draw
2021-01-03 00:36:31 +01:00
Tristan Giles
337dd653ae Clear framebuffer before copying surface to prevent visual garbage
Fixes #3481
2021-01-02 23:54:11 +01:00
Orestis Floros
8d0b8b59c4 Merge pull request #4305 from i3/orestisfl-patch-1
Comment-out i3-dmenu-desktop bindcode
2021-01-02 23:09:06 +01:00
Orestis Floros
3f063bcb6f Comment-out duplicate i3-dmenu-desktop bindcode
Fixes #4304
2021-01-02 21:54:36 +01:00
Orestis Floros
b638ca593d Merge pull request #4230 from Xyene/tab-focus
Implement context-sensitive tab-clicking behavior
2021-01-01 22:17:27 +01:00
Tudor Brindus
f2ec5a4e77 Implement context-sensitive tab-clicking behavior
This commit makes it so that when clicking on a tab for the first time,
its inactive-focused child is focused. This matches i3 behavior when
scrolling on tabs.

A second click on the tab titlebar focuses the tab container itself.

Subsequent clicks cycle between these two states.

Closes #4225.
2021-01-01 16:04:33 -05:00
Orestis Floros
b2af112a04 Merge pull request #4284 from sojito/next
Add missing SYNC Reply type in IPC docs
2021-01-01 15:57:04 +01:00
Orestis Floros
87f033fbd4 Merge pull request #4299 from abeutot/fix_workspace_assignment_on_screen_change
Fix workspace assignment on screen change
2020-12-30 23:33:08 +01:00
Anaël Beutot
d539c6e288 Fix workspace assignements after output changes
Fix #4261

The previous method was modifying the same list it was iterating upon
causing an erronous iteration and thus not every workspace got assigned
back to were they should (only the first one).
2020-12-30 23:01:50 +01:00
Orestis Floros
5354eaa27e Merge pull request #4300 from abeutot/cleanup_remaining_cmdparse
Remove unused header file and references to it
2020-12-30 22:09:09 +01:00
Anaël Beutot
b1fb440345 Remove unused header file and references to it 2020-12-30 21:40:54 +01:00
Ingo Bürk
1d06cb976e Merge pull request #4297 from Airblader/feature-requests-doc
[Proposal] Update CONTRIBUTING and issue template(s) for feature requests
2020-12-30 20:17:32 +01:00
Ingo Bürk
b6ced01676 Update CONTRIBUTING and issue template(s) for feature requests 2020-12-29 20:29:48 +01:00
Michael Stapelberg
74b461e25e build.i3wm.org: disallow search engine indexing (#4295)
related to https://github.com/i3/i3.github.io/issues/41
2020-12-29 20:05:59 +01:00
Orestis Floros
da1a720782 Merge pull request #4296 from stapelberg/spelling
check-spelling: exempt typo until upstream merges the fix
2020-12-29 17:37:59 +01:00
Michael Stapelberg
3a1e44da68 check-spelling: exempt typo until upstream merges the fix
This must have come in with a new version of clang.
2020-12-29 17:13:11 +01:00
Romuald Brunet
146305d6c6 Remove small bulge in i3 SVG logo (#4281)
* Upgrade logo's inkscape SVG attributes

Inscape changed their attribute handling with version 1.0, this commit
is dedicated to this change

* Update logo to remove small bulge
2020-12-28 23:22:22 +01:00
Ralph Gutkowski
679335f19b Add missing SYNC Reply type in IPC docs 2020-12-16 16:36:55 +01:00
ajakk
27ff84ff42 Use docdir for all docs when building (#4269) 2020-12-08 08:11:59 +01:00
Orestis Floros
be4790802e Merge pull request #4244 from ekarpp/nagbar
i3-nagbar: add possibility to open bar on focused monitor
2020-11-29 23:34:43 +01:00
ekarpp
b6690045ed i3-nagbar: add possibility to open bar on focused monitor
Closes #3692

i3-nagbar will open by default on the monitor with input focus and using the flag -p on the primary monitor.
2020-11-29 22:36:49 +01:00
Orestis Floros
37ebd2a179 Merge pull request #4252 from orestisfl/create_workspace_on_output-duplicate-num
create_workspace_on_output: Prevent duplicate workspace nums
2020-11-28 23:41:49 +01:00
Orestis Floros
13757ac1ca workspace.c: Make small consistency changes 2020-11-28 23:22:55 +01:00
Orestis Floros
68258785ac create_workspace_on_output: Prevent duplicate workspace nums
When going through the `binding_workspace_names` to prioritize
user-specified names, we only check if the workspace exists, not the
workspace number. If the user specified a `bindsym … workspace number X`
directive, then it is appended in `binding_workspace_names` and a
workspace is created using that number even though from the POV of a
user that uses numbers to change workspaces, that workspace already
exists.

In similar code here:
1d9160f2d2/src/workspace.c (L997)
we do the check.

Fixes #4238
2020-11-28 23:22:55 +01:00
Dmitri Goutnik
d0067077ed declare parser generated sources as deps (#4264) 2020-11-21 19:18:24 +01:00
Michael Stapelberg
eb83b37936 userguide: clarify home row / vi navigational key relation (#4260)
Before this commit, the userguide mentioned “compatibility with most keyboard
layouts”, but that seems to not have been the intention of vi author(s).
2020-11-16 11:10:03 +01:00
Michael Stapelberg
9f3a3a1d98 i3-sensible-terminal: prioritize terminals with good accessibility (#4259)
We never did (and still do not) guarantee any order in which terminal emulators
are tried. Quoting from the i3-sensible-terminal man page:

> Please don’t complain about the order: If the user has any preference, they
> will have $TERMINAL set or modified their i3 configuration file.

This commit moves mate-terminal to the beginning of the list, which is
considered the most accessible terminal emulator among blind users.

fixes https://github.com/i3/i3/issues/4256
2020-11-16 09:56:49 +01:00
Michael Stapelberg
4b1ea08eef release.sh and release notes changes post-release (#4258) 2020-11-15 19:22:09 +01:00
Michael Stapelberg
a901498758 debian: update changelog 2020-11-15 18:28:25 +01:00
Michael Stapelberg
e6af0a5427 Merge branch 'next' into stable 2020-11-15 18:23:15 +01:00
Michael Stapelberg
2e59f512e3 Merge branch 'release-4.19' 2020-11-15 18:23:15 +01:00
Michael Stapelberg
8ac9a815f3 Restore non-git version suffix 2020-11-15 18:23:15 +01:00
Michael Stapelberg
969e6bc8c4 release i3 4.19 2020-11-15 18:23:00 +01:00
Michael Stapelberg
93d3f9cc6a remove now-unnecessary I3_VERSION file
related to https://github.com/i3/i3/issues/4086
2020-11-15 16:42:41 +01:00
Michael Stapelberg
f4d784b5a7 debian/rules: remove now-unnecessary override
related to https://github.com/i3/i3/issues/4086
2020-11-15 16:42:41 +01:00
Michael Stapelberg
60c89296c1 gitignore: remove now-unused autotools files
related to https://github.com/i3/i3/issues/4086
2020-11-15 16:42:41 +01:00
Michael Stapelberg
a4c12432cf travis: remove autotools build in favor of meson
related to https://github.com/i3/i3/issues/4086
2020-11-15 16:42:41 +01:00
Michael Stapelberg
358471a5f2 remove autotools files in favor of meson
related to https://github.com/i3/i3/issues/4086
2020-11-15 16:42:41 +01:00
Michael Stapelberg
8c0077c058 Update compilation instructions throughout our docs
related to https://github.com/i3/i3/issues/4086
2020-11-15 16:42:41 +01:00
Orestis Floros
e9610b84f6 Merge pull request #4249 from wlhlm/issue-3889-v2
Only swallow windows once v2
2020-11-10 18:54:13 +01:00
Wilhelm Schuster
c246f176eb Add regression test for #3888 2020-11-10 17:16:56 +01:00
izzel
377f7d7ab2 added remanage swallow check 2020-11-10 16:58:43 +01:00
Orestis Floros
1d9160f2d2 Merge pull request #4243 from stapelberg/parseerror
ipc: document parse_error COMMAND reply field
2020-11-03 11:51:42 +01:00
Michael Stapelberg
829b4d2b7c config: specify --no-startup-id for dmenu_run
fixes #4216
2020-11-03 11:35:40 +01:00
Michael Stapelberg
c22b35c293 ipc: document parse_error COMMAND reply field
fixes #4166
2020-11-03 09:48:28 +01:00
Orestis Floros
19fbe1d30c Merge pull request #4240 from stapelberg/may
userguide: may → might in most places (thanks Bruce)
2020-11-01 21:13:23 +01:00
Michael Stapelberg
6a1806931b userguide: may → might in most places (thanks Bruce)
Quoting https://www.freelists.org/post/i3-discuss/Grammar-check-in-the-doc

May inquires only into permission.
Might inquires into probability.
Can inquires into possibility.
Will/shall inquires into certainty.
2020-11-01 10:09:43 +01:00
Michael Stapelberg
8a7ac068c8 meson.build: fix typo in summary: docs → mans 2020-10-28 21:34:48 +01:00
Michael Stapelberg
5c565d0ad4 debian/rules: explicitly enable building manpages
This fixes a build failure in dh_installwms.

fixes #4136
2020-10-28 21:34:48 +01:00
Orestis Floros
e54e88b9e5 Merge pull request #4229 from stapelberg/next
travis: fix bintray deploy step
2020-10-25 22:42:09 +01:00
Michael Stapelberg
466f7c16f9 travis: fix bintray deploy step
Commit be1065f62d moved the Debian/Ubuntu package
builds into the distbuild/ directory.

fixes #4179
2020-10-25 21:54:07 +01:00
Orestis Floros
a24c9b65e1 Merge pull request #4195 from mschuwalow/i3bar-nonprimary-output
i3bar: add support for nonprimary output
2020-10-24 14:29:17 +02:00
Maxim Schuwalow
90e7a156a2 i3bar: add support for nonprimary output
Added a new output option `nonprimary` that causes the bar to be
displayed on all outputs except the primary one.

Fixes #4083
2020-10-24 11:44:34 +02:00
Orestis Floros
3cd1c45eba Merge pull request #4214 from burik666/i3bar-output_xy
Add coordinates relative to the current output in i3bar click events
2020-10-23 13:56:57 +02:00
Andrey Burov
60384d446b Add coordinates relative to the current output in i3bar click events
Currently i3bar click events provide x and y coordinates relative to all monitors.
I've added coordinates relative to the current output.

+-----------+-----------+
|           |   i3bar   |
|           +-----------+
|   HDMI-0  |    DP-0   |
| 1920x1080 | 2560x1080 |
+-----------+-----------+

When you click in the top right corner of the DP-0,
i3bar will provide something like this:

{
  "x": 4480,
  "y": 10,
  "output_x": 2560,
  "output_y": 10,
}

This is useful for creating a rofi menu or something else.
rofi -show run -location 1 -xoffset ${I3_OUTPUT_X} -yoffset ${I3_OUTPUT_Y}
2020-10-23 12:51:21 +03:00
Orestis Floros
e6f419b882 Merge pull request #4189 from acheronfail/feat-3519/ppt-move-position
allow ppt values in move direction and move position commands
2020-10-20 11:20:20 +02:00
Orestis Floros
ffad26beb0 Merge pull request #3957 from xzfc/clang-format-typenamemacros
clang-format: use TypenameMacros
2020-10-20 09:43:24 +02:00
Alessandro Vinciguerra
9e059ccc55 Add situational exit codes (#4107)
Add situational exit codes

Distinguish user canceled and other errors
Closes #3705
2020-10-20 09:38:35 +02:00
Albert Safin
e3a1c5b294 clang-format: use TypenameMacros
This commit removes line breaks and extra empty lines introduced in
commit fff3f79da9.
2020-10-20 09:36:44 +02:00
acheronfail
fae10f6df7 allow ppt values in move direction and move position commands
make ppt values clear in userguide

chore: move is_ppt and DLOG out of TAILQ_FOREACH loop
2020-10-20 17:48:26 +11:00
Michael Stapelberg
83078a1e16 debian: update changelog 2020-10-19 23:41:16 +02:00
Michael Stapelberg
036903e8b2 Merge branch 'release-4.18.3' 2020-10-19 23:17:05 +02:00
Michael Stapelberg
ce01babc7c Update debian/changelog 2020-10-19 23:17:05 +02:00
Michael Stapelberg
4da7e318e5 Set non-git version to 4.18.3-non-git. 2020-10-19 23:17:05 +02:00
Michael Stapelberg
e6b4e1314a Merge branch 'stable' into next 2020-10-19 23:17:05 +02:00
Michael Stapelberg
b2ac041ffa release i3 4.18.3 2020-10-19 23:16:56 +02:00
Orestis Floros
eaac9125a9 meson: Mark complete-run.pl as executable (#4224)
Fixes problem described in
https://github.com/i3/i3/issues/4086#issuecomment-711774506
2020-10-19 22:10:14 +02:00
Orestis Floros
3b2f15e613 Merge pull request #4023 from orestisfl/ws-assignment
Fix 2 workspace assignment bugs
2020-10-19 10:41:39 +02:00
Mark Guptill
654e2cefa6 kick tray clients before destroying the bar 2020-10-19 09:45:51 +02:00
Orestis Floros
71c059d033 i3-dmenu-desktop: Manually search for topdir (#4033)
Since 3a672bc, using follow or follow_fast, does not set
$File::Find::topdir, breaking our deduplication.

Fixes #4031
2020-10-18 20:02:37 +02:00
Orestis Floros
b6024122dc Fix conflicting workspace assignments when renaming
The bug here is that workspace assignments with numbers are triggered
even if a named argument matches later on.

With this commit, get_assigned_output is called to correctly iterate the
workspace assignments.

Fixes #4021
2020-10-18 17:28:55 +02:00
Orestis Floros
0d5a7eeff8 init_ws_for_output: Change loop that assigns existing workspaces
I find the new loop more straightforward and easy to understand.

Old loop used to be:
    foreach assignment:
        foreach assignment2:
            // find if this is the first valid output in this assignment
        foreach workspace:
            // find matching by assignment name
        if workspace:
            move workspace to output
New loop is:
    foreach workspace:
        foreach assignment:
            if workspace is assigned to this output:
                move workspace to output

With this, workspace assignments triggered by numbers during output
changes should be handled correctly.

Fixes #3685
2020-10-18 17:28:53 +02:00
Orestis Floros
6b2d8cb4d6 Make get_assigned_output public 2020-10-18 17:28:14 +02:00
Orestis Floros
9d2c855fcd workspace_get: Remove useless argument
Also reworks the structure a bit
2020-10-18 17:28:14 +02:00
Orestis Floros
9b295fbb57 Remove dead declarations in header files 2020-10-18 17:28:09 +02:00
Orestis Floros
440268f454 Merge pull request #4116 from ammgws/patch-1
Update WORKSPACES reply docs
2020-10-15 09:41:54 +02:00
Orestis Floros
fff8b0c0e8 Merge pull request #4172 from jorgheymans/patch-1
increase font-size for kbd in refcard
2020-10-13 10:29:18 +02:00
Orestis Floros
144c483b08 Merge pull request #4197 from zero77/patch-1
Update README.md
2020-10-13 10:26:54 +02:00
zero77
9c826655a3 Update README.md
This quickly shows all package versions across different distros at a glance.
2020-09-15 13:41:34 +00:00
Mike Sharov
04c489043c Reformat LICENSE so github sees it as BSD-3-Clause. (#4181)
This changes LICENSE text to the standard BSD-3-Clause text.
	The wording is almost identical, with only "copyright holders
	and contributors" replacing "Michael Stapelberg and contributors"
	in the license text.
2020-09-02 11:42:05 +02:00
Orestis Floros
f33a49372f i3bar: Remove duplicate call to kick_tray_clients (#4163)
Fixes #4159
Fixes #4162
2020-08-31 08:58:46 +02:00
Jorg Heymans
fa94d2d8a9 increase font-size for kbd in refcard
fixes https://github.com/i3/i3/issues/4135
2020-08-10 22:53:44 +02:00
Orestis Floros
e5992eed16 Merge pull request #4145 from i3/orestisfl-patch-2
route_click: Correctly eat the event
2020-08-01 09:43:26 +02:00
Michael Stapelberg
15e51ca38c Update debian/changelog 2020-07-26 10:25:37 +02:00
Michael Stapelberg
5af9ea65fe Merge branch 'release-4.18.2' 2020-07-26 10:11:49 +02:00
Michael Stapelberg
6bb01bbe83 Merge branch 'stable' into next 2020-07-26 10:11:49 +02:00
Michael Stapelberg
768fd7f21c Set non-git version to 4.18.2-non-git. 2020-07-26 10:11:49 +02:00
Michael Stapelberg
82450c9508 release i3 4.18.2 2020-07-26 10:11:37 +02:00
Orestis Floros
68904aeb38 Fix i3bar Xorg memory leak (#4140)
The `*_free_*` calls in this branch:
51b0583578/i3bar/src/xcb.c (L1854)
are never called when we remove the output from the tailq during a
refresh.

Fixes #4123
2020-07-22 09:33:19 +02:00
Orestis Floros
551d0a5b13 get_output_by_name: guard output->primary with require_active
This is related to #4048 but might not fix it completely. Either way,
this should be the correct behaviour of the function.
2020-07-22 09:32:29 +02:00
Orestis Floros
96639c0410 floating_maybe_reassign_ws: only re-focus if previously focused
Fixes #3979
2020-07-22 09:24:24 +02:00
Orestis Floros
e674073027 Merge pull request #4147 from compguy284/kick_tray_clients
kick tray clients before destroying the bar
2020-06-30 11:19:36 +02:00
Mark Guptill
838b600fea kick tray clients before destroying the bar 2020-06-30 04:34:32 -04:00
Orestis Floros
1449d4890f Merge pull request #4146 from lukaskern/next
Fixed a typo in the user's guide
2020-06-29 21:00:12 +02:00
Lukas Kern
2c1b18b1ac Fixed a typo in the user's guide 2020-06-29 20:34:35 +02:00
Orestis Floros
65e468edd7 route_click: Correctly eat the event
Restores original intention of 93e96f4 after #4144
2020-06-29 10:47:50 +02:00
Ingo Bürk
a45eb8156c Merge pull request #4144 from i3/orestisfl-patch-2
route_click: Fix regression: release mouse
2020-06-29 10:25:00 +02:00
Orestis Floros
874d862507 route_click: Fix regression: release mouse
Fixes #4143
2020-06-29 09:55:11 +02:00
Orestis Floros
025743eaf9 Fix i3bar Xorg memory leak (#4140)
The `*_free_*` calls in this branch:
51b0583578/i3bar/src/xcb.c (L1854)
are never called when we remove the output from the tailq during a
refresh.

Fixes #4123
2020-06-27 00:10:53 +02:00
Ingo Bürk
51b0583578 Merge pull request #4133 from VasilyFomin/patch-1
Fixed a typo in the docs
2020-06-25 08:34:53 +02:00
Vasily Fomin
24e30a81c3 Fixed a typo in the docs 2020-06-24 17:51:05 -07:00
Orestis Floros
5bc5fc188b Merge pull request #4131 from stapelberg/bindingstate
binding state post-submit review fixes
2020-06-17 11:22:23 +02:00
Michael Stapelberg
b402ce2cc9 binding state post-submit review fixes 2020-06-16 22:28:58 +02:00
Jason
4e676ef73e i3-msg: add missing option (#4128) 2020-06-16 22:27:39 +02:00
Michael Stapelberg
4085c4be3b the stable version can now be found in the stable branch (#4129)
fixes #4127
2020-06-15 12:00:24 +02:00
Jason
209bef7ea3 Update WORKSPACES reply docs 2020-06-14 08:22:10 +09:00
Ingo Bürk
cf09cc790c Merge pull request #4125 from orestisfl/move-fullscreen-to-ws
_con_move_to_con: Traverse below con to check for fullscreen
2020-06-10 08:14:11 +02:00
Orestis Floros
4d9c3131ad _con_move_to_con: Traverse below con to check for fullscreen
Fixes #4124
2020-06-10 03:44:02 +02:00
Ingo Bürk
f4964faef0 Merge pull request #4122 from stapelberg/bindingstate
Introduce GET_BINDING_STATE IPC command
2020-06-07 00:17:34 +02:00
Michael Stapelberg
45feaac54c Introduce GET_BINDING_STATE IPC command
fixes #3892
2020-06-06 20:39:05 +02:00
Orestis Floros
50160eb13b Merge pull request #4120 from stapelberg/meson-i3test
add i3test_pm dependency after all
2020-06-06 14:25:16 +02:00
Michael Stapelberg
ac5368770e add i3test_pm dependency after all
I suppose the now-conditional docs building had previously pulled in i3test_pm
implicitly.

related to #4086
2020-06-06 14:14:24 +02:00
Michael Stapelberg
ff77b67101 switch from clang-format-6 to clang-format-9 (#4121)
No changes required, but this unbreaks our CI
2020-06-06 14:03:31 +02:00
Orestis Floros
db2526c39c Merge pull request #4109 from i3/orestisfl-patch-2
i3-input: Fix memory leaks
2020-05-31 12:15:45 +02:00
Orestis Floros
c9f8183841 Merge pull request #4114 from orestisfl/i3bar-regression
Fix swapped cmd_bar_{mode,hidden_state}
2020-05-31 12:15:20 +02:00
Ingo Bürk
51d6ddf323 Merge pull request #4115 from ammgws/pwoerdocs
i3bar: improve docs for battery saving feature
2020-05-31 11:07:58 +02:00
Jason Nader
cf94ce6c2b i3bar: improve docs for battery saving feature 2020-05-31 17:06:07 +09:00
Orestis Floros
ae9613576f Fix swapped cmd_bar_{mode,hidden_state}
Mentioned in
fb2677f5f4 (r39550195)
2020-05-30 16:46:14 +02:00
Orestis Floros
128f9c0109 i3-input: Fix memory leaks
Mentioned in #4107
2020-05-28 10:23:40 +02:00
Orestis Floros
dd13398e04 Merge pull request #4106 from orestisfl/nagbar
Improve handling of nagbar processes
2020-05-24 15:16:08 +02:00
Orestis Floros
00ffa68a6c Move nagbar cleanup to i3_exit
Otherwise, each time we start a nagbar, a cleanup handler is created.
However, each of these handlers tries to kill the same process (->data
is a pointer to config_error_nagbar_pid / command_error_nagbar_pid).

With this commit, both potential nagbar processes are killed once.
2020-05-24 13:04:33 +02:00
Orestis Floros
78595f1f68 Improve handling of nagbar processes
Other changes in nagbar_exited:
- Remove ERROR from ELOG as it shows up as "ERROR: ERROR:"
- Make sure to reset the PID even when the process did not exit
normally.
- Use ELOG when exitcode != 0
- Remove the not found error: if nagbar is not in $PATH, exec_i3_utility
prints an error as well.

For the record, I also implemented a more complicated approach with a
new watcher data structure:
bd3aaf3a33
While writing the commit message, it occurred to me to compare
watcher->pid with *watcher->data, which fixes the problems mentioned in
that patch.

Fixes #4104
2020-05-24 13:04:33 +02:00
Orestis Floros
6e087d4a20 kill_nagbar: No need for pointer to pid_t 2020-05-24 13:04:33 +02:00
Orestis Floros
9aa28f357f Merge pull request #4100 from stapelberg/meson-fixes
meson: only install docs/man pages when they exist (release tarball)
2020-05-19 22:44:47 +02:00
Michael Stapelberg
bec3887fc8 meson: only install docs/man pages when they exist (release tarball)
related to #4086
2020-05-19 22:28:21 +02:00
Michael Stapelberg
d09ed08668 Merge pull request #4098 from stapelberg/meson-fixes
More CI fixes
2020-05-19 22:12:06 +02:00
Michael Stapelberg
abf9b18f12 docs.sh: no longer rely on now-deleted debian/i3-wm.{manpages,docs}
related to #4086
2020-05-19 20:27:50 +02:00
Michael Stapelberg
be1065f62d debian-build: s/build/distbuild/
related to #4086
2020-05-19 20:27:50 +02:00
Michael Stapelberg
4544a6d595 travis: build dist tarball after running tests
This way, users get more detailed feedback about new test failures.

related to #4086
2020-05-19 20:27:50 +02:00
Michael Stapelberg
0c0aef84fa Merge pull request #4096 from stapelberg/meson-fixes
meson fixes for unbreaking the Debian/Ubuntu package builds on Travis
2020-05-19 19:59:42 +02:00
Michael Stapelberg
571eec861e debian: remove i3-wm.{docs,manpages}, meson installs them
related to #4086
2020-05-19 19:36:56 +02:00
Michael Stapelberg
315f646876 meson: install docs from release tarball
related to #4086
2020-05-19 19:36:56 +02:00
Michael Stapelberg
2e23412f5d debian-build: use release tarball from build step
…instead of building a release tarball over and over again.

This has become an issue as meson insists on running tests before creating a
release tarball (which is a good policy).

related to #4086
2020-05-19 19:36:56 +02:00
Michael Stapelberg
0bea175b51 disable dh_autoreconf
We still have autotools in the tree, so this is not a no-op yet.

related to #4086
2020-05-19 19:07:53 +02:00
Michael Stapelberg
ff6c2d2214 debian: set buildsystem to meson, not meson+ninja
The latter fails on Ubuntu, presumably due to an older debhelper version.

related to #4086
2020-05-19 19:07:51 +02:00
Michael Stapelberg
97e477777e meson: install static documentation files
related to #4086
2020-05-19 19:07:48 +02:00
Michael Stapelberg
693eee0c03 meson: make docdir configurable
The debian package wants to install docs to $datadir/doc/i3-wm.

related to #4086
2020-05-19 19:07:45 +02:00
Michael Stapelberg
aba6ec3e52 add meson build files (#4094)
Motivation:

• faster builds (on an Intel Core i9-9900K):
  ( ../configure --disable-sanitizers && make -j8; )
  19,47s user 2,78s system 395% cpu 5,632 total

  ( meson .. -Dmans=true -Ddocs=true -Dprefix=/usr && ninja; )
  38,67s user 3,73s system 1095% cpu 3,871 total

• more approachable build system configuration in the
  python-esque meson domain specific language instead of
  the autotools m4 macro language

• built-in language server support thanks to ninja:
  the required compile_commands.json is built automatically
  and only needs to be linked from the source dir, e.g.:
  ln -s build/compile_commands.json .

Changes:

• the embedded vcs version info format changed from e.g.
  4.18-282-gabe46f69 (2020-05-16, branch "next")
  to:
  4.18-282-gabe46f69
  I think it’s better to lose a little bit of detail for
  the gained cleanliness of using meson’s vcs_tag()

• Drop unused xcb-event dependency.

• We can no longer enable sanitizers and debug options
  based on whether we are in a release or non-release build,
  because our new version logic runs at ninja build time,
  not at meson configure time.

  The new behavior is probably for the better in terms of
  what people expect, and we can make the CI use address sanitizer
  explicitly to ensure it is still exercised.

• We lose the AX_EXTEND_SRCDIR behavior, i.e. including the
  path component of the parent of the source dir in all paths.
  This was a trick we used for easier debugging, so that stack
  traces would contain e.g. ../i3-4.18.1/src/main.c, instead of
  just src/main.c.

  The other mechanism (_i3_version symbol) that we have for including
  the version number in the “backtrace full” (but not merely
  “backtrace”) output of gdb still works.

• Release tarballs now use tar.xz. Why not.

Migration plan

This commit adds the meson build files to the tree, but does not remove
autotools yet. For the development phase, we will keep both build systems
functional (and built on travis).

Then, just before the i3 v4.19 release, we will remove autotools from the tree
and the release tarball will require meson to compile.

This way, we incentivize maintainers to change, while also offering them an easy
way out (if desired) by reverting the most recent commit. In practice, switching
a distribution package from autotools to meson should only be a few line change,
easier than applying the provided patch :). Take a look at the debian/ changes
in this commit for an example.

meson is broadly available everywhere that i3 is available: Both xorg-server and
systemd gained meson build files in 2017, so we can follow suit:
https://anholt.livejournal.com/52574.html
https://in.waw.pl/~zbyszek/blog/systemd-meson.html

How do I?

For producing a coverage report, enable the b_coverage meson base option
and run ninja coverage-html:
% cd build
% meson .. -Db_coverage=true
% ninja
% ninja test
% ninja coverage-html
See also https://mesonbuild.com/howtox.html#producing-a-coverage-report

For using the address sanitizer, memory sanitizer or undefined behavior
sanitizer, use the b_sanitize meson base option:
% cd build
% meson .. -Db_sanitize=address
% ninja
See also https://mesonbuild.com/Builtin-options.html#base-options

related to #4086
2020-05-19 14:45:06 +02:00
Michael Stapelberg
ef8935b1db autotools: place binaries in top level of build dir, not in subdirs (#4093)
meson only supports the top level (no subdirs), so this makes the transition
easier.

For this to work with autotools, we need to *disable* the subdir-objects option,
that autotools wants us to enable for forward-compatibility.

This results in a bunch of warnings at autoreconf-time, but we don’t care, given
that we intend to switch away from autotools. Both build systems working next to
each other (as best as they can) is more important.

related to #4086
2020-05-18 22:18:00 +02:00
Orestis Floros
75963cd088 Merge pull request #4092 from stapelberg/fixup
update forgotten srcdir AnyEvent-I3 reference, remove xmacro files
2020-05-18 21:23:43 +02:00
Michael Stapelberg
ddebce8a7f update forgotten srcdir AnyEvent-I3 reference, remove xmacro files
Both oversights in the previous commits.
2020-05-18 20:40:07 +02:00
Orestis Floros
7a4354f42a Merge pull request #4088 from stapelberg/san
free(socket_path) to suppress leak sanitizer false-positive with -O2
2020-05-18 18:25:19 +02:00
Michael Stapelberg
ed0d6acebd free(socket_path) to suppress leak sanitizer false-positive with -O2
related to #4086 (triggered by our meson config)
related to #4087 (sanitizer cleanup tracking bug)
2020-05-18 17:08:53 +02:00
Orestis Floros
f233245a6c Merge pull request #4089 from stapelberg/xmacro
xmacro: declare in header files, instantiate instead of include
2020-05-18 09:54:51 +02:00
Orestis Floros
c06fd161f8 Merge pull request #4090 from stapelberg/any
build AnyEvent::I3 in build dir, not source dir
2020-05-18 00:30:15 +02:00
Michael Stapelberg
84397ceb54 build AnyEvent::I3 in build dir, not source dir
related to #4086
2020-05-17 17:27:03 +02:00
Michael Stapelberg
1b8ddd5fd1 xmacro: declare in header files, instantiate instead of include
This works better with meson, where .h files can be declared as being part of an
executable easily, but I couldn’t find a way to declare
e.g. include/atoms.xmacro as a dependency.

related to #4086
2020-05-17 16:38:43 +02:00
Ingo Bürk
08052ddeb9 Merge pull request #4084 from orestisfl/get_output_by_name_primary_active
get_output_by_name: guard output->primary with require_active
2020-05-15 10:02:58 +02:00
Orestis Floros
0fb56a92d0 get_output_by_name: guard output->primary with require_active
This is related to #4048 but might not fix it completely. Either way,
this should be the correct behaviour of the function.
2020-05-14 21:53:21 +02:00
Ingo Bürk
4d929003ea Merge pull request #4081 from orestisfl/i3bar-regression
i3bar mode: Fix regression: bar_id can be NULL
2020-05-14 08:34:48 +02:00
Orestis Floros
fb2677f5f4 cmd_bar: Fix regression with invalid modes
This is another regression from #4014: multiple arrows in a row mean
optional values. Re-introduce new states to force matching & proper
parser errors.
2020-05-14 00:40:09 +02:00
Orestis Floros
9eb2458b55 cmd_bar: Fix regression: bar_id can be NULL
Regression introduced by #4014
Fixes #4080
2020-05-14 00:39:25 +02:00
Orestis Floros
f63a4bef54 cmd_bar improvements (#4014)
- Split cmd_bar into 2 functions, improving errors and reducing strcmps
- Only update barconfig when something has changed
- Only update barconfig for the specific bar that has changed

Fixes #3958
2020-05-07 09:22:03 +02:00
Orestis Floros
142b3fa945 Merge pull request #4054 from orestisfl/randr-ewmh
randr_query_outputs: call ewmh_update_desktop_properties
2020-05-06 17:32:45 +02:00
Orestis Floros
0877e35439 Merge pull request #4055 from orestisfl/rofi
Mention rofi in default config file
2020-05-06 17:31:09 +02:00
Orestis Floros
e4629d678e Merge pull request #4057 from orestisfl/hacking-howto
Update first 1/3 of hacking-howto document
2020-05-06 17:30:58 +02:00
Orestis Floros
94b619e118 randr_query_outputs: call ewmh_update_desktop_properties
Fixes #4053
2020-05-06 17:26:49 +02:00
Orestis Floros
9a1c272900 Mention rofi in default config file
Fixes #2482
2020-05-06 17:25:52 +02:00
Orestis Floros
4b97027034 hacking-howto: Add warning 2020-05-06 17:25:28 +02:00
Orestis Floros
cdf5ccbed8 hacking-howto: Update 'data structures' section
- Includes updated bigpicture.png from dump-asy.pl script
- The X11 root window is not a container
- Adds some extra information

bigpicture.png is created by converting the .asy to an .eps with `asy
bigpicture .eps` and then using the following gs command:
gs -dSAFER -dBATCH -dNOPAUSE -dEPSCrop -r600 -sDEVICE=pngalpha -sOutputFile=bigpicture.png bigpicture.eps
2020-05-06 17:25:28 +02:00
Orestis Floros
c7b6edf810 hacking-howto: Update 'files' section
Instead of sorting alphanumerically, use a more opinionated order,
listing more "important" files towards the beginning.

Info in this section was a bit outdated. First of all, i3 contains many
more files that were not mentioned. Instead of trying to include
everything, I deleted some files with very obvious descriptions. We can
always re-add something if we want to add more details to it.
2020-05-06 17:25:28 +02:00
Orestis Floros
516363a86b hacking-howto: Mention "stacking" window managers 2020-05-06 17:25:28 +02:00
Orestis Floros
a0ca5ffe70 hacking-howto: Update git section
This still had some leftovers from the patch era. Since git and
specifically GitHub-like developing is much more mainstream now we don't
need to link introductions or even mention the idea of "patching".

The deleted "them" was referencing an old sentence referring to patches,
generated by the git cli. As emailing patches is not common at all for
GitHub repos, I removed the sentence altogether.

Also simplifies the 'branches' subsection a bit. Asking people to verify
their patch on master seems too much preliminary work and I doubt that
anyone does it anyway.
2020-05-06 17:25:28 +02:00
Orestis Floros
4f0a93c3d9 hacking-howto: Update 'build system' section
Mention new --disable flags
2020-05-06 17:25:27 +02:00
Orestis Floros
0963159368 hacking-howto: Normalize code highlighting 2020-05-06 17:25:14 +02:00
Orestis Floros
b8f3c5b284 Re-add v4.18.1 release notes (#4071)
Fixes travis builds on next (non-PR)

Closes #4040
2020-05-05 19:14:04 +02:00
Orestis Floros
6a37114af1 Makefile.am: Use BUILT_SOURCES for GENERATED headers (#4068)
The previous fix when using _DEPENDENCIES was wrong because that
dependency is only created for the final executable. However, the build
fails when building the object file. The manual explicitly mentions that
using _DEPENDENCIES is wrong for source files:
> In rare cases you may need to add other kinds of files such as linker
> scripts, but listing a source file in _DEPENDENCIES is wrong. If some
> source file needs to be built before all the components of a program
> are built, consider using the BUILT_SOURCES variable instead (see
> Sources).
https://www.gnu.org/software/automake/manual/automake.html#Linking

Instead, using BUILT_SOURCES works, as mentioned in the manual.
https://www.gnu.org/software/automake/manual/automake.html#Sources

I have also removed the dependencies from i3_SOURCES since AFAIK
dependencies to header files don't do anything. I have verified that
modifying the header correctly re-triggers the build for i3 &
i3-config-wizard.
> Header files listed in a _SOURCES definition will be included in the
> distribution but otherwise ignored. In case it isn’t obvious, you
> should not include the header file generated by configure in a
> _SOURCES variable; this file should not be distributed. Lex (.l) and
> Yacc (.y) files can also be listed; see Yacc and Lex.
https://www.gnu.org/software/automake/manual/automake.html#Program-Sources

An alternative instead of BUILT_SOURCES that should also work in our
case is found in this section:
https://www.gnu.org/software/automake/manual/automake.html#Built-Sources-Example
see "Recording Dependencies manually". The syntax would be:
    foo.$(OBJEXT): $(config_parser_SOURCES) $(command_parser_SOURCES)
The benefit of this over BUILT_SOURCES is that it will work for targets
other than 'all', 'check' and 'install'. However, since we don't really
have such targets we don't need to do this right now.

Tested extensively using this script:
    #!/bin/bash
    set -x

    autoreconf -fi
    while mkdir build && cd build && ../configure && make -j; do
        cd ..
        rm -rf build
    done

Fixes #3670
2020-05-05 18:13:19 +02:00
Konstantin Kharlamov
666906b517 Makefile.am: make sure i3-config-wizard depends on libi3.a (#4069)
i3-config-wizard uses libi3.a as part of its build process. When
parallel build is enabled, build of i3-config-wizard may start before
libi3.a finished building. Fix this by adding dependency on libi3.a

Fixes: #4020
2020-05-05 18:00:11 +02:00
Orestis Floros
2fb2ef60de travis: Dockerfile: Add build-essential (#4065)
Fixes the recent travis failures
2020-05-05 17:37:32 +02:00
Ingo Bürk
d7d4f0a95b Merge pull request #3969 from ghost/patch-1
clean up math calculating width of last tab
2020-05-01 09:47:25 +02:00
Ingo Bürk
b61a28f156 Merge pull request #4025 from xzfc/always-clear-parent-pixmap
x_draw_decoration: always clear parent pixmap when rendering the first child
2020-05-01 09:46:07 +02:00
Ingo Bürk
e58f104f1e Merge pull request #4051 from orestisfl/format-placeholders
placeholder_t: Make char*s const
2020-05-01 09:43:43 +02:00
Ingo Bürk
151281aaf1 Merge pull request #4050 from orestisfl/config-details-bug-template
Bug template: Add collapsible for config file
2020-05-01 09:40:46 +02:00
Orestis Floros
c6cf0d32b9 placeholder_t: Make char*s const
Similarly to https://github.com/i3/i3status/pull/412
2020-05-01 01:13:12 +02:00
Orestis Floros
5f9cbb12b8 Add RELEASE-NOTES for next release (#4046)
* Add RELEASE-NOTES template for next

The placeholder items are useful instead of having to find the •
character for every new release.

Closes #4040

* Remove leftover bugfix release notes from tree
2020-04-30 21:07:11 +02:00
Orestis Floros
c6b46e1e01 Bug template: Add collapsible for config file
As discussed in #4022
2020-04-30 20:31:26 +02:00
Orestis Floros
eae996c579 Merge pull request #4049 from stapelberg/have
Fix #ifndef statements: HAVE_ variables are all upper case
2020-04-30 18:34:23 +02:00
Michael Stapelberg
5ee7690af3 Fix #ifndef statements: HAVE_ variables are all upper case
The autoconf manual states:

   define HAVE_function (in all capitals) if it is available

https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Generic-Functions.html#Generic-Functions

Thanks to @sur5r for the report
2020-04-30 18:20:51 +02:00
Ingo Bürk
10646eb002 Merge pull request #4041 from orestisfl/floating_enable-bool
Only set FLOATING_AUTO_ON when floating_enable succeeds
2020-04-30 09:04:22 +02:00
Ingo Bürk
f1824fd10b Merge pull request #4043 from i3/orestisfl-patch-2
con.c: Reorder use after free
2020-04-30 09:03:43 +02:00
Orestis Floros
0c9c9fb35f con.c: Reorder use after free
This shows up in various static analysis tools. I doubt that it is dangerous in any way but the end result is the same.
2020-04-28 21:41:13 +02:00
Orestis Floros
9c2b8f8b31 Merge pull request #4028 from orestisfl/headers
Header file cleaning
2020-04-28 08:28:00 +02:00
Orestis Floros
5e2f13a28c Only set FLOATING_AUTO_ON when floating_enable succeeds
Fixes #4039

Crash with docking clients where the floating field is set even though
floating_enable refuses to make them floating.

See issue for example with logs.
2020-04-27 13:43:53 +02:00
Ingo Bürk
4d55bba7f8 Merge pull request #4032 from stapelberg/release-sh
release.sh fixes from last release
2020-04-22 11:07:17 +02:00
Michael Stapelberg
8f0b92cae2 release.sh: update versions 2020-04-22 09:33:11 +02:00
Michael Stapelberg
c4ffc0f5e1 release.sh: docker build: use --no-cache
This avoids issues with stale caches. We rather don’t use caching at all:
release.sh is only run once per release.
2020-04-22 09:32:38 +02:00
Michael Stapelberg
f5ab2c919f release.sh: use diff --color
colordiff is no longer necessary, and not installed on many systems.
2020-04-22 09:32:22 +02:00
Michael Stapelberg
f9ed0db694 Update debian/changelog 2020-04-22 09:24:59 +02:00
Michael Stapelberg
dae37a902b Merge branch 'release-4.18.1' 2020-04-22 09:21:15 +02:00
Michael Stapelberg
1e5a022acb Merge branch 'master' into next 2020-04-22 09:21:15 +02:00
Michael Stapelberg
fe3d0b6752 Set non-git version to 4.18.1-non-git. 2020-04-22 09:21:15 +02:00
Michael Stapelberg
10eef6c12d release i3 4.18.1 2020-04-22 09:21:08 +02:00
Heman Gandhi
45468a36f0 Move parent nodes in scratchpad correctly (#3793)
* Move parent nodes in scratchpad across workspaces

Co-Authored-By: Orestis <orestisflo@gmail.com>
2020-04-22 08:57:00 +02:00
Orestis Floros
81671d454e Call cont_child() more liberally (#3996)
Following the reproduction instructions from
https://github.com/i3/i3/issues/3242#issuecomment-436175346

For me, #3242 happened when the following sequence executed:
1. Fullscreening window correctly calls `stop_child()` in
6e24e2ad6f/i3bar/src/xcb.c (L685)
2. Xrandr change, `reconfig_windows()` is called and `output->visible` is
set to `true` in this line:
6e24e2ad6f/i3bar/src/xcb.c (L1791)
3. When the window's fullscreen is disabled,
`handle_visibility_notify()` returns in this line:
6e24e2ad6f/i3bar/src/xcb.c (L677)
because previously `output->visible` was set to `true`

To fix this, I call `cont_child()` more leniently since it is a no-op
when the child is not stopped.

Fixes #3242
Closes #3761
2020-04-22 08:55:41 +02:00
Orestis Floros
ae00468dca Fix load_layout crash when floating node doesn't have CT_FLOATING_CON parent
Fixes #3901
2020-04-22 08:54:55 +02:00
Orestis Floros
d614f26906 Fix SEGFAULT when i3bar receives invalid input
Fixes #3844
2020-04-22 08:54:51 +02:00
Orestis Floros
de0bca6389 Revert "floating_reposition: avoid extra tree_render"
This reverts commit 204eefc679.

workspace_show does not call tree_render
2020-04-22 08:54:40 +02:00
Orestis Floros
fa9e6c2735 Call tree_render if floating move changes workspace
This fixes a bug where moving a floating container with
cmd_move_direction displays a "broken" state if the container crosses
workspace boundaries.
2020-04-22 08:54:36 +02:00
Orestis Floros
20a06462bc Update EWMH properties on workspace move
Closes #3965
Fixes #4001
2020-04-22 08:54:31 +02:00
Orestis Floros
50d2b44325 cmd_focus_sibling: Fix crash on workspace level
Fixes #3997
2020-04-22 08:53:52 +02:00
Orestis Floros
38f28186ec Remove some includes from all.h
Also removes duplicates from other headers

All used std* imports are included once in all.h for easy use

- getopt: Only used in main.c and inject_randr1.5.c
- glob: Not used in i3, only in i3bar & libi3
- inttypes: Only used in util.c
- locale: A bit specific for all.h
- math: Slow according to #4022
- unistd: I feel it's good to explicitly include per file that needs it
- yajl: Specific to yajl_utils.h and ipc.h

Related to #4022

Timing before:

```
Analyzing build trace from ...
**** Time summary:
Compilation (81 times):
  Parsing (frontend):           51.3 s
  Codegen & opts (backend):      7.7 s

**** Files that took longest to parse (compiler frontend):
  1254 ms: build/src/i3-commands.o
   972 ms: build/src/i3-resize.o
   945 ms: build/src/i3-con.o
   921 ms: build/src/i3-scratchpad.o
   907 ms: build/src/i3-main.o
   904 ms: build/src/i3-handlers.o
   904 ms: build/src/i3-config_directives.o
   893 ms: build/src/i3-restore_layout.o
   875 ms: build/src/i3-x.o
   854 ms: build/src/i3-ipc.o

**** Files that took longest to codegen (compiler backend):
   863 ms: build/src/i3-commands.o
   471 ms: build/i3bar/src/i3bar-xcb.o
   377 ms: build/src/i3-con.o
   360 ms: build/src/i3-ipc.o
   306 ms: build/src/i3-x.o
   290 ms: build/src/i3-main.o
   238 ms: build/src/i3-config_parser.o
   237 ms: build/src/i3-handlers.o
   220 ms: build/i3-config-wizard/i3_config_wizard-main.o
   214 ms: build/src/i3-bindings.o

**** Functions that took longest to compile:
   209 ms: main (../../i3/src/main.c)
    95 ms: manage_window (../../i3/src/manage.c)
    57 ms: reconfig_windows (../../i3/i3bar/src/xcb.c)
    55 ms: x_draw_decoration (../../i3/src/x.c)
    49 ms: x_push_node (../../i3/src/x.c)
    48 ms: handle_client_message (../../i3/src/handlers.c)
    48 ms: dump_node (../../i3/src/ipc.c)
    47 ms: GENERATED_call (../../i3/src/config_parser.c)
    45 ms: config_string_cb (../../i3/i3bar/src/config.c)
    44 ms: GENERATED_call (../../i3/src/commands_parser.c)
    42 ms: floating_check_size (../../i3/src/floating.c)
    40 ms: con_swap (../../i3/src/con.c)
    40 ms: parse_config (../../i3/src/config_parser.c)
    39 ms: main (../../i3/i3-nagbar/main.c)
    39 ms: cmd_rename_workspace (../../i3/src/commands.c)
    38 ms: window_update_normal_hints (../../i3/src/window.c)
    38 ms: cmd_swap (../../i3/src/commands.c)
    37 ms: dump_bar_config (../../i3/src/ipc.c)
    36 ms: translate_keysyms (../../i3/src/bindings.c)
    35 ms: tree_close_internal (../../i3/src/tree.c)
    34 ms: match_matches_window (../../i3/src/match.c)
    34 ms: floating_enable (../../i3/src/floating.c)
    34 ms: json_string (../../i3/src/load_layout.c)
    33 ms: x_push_changes (../../i3/src/x.c)
    33 ms: main (../../i3/i3-config-wizard/main.c)
    31 ms: free_configuration (../../i3/src/config.c)
    30 ms: parse_file (../../i3/src/config_parser.c)
    28 ms: load_font (../../i3/libi3/font.c)
    28 ms: handle_configure_request (../../i3/src/handlers.c)
    28 ms: parse_command (../../i3/src/commands_parser.c)

**** Function sets that took longest to compile / optimize:

*** Expensive headers:
29287 ms: ../../i3/include/libi3.h (included 78 times, avg 375 ms), included via:
  i3-resize.o all.h data.h  (576 ms)
  a-g_utf8_make_valid.o  (491 ms)
  a-dpi.o  (491 ms)
  a-get_colorpixel.o  (483 ms)
  a-is_debug_build.o  (478 ms)
  a-strndup.o  (478 ms)
  ...

29221 ms: ../../i3/include/all.h (included 39 times, avg 749 ms), included via:
  i3-resize.o  (946 ms)
  i3-scratchpad.o  (895 ms)
  i3-restore_layout.o  (865 ms)
  i3-handlers.o  (839 ms)
  i3-drag.o  (830 ms)
  i3-config_directives.o  (793 ms)
  ...

5195 ms: /usr/include/xcb/xcb.h (included 79 times, avg 65 ms), included via:
  i3-handlers.o all.h  (113 ms)
  i3-restore_layout.o all.h  (108 ms)
  a-g_utf8_make_valid.o libi3.h  (108 ms)
  i3bar-xcb.o common.h  (105 ms)
  i3-scratchpad.o all.h  (95 ms)
  a-get_colorpixel.o libi3.h  (89 ms)
  ...

4100 ms: /usr/include/math.h (included 41 times, avg 100 ms), included via:
  i3-scratchpad.o all.h  (180 ms)
  i3-fake_outputs.o all.h  (138 ms)
  i3-regex.o all.h  (130 ms)
  i3-restore_layout.o all.h  (128 ms)
  i3-xcb.o all.h  (121 ms)
  i3-move.o all.h  (119 ms)
  ...

4046 ms: ../../i3/i3bar/include/common.h (included 9 times, avg 449 ms), included via:
  i3bar-main.o  (503 ms)
  i3bar-xcb.o  (501 ms)
  i3bar-workspaces.o  (472 ms)
  i3bar-parse_json_header.o  (446 ms)
  i3bar-child.o  (438 ms)
  i3bar-ipc.o  (434 ms)
  ...

2713 ms: ../../i3/include/i3.h (included 41 times, avg 66 ms), included via:
  i3-xcursor.o  (450 ms)
  i3-config_directives.o all.h ipc.h configuration.h  (87 ms)
  i3-config.o all.h ipc.h configuration.h  (71 ms)
  i3-manage.o all.h ipc.h configuration.h  (70 ms)
  i3-window.o all.h ipc.h configuration.h  (68 ms)
  i3-x.o all.h ipc.h configuration.h  (61 ms)
  ...

1492 ms: /usr/include/xcb/xkb.h (included 42 times, avg 35 ms), included via:
  i3-config_directives.o all.h ipc.h configuration.h i3.h  (50 ms)
  i3-config.o all.h ipc.h configuration.h i3.h  (45 ms)
  i3-window.o all.h ipc.h configuration.h i3.h  (43 ms)
  i3-x.o all.h ipc.h configuration.h i3.h  (42 ms)
  i3-manage.o all.h ipc.h configuration.h i3.h  (41 ms)
  i3-config_parser.o all.h ipc.h configuration.h i3.h  (38 ms)
  ...

1432 ms: /usr/include/stdlib.h (included 79 times, avg 18 ms), included via:
  i3-scratchpad.o all.h  (48 ms)
  i3-restore_layout.o all.h  (36 ms)
  i3-regex.o all.h  (32 ms)
  i3-key_press.o all.h  (28 ms)
  i3-commands.o all.h  (28 ms)
  i3-bindings.o all.h  (24 ms)
  ...

1349 ms: /usr/include/pthread.h (included 79 times, avg 17 ms), included via:
  i3bar-xcb.o common.h xcb.h  (33 ms)
  a-ucs2_conversion.o libi3.h xcb.h  (32 ms)
  i3-match.o all.h xcb.h  (27 ms)
  i3-scratchpad.o all.h xcb.h  (25 ms)
  a-g_utf8_make_valid.o libi3.h xcb.h  (25 ms)
  i3_config_wizard-main.o xcb.h  (24 ms)
  ...

1151 ms: /usr/include/X11/Xlib.h (included 45 times, avg 25 ms), included via:
  i3-output.o all.h data.h sn-launcher.h sn-common.h  (50 ms)
  i3-config_parser.o all.h data.h sn-launcher.h sn-common.h  (43 ms)
  i3-x.o all.h data.h sn-launcher.h sn-common.h  (34 ms)
  i3-config_directives.o all.h data.h sn-launcher.h sn-common.h  (32 ms)
  i3_config_wizard-main.o sn-launchee.h sn-common.h  (30 ms)
  i3-drag.o all.h data.h sn-launcher.h sn-common.h  (29 ms)
  ...
```

Timing after:

```
Analyzing build trace from ...
**** Time summary:
Compilation (81 times):
  Parsing (frontend):           47.6 s
  Codegen & opts (backend):      7.6 s

**** Files that took longest to parse (compiler frontend):
  1154 ms: build/src/i3-commands.o
   929 ms: build/src/i3-display_version.o
   852 ms: build/src/i3-bindings.o
   847 ms: build/src/i3-con.o
   806 ms: build/src/i3-ipc.o
   801 ms: build/src/i3-floating.o
   792 ms: build/src/i3-main.o
   792 ms: build/src/i3-drag.o
   792 ms: build/src/i3-window.o
   776 ms: build/src/i3-config_directives.o

**** Files that took longest to codegen (compiler backend):
   885 ms: build/src/i3-commands.o
   422 ms: build/i3bar/src/i3bar-xcb.o
   382 ms: build/src/i3-con.o
   348 ms: build/src/i3-x.o
   288 ms: build/src/i3-ipc.o
   268 ms: build/src/i3-handlers.o
   254 ms: build/src/i3-main.o
   251 ms: build/src/i3-floating.o
   249 ms: build/src/i3-config_parser.o
   194 ms: build/src/i3-randr.o

**** Functions that took longest to compile:
   186 ms: main (../../i3/src/main.c)
    95 ms: manage_window (../../i3/src/manage.c)
    65 ms: floating_check_size (../../i3/src/floating.c)
    63 ms: x_draw_decoration (../../i3/src/x.c)
    58 ms: handle_client_message (../../i3/src/handlers.c)
    55 ms: x_push_node (../../i3/src/x.c)
    54 ms: match_matches_window (../../i3/src/match.c)
    51 ms: parse_config (../../i3/src/config_parser.c)
    49 ms: dump_node (../../i3/src/ipc.c)
    47 ms: reconfig_windows (../../i3/i3bar/src/xcb.c)
    47 ms: config_string_cb (../../i3/i3bar/src/config.c)
    45 ms: GENERATED_call (../../i3/src/config_parser.c)
    45 ms: GENERATED_call (../../i3/src/commands_parser.c)
    43 ms: floating_enable (../../i3/src/floating.c)
    42 ms: handle_configure_request (../../i3/src/handlers.c)
    40 ms: con_swap (../../i3/src/con.c)
    36 ms: main (../../i3/i3-input/main.c)
    36 ms: main (../../i3/i3-msg/main.c)
    36 ms: main (../../i3/i3-nagbar/main.c)
    36 ms: cmd_move_con_to_workspace_number (../../i3/src/commands.c)
    35 ms: json_string (../../i3/src/load_layout.c)
    35 ms: tree_restore (../../i3/src/tree.c)
    35 ms: cmd_swap (../../i3/src/commands.c)
    34 ms: x_push_changes (../../i3/src/x.c)
    32 ms: main (../../i3/i3-config-wizard/main.c)
    32 ms: ewmh_setup_hints (../../i3/src/ewmh.c)
    31 ms: match_parse_property (../../i3/src/match.c)
    30 ms: cmd_mark (../../i3/src/commands.c)
    30 ms: translate_keysyms (../../i3/src/bindings.c)
    30 ms: window_update_normal_hints (../../i3/src/window.c)

**** Function sets that took longest to compile / optimize:

*** Expensive headers:
29596 ms: ../../i3/include/libi3.h (included 78 times, avg 379 ms), included via:
  a-get_config_path.o  (539 ms)
  i3_dump_log-main.o  (522 ms)
  i3_config_wizard-main.o  (501 ms)
  a-fake_configure_notify.o  (500 ms)
  a-root_atom_contents.o  (488 ms)
  i3-display_version.o all.h  (466 ms)
  ...

26054 ms: ../../i3/include/all.h (included 41 times, avg 635 ms), included via:
  i3-display_version.o  (901 ms)
  i3-drag.o  (775 ms)
  i3-ewmh.o  (703 ms)
  i3-startup.o  (693 ms)
  i3-commands.o  (687 ms)
  i3-xcb.o  (680 ms)
  ...

5345 ms: /usr/include/xcb/xcb.h (included 79 times, avg 67 ms), included via:
  i3-display_version.o all.h  (173 ms)
  i3_input-keysym2ucs.o keysym2ucs.h  (106 ms)
  i3-ewmh.o all.h  (106 ms)
  a-fake_configure_notify.o libi3.h  (103 ms)
  a-get_config_path.o libi3.h  (95 ms)
  i3bar-parse_json_header.o common.h  (93 ms)
  ...

4127 ms: ../../i3/i3bar/include/common.h (included 9 times, avg 458 ms), included via:
  i3bar-child.o  (524 ms)
  i3bar-mode.o  (486 ms)
  i3bar-outputs.o  (464 ms)
  i3bar-parse_json_header.o  (463 ms)
  i3bar-config.o  (457 ms)
  i3bar-ipc.o  (448 ms)
  ...

1542 ms: /usr/include/xcb/xkb.h (included 42 times, avg 36 ms), included via:
  i3-con.o all.h ipc.h configuration.h i3.h  (60 ms)
  i3-render.o all.h ipc.h configuration.h i3.h  (56 ms)
  i3-bindings.o all.h ipc.h configuration.h i3.h  (56 ms)
  i3-sighandler.o all.h ipc.h configuration.h i3.h  (48 ms)
  i3-xcb.o all.h ipc.h configuration.h i3.h  (47 ms)
  i3-resize.o all.h ipc.h configuration.h i3.h  (39 ms)
  ...

1456 ms: /usr/include/stdlib.h (included 79 times, avg 18 ms), included via:
  i3-drag.o all.h  (60 ms)
  i3-display_version.o all.h  (55 ms)
  i3-fake_outputs.o all.h  (39 ms)
  i3-config_directives.o all.h  (33 ms)
  i3-xcursor.o all.h  (30 ms)
  i3bar-mode.o common.h libi3.h pango.h pango-attributes.h pango-font.h pango-coverage.h glib-object.h gbinding.h glib.h gasyncqueue.h gthread.h gutils.h  (29 ms)
  ...

1136 ms: /usr/include/X11/Xlib.h (included 44 times, avg 25 ms), included via:
  i3-con.o all.h data.h sn-launcher.h sn-common.h  (35 ms)
  i3-resize.o all.h data.h sn-launcher.h sn-common.h  (34 ms)
  i3-util.o all.h data.h sn-launcher.h sn-common.h  (33 ms)
  i3-assignments.o all.h data.h sn-launcher.h sn-common.h  (33 ms)
  i3-sighandler.o all.h data.h sn-launcher.h sn-common.h  (31 ms)
  i3-xcb.o all.h data.h sn-launcher.h sn-common.h  (31 ms)
  ...

808 ms: /usr/include/stdio.h (included 79 times, avg 10 ms), included via:
  i3-drag.o all.h  (19 ms)
  i3-fake_outputs.o all.h  (18 ms)
  a-font.o libi3.h  (16 ms)
  i3bar-child.o common.h libi3.h  (15 ms)
  a-safewrappers.o libi3.h  (15 ms)
  a-ipc_send_message.o libi3.h  (13 ms)
  ...

770 ms: /usr/include/xcb/randr.h (included 42 times, avg 18 ms), included via:
  i3-click.o all.h data.h  (29 ms)
  i3-commands.o all.h data.h  (27 ms)
  i3-assignments.o all.h data.h  (25 ms)
  i3-xcb.o all.h data.h  (21 ms)
  i3-resize.o all.h data.h  (21 ms)
  i3-sighandler.o all.h data.h  (20 ms)
  ...

688 ms: /usr/include/math.h (included 6 times, avg 114 ms), included via:
  a-dpi.o  (145 ms)
  i3-render.o  (127 ms)
  i3-floating.o  (106 ms)
  a-root_atom_contents.o  (106 ms)
  i3-window.o  (102 ms)
  i3-bindings.o  (99 ms)
  ...
```
2020-04-20 05:54:17 +02:00
Orestis Floros
af7c4ae76b generate-command-parser: Add '#pragma once' 2020-04-20 04:25:45 +02:00
Orestis Floros
2954125324 nagbar: Remove i3-nagbar.h 2020-04-20 04:25:45 +02:00
Orestis Floros
0b62129224 Remove unused headers
With help from
https://github.com/include-what-you-use/include-what-you-use/
2020-04-20 04:25:06 +02:00
Orestis Floros
3c522d9f2f Sort includes in *.c files
Not enabling in .clang-format because it breaks headers files.

Used:
    IncludeCategories:
      - Regex:           '^<config'
        Priority:        0
      - Regex:           '^".*"'
        Priority:        1
      - Regex:           '^<(xcb|xkb|yajl|X11)'
        Priority:        3
      - Regex:           '.*'
        Priority:        2
2020-04-19 09:58:25 +02:00
Albert Safin
7419400a8d x_draw_decoration: always clear parent pixmap when rendering the first child
Previously, i3 used to clean the parent pixmap only if the first child
has a titlebar.

This worked well for case `V[a b]` when both `a` and `b` have titlebars
(clearing is required), or both haven't (clearing is not required).
However, in case if `a` has no titlebar, but `b` has, this could lead
to graphical glitches.

This commit rearranges the order of conditions to make sure that the
parent pixmap is cleared regardless of the border style of the first
child.
2020-04-18 04:21:16 +00:00
Ingo Bürk
0bce0d86bf Merge pull request #4018 from orestisfl/reorder-docks
Sort dock clients by class and instance
2020-04-15 08:36:10 +02:00
Orestis Floros
7df88f18eb Sort dock clients by class and instance
This is similar to #3820 but does not use qsort but an insertion sort in
con_attach.

Since each bar block automatically gets its own incremental bar id,
bards end up being sorted according to their definition order in the
config file.

For i3bar, the WM_CLASS is modified to include an instance name which
depends on the bar_id. This could be useful for other reason, e.g. users
targeting a specific bar instance.

Fixes #3491
2020-04-14 20:47:51 +02:00
Orestis Floros
4212fb6488 i3bar: Set WM_CLASS instance to bar_id 2020-04-14 20:46:49 +02:00
Orestis Floros
831a52de9a Move content for non-existing output containers (#3767)
Probably fixes various related issues:
Closes #2276
Closes #2459
Closes #2936
Closes #3766

Tested using
bindsym $mod+Shift+i exec xrandr --output DVI-D-0 --mode 1920x1080 --pos 0x0 --rotate normal --output DVI-I-1 --off, restart

The core issue here is that the JSON read during a restart might contain
invalid outputs when the new process is done reading it.
2020-04-12 13:52:05 +02:00
Orestis Floros
ae757c6848 Extend tiling/floating criteria with optional auto/user values (#4006)
The default `tiling` and `floating` behavior is preserved and matches
both cases.

Adds a new handler to `remanage_window` on A_I3_FLOATING_WINDOW change.

Mainly in order to `run_assignments`, this makes `for_window [floating]`
directives to work for windows which where initially opened as tiling.
Now, when floating is enabled, `for_window` will trigger correctly. Same
applies to `for_window [tiling]`.

The obvious solution of `run_assignments` after
`floating_{enable,disable}` doesn't work because `run_assignments`
modifies the parser state in src/assignments.c:51.

Fixes #3588

Co-Authored-By: Michael Stapelberg <michael@stapelberg.de>
2020-04-12 13:49:08 +02:00
Michael Stapelberg
e7191af8b3 pod2html: render without stylesheet by default (#4016)
fixes #3956
2020-04-12 11:07:43 +02:00
Ingo Bürk
46e940efba Merge pull request #4013 from orestisfl/i3-dmenu-desktop-symlinks
i3-dmenu-desktop: Support symlinks
2020-04-12 09:15:40 +02:00
Ingo Bürk
adbef0c7e7 Merge pull request #4015 from orestisfl/layout-restore-crash-floating
Fix load_layout crash when floating node doesn't have CT_FLOATING_CON parent
2020-04-12 09:12:16 +02:00
Orestis Floros
a87e8c8d5b Fix load_layout crash when floating node doesn't have CT_FLOATING_CON parent
Fixes #3901
2020-04-12 00:48:01 +02:00
Orestis Floros
3a672bc930 i3-dmenu-desktop: Support symlinks
follow_fast is passed to find() in order to support this. Since we check
ourselves for duplicates, the fast option can be used.

Fixes #3973
2020-04-11 22:57:29 +02:00
Ingo Bürk
62279aba45 Merge pull request #4005 from orestisfl/route_click_clutter
route_click readability improvements
2020-04-11 19:51:00 +02:00
Ingo Bürk
f4b1da7f23 Merge pull request #4011 from orestisfl/floating_reposition-needs_tree_render
Call tree_render if floating move changes workspace
2020-04-11 19:50:14 +02:00
Ingo Bürk
93bb2022bb Merge pull request #4012 from orestisfl/floating_maybe_reassign_ws_focus
floating_maybe_reassign_ws: only re-focus if previously focused
2020-04-11 19:49:53 +02:00
Ingo Bürk
e47d5f6a3e Merge pull request #4008 from orestisfl/limit-run_command-LOG
Limit log length with IPC commands
2020-04-11 19:49:24 +02:00
Ingo Bürk
1e9fbd7186 Merge pull request #4010 from orestisfl/trailing-whitespace-log
Fix trailing whitespace in a DLOG
2020-04-11 19:49:05 +02:00
Orestis Floros
5eab604a10 floating_maybe_reassign_ws: only re-focus if previously focused
Fixes #3979
2020-04-11 11:10:51 +02:00
Orestis Floros
755d306df3 Revert "floating_reposition: avoid extra tree_render"
This reverts commit 204eefc679.

workspace_show does not call tree_render
2020-04-11 11:08:55 +02:00
Orestis Floros
bb8f2927ae Call tree_render if floating move changes workspace
This fixes a bug where moving a floating container with
cmd_move_direction displays a "broken" state if the container crosses
workspace boundaries.
2020-04-11 10:52:35 +02:00
Orestis Floros
e4cfb80a05 Fix trailing whitespace in a DLOG 2020-04-11 10:10:44 +02:00
Orestis Floros
964456b628 Limit log length with IPC commands
Fixes #3525
2020-04-10 16:59:46 +02:00
Orestis Floros
57a37f8af4 run_command: Update outdated docstring 2020-04-10 16:41:36 +02:00
Heman Gandhi
b247896a75 Move parent nodes in scratchpad correctly (#3793)
* Move parent nodes in scratchpad across workspaces

Co-Authored-By: Orestis <orestisflo@gmail.com>
2020-04-10 16:27:40 +02:00
Ingo Bürk
e2b2a28625 Merge pull request #4004 from orestisfl/i3bar-segfault
Fix SEGFAULT when i3bar receives invalid input
2020-04-10 14:00:51 +02:00
Ingo Bürk
312d3dfbd3 Merge pull request #4003 from orestisfl/update_desktop_properties_on_move
Update EWMH properties on workspace move
2020-04-10 14:00:26 +02:00
Ingo Bürk
1e6b510497 Merge pull request #4002 from orestisfl/DLOG_CHILD
i3bar: Add a macro to log child info
2020-04-10 13:59:55 +02:00
Michael Stapelberg
960df0dbfc Makefile: add bear target for using clangd/ccls language servers (#3953)
After installing clangd and/or ccls (Emacs eglot defaults to ccls),
run e.g. make bear -j32 and restart your editor (or just its language server).
2020-04-10 12:26:03 +02:00
Orestis Floros
58d383b1a0 route_click: Remove condition that is always true
For reference:
typedef enum { CLICK_BORDER = 0,
               CLICK_DECORATION = 1,
               CLICK_INSIDE = 2 } click_destination_t;
2020-04-10 12:24:18 +02:00
Orestis Floros
07c7384272 route_click: Add some const bools for readability 2020-04-10 12:22:24 +02:00
Orestis Floros
b401cc994b Merge pull request #3954 from xzfc/floating-tiling-resize
Make floating-tiling resize code consistent with plain tiling resize
2020-04-10 12:17:26 +02:00
Orestis Floros
59108ec299 Merge pull request #3816 from sandsmark/martin/empty-matches
Match empty window properties (e. g. no title set) #3308
2020-04-10 11:44:46 +02:00
Orestis Floros
91ec14f2bc Fix SEGFAULT when i3bar receives invalid input
Fixes #3844
2020-04-10 11:38:19 +02:00
Orestis Floros
ed67eaca2c Update EWMH properties on workspace move
Closes #3965
Fixes #4001
2020-04-10 04:40:11 +02:00
Orestis Floros
c46fdc8363 Merge pull request #3995 from xzfc/refactor-property-handlers
Refactor property handlers
2020-04-10 03:58:12 +02:00
Orestis Floros
40697a233c i3bar: Add a macro to log child info
Mentioned in #3242
2020-04-10 03:22:34 +02:00
Ingo Bürk
c611b9e0e0 Merge pull request #4000 from orestisfl/revert-3983-resize-behind-fullscreen
Correctly handle mouse resize in fullscreen containers
2020-04-09 16:41:43 +02:00
Orestis Floros
6fa2cd32a0 handle_button_press and route_click do not need to return int 2020-04-09 16:16:30 +02:00
Orestis Floros
93e96f4e6b Do not propagate $mod+right click to clients 2020-04-09 16:08:41 +02:00
Orestis Floros
b590ca076c Avoid resizing fullscreen container with non-fullscreen
Another option is to modify resize_find_tiling_participants but this
would also affect resizing of tiling containers in scripts, so I chose
to make this change specific to resizing with the mouse.

Follow-up after #3983
Fixes #3980
2020-04-09 15:49:09 +02:00
Orestis Floros
4922b245c1 Revert "Avoid resizing fullscreen container"
This reverts commit 1a2882d740.

As mentioned in
https://github.com/i3/i3/issues/3980#issuecomment-611515497, this
disables resizing children of fullscreen containers.
2020-04-09 15:11:46 +02:00
Ingo Bürk
26cbca3d27 Merge pull request #3999 from orestisfl/cmd_focus_sibling_workspace_crash
cmd_focus_sibling: Fix crash on workspace level
2020-04-09 11:47:32 +02:00
Orestis Floros
4b4f1f604f cmd_focus_sibling: Fix crash on workspace level
Fixes #3997
2020-04-09 11:29:14 +02:00
Orestis Floros
016d4a3f45 Call cont_child() more liberally (#3996)
Following the reproduction instructions from
https://github.com/i3/i3/issues/3242#issuecomment-436175346

For me, #3242 happened when the following sequence executed:
1. Fullscreening window correctly calls `stop_child()` in
6e24e2ad6f/i3bar/src/xcb.c (L685)
2. Xrandr change, `reconfig_windows()` is called and `output->visible` is
set to `true` in this line:
6e24e2ad6f/i3bar/src/xcb.c (L1791)
3. When the window's fullscreen is disabled,
`handle_visibility_notify()` returns in this line:
6e24e2ad6f/i3bar/src/xcb.c (L677)
because previously `output->visible` was set to `true`

To fix this, I call `cont_child()` more leniently since it is a no-op
when the child is not stopped.

Fixes #3242
Closes #3761
2020-04-09 10:43:48 +02:00
Albert Safin
d9d366a656 handlers.c: cb_property_handler_t: take Con instead of xcb_window_t
Since every handler calls con_by_window_id() and checks for NULL, it is
better to move this call into property_notify().
2020-04-08 08:37:40 +00:00
Albert Safin
e03fdef3e5 handlers.c: property_notify(): DLOG and return in case of an error 2020-04-08 08:37:40 +00:00
Albert Safin
5716ff541f handlers.c: remove redundant property fetching
Some property handlers trying to fetch property again if `prop == NULL`.
This is redundant since these properties are either fetched by
property_notify() just before or deleted.
2020-04-08 08:37:40 +00:00
Albert Safin
148ff54f18 handlers.c: remove unused arguments from cb_property_handler_t
Also, use `conn` global variable instead of passing it as an argument.
2020-04-08 08:02:17 +00:00
Orestis Floros
6e24e2ad6f Merge pull request #3985 from orestisfl/userguide-button6-7
userguide: Add button{6,7}
2020-04-07 20:20:00 +02:00
Orestis Floros
f3762cd041 userguide: Add button{6,7}
Related to #3984
2020-04-07 20:10:29 +02:00
Ingo Bürk
47732a4d9b Merge pull request #3994 from stapelberg/lintian
check-spelling: update to new Lintian::Profile API
2020-04-07 17:47:46 +02:00
Michael Stapelberg
72a6ad2013 check-spelling: update to new Lintian::Profile API
This changed between Lintian 2.62.0 and 2.64.0.
2020-04-07 17:41:56 +02:00
Ingo Bürk
cf505eaea8 Merge pull request #3983 from orestisfl/resize-behind-fullscreen
Avoid resizing fullscreen container
2020-03-31 09:52:46 +02:00
Orestis Floros
1a2882d740 Avoid resizing fullscreen container
Fixes #3980
2020-03-31 08:52:53 +02:00
Ingo Bürk
164336099d Merge pull request #3970 from ianyfan/ipc
ipc: always include marks property in TREE reply
2020-03-09 13:01:11 +01:00
Ian Fan
d02cda4241 ipc: always include marks property in TREE reply 2020-03-07 11:12:47 +00:00
6144
1d422dfc3a clean up math calculating width of last tab. 2020-03-07 09:05:41 +01:00
Ingo Bürk
cae3b294ad Merge pull request #3964 from ammgws/_PATH_BSHELL
Use _PATH_BSHELL in nagbar script as well
2020-03-01 08:28:28 +01:00
Jason Nader
9a3318b622 Fix error message 2020-03-01 13:25:42 +09:00
Jason Nader
191c394db8 Use _PATH_BSHELL in nagbar script as well 2020-03-01 12:46:30 +09:00
Ingo Bürk
d2acdcc69f Merge pull request #3960 from ammgws/patch-2
Remove comment referencing old source code
2020-03-01 01:29:30 +01:00
Ingo Bürk
daa2ea0d05 Merge pull request #3961 from ammgws/patch-1
i3-nagbar: Use _PATH_BSHELL
2020-03-01 01:28:57 +01:00
Jason
5024a13b8b Remove comment referencing old source code
Behaviour was changed in f691a55923
2020-03-01 05:03:41 +09:00
Jason
a516bdbb92 Use _PATH_BSHELL
Possibly overlooked in f691a55923850a4d315450925fc98733d07b69c9?
2020-03-01 04:53:35 +09:00
xzfc
47be36410c Assume xcb_cursor_context_new never fails (#3955)
According to libxcb-cursor code, the only condition in which
xcb_cursor_context_new() returns a non-zero result is a memory
allocation failure[1].  Thus, it is safe to assume that
xcursor_supported is always true, and remove dead code.

[1]: https://gitlab.freedesktop.org/xorg/lib/libxcb-cursor/blob/0.1.3/cursor/cursor.c#L131-132
2020-02-24 08:48:58 +01:00
Albert Safin
d36829d6e2 Make floating-tiling resize code consistent with plain tiling resize
Now dragging an inner border of a floating split triggers a tiling
resize (as expected) instead of a floating resize.
2020-02-22 23:35:55 +00:00
Michael Stapelberg
0ba325c5f3 Makefile.am: respect configure --program-suffix (#3944)
related to #3838
2020-02-22 13:47:49 +01:00
Joseph
967ec2e0ea Fix test case 180-fd-leaks when running on Fedora (#3911) 2020-02-22 10:09:11 +01:00
Orestis Floros
a376d1e52f Merge pull request #3950 from xzfc/small-fixes
Small fixes
2020-02-21 19:01:40 +01:00
Ingo Bürk
c5d50ac5fd Merge pull request #3951 from txtor/next
typo
2020-02-21 10:59:35 +01:00
Francesc Hervada-Sala
80f9bb6dbe typo 2020-02-21 10:53:02 +01:00
Albert Safin
b98b055459 i3 --moreversion: erase the line before writing over
The trailing part of the line (`abort…)`) has often been appearing in
bug reports.
2020-02-21 02:07:23 +00:00
Albert Safin
83c7aff089 Limit workspace numbers within 0..INT32_MAX
Before this commit, large workspace numbers treated oddly:

   $ i3-msg 'rename workspace to 1234567890'
   # displayed in i3bar as `0`

   $ i3-msg 'rename workspace to 4294967200'
   $ i3-msg -t get_workspaces | jq '.[]|select(.focused).num'
   -96 # int32_t overflow

   $ i3-msg 'rename workspace to 99999999999999999999'
   $ i3-msg -t get_workspaces | jq '.[]|select(.focused).num'
   -1 # treated as unnumbered

This commit puts a consistent limit on workspace numbers.  Now
workspaces with numbers beyond INT32_MAX are treated as unnumbered.
2020-02-21 02:07:04 +00:00
Albert Safin
d3976fee8c Code style: fix misaligned and trailing whitespaces 2020-02-21 02:06:48 +00:00
Orestis Floros
854885ea9d Merge pull request #3949 from xzfc/overlap
Sanitize window dimensions and handle decoration overlap
2020-02-19 11:41:58 +01:00
Albert Safin
670c23600f Decoration click/mouse move: iterate children in reverse order
In the case of decoration overlap, we should handle the one that is
drawn on top, i.e., the last one.
2020-02-19 11:33:49 +01:00
Albert Safin
e6ca7ca06f Sanitize con and window rect dimensions
Make sure they're neither zero (prohibited by X11) nor overflown during
subtraction.
2020-02-19 11:33:49 +01:00
xzfc
1f0c628cde clang-format: bring back ForeachMacros (#3948)
* clang-format: bring back ForeachMacros

ForeachMacros was disabled in 4211274fcd
due to the breakage of include/queue.h. The currently used version,
clang-format-6.0 doesn't break it.

* Add curly braces

Co-authored-by: Orestis Floros <orestisflo@gmail.com>
2020-02-19 11:31:09 +01:00
Ingo Bürk
e3f120c0b6 Merge pull request #3946 from phy1729/i3bar_command-exec
Prepend "exec " to default i3bar_command
2020-02-18 09:16:27 +01:00
Ingo Bürk
13ca970bfe Merge pull request #3945 from stapelberg/deps
Makefile.am: i3-config-wizard: add dependency on config parser
2020-02-18 09:16:06 +01:00
Michael Stapelberg
12095103fa Makefile.am: i3-config-wizard: add dependency on config parser
fixes #3670
2020-02-17 21:49:47 +01:00
Michael Stapelberg
30e886b031 debian: update changelog 2020-02-17 18:31:40 +01:00
Michael Stapelberg
b2c25cec54 Update debian/changelog 2020-02-17 18:27:46 +01:00
Michael Stapelberg
0dd60756af Merge branch 'release-4.18' 2020-02-17 18:27:46 +01:00
Michael Stapelberg
53718d354b Merge branch 'next' into master 2020-02-17 18:27:46 +01:00
Michael Stapelberg
949aff3016 Set non-git version to 4.18-non-git. 2020-02-17 18:27:46 +01:00
Michael Stapelberg
9929949d26 release i3 4.18 2020-02-17 18:27:38 +01:00
Ingo Bürk
2914c7fb43 Merge pull request #3942 from stapelberg/iconv
configure.ac: test for iconv_open with #include <iconv.h>
2020-02-16 18:50:54 +01:00
Michael Stapelberg
91b00c5605 configure.ac: test for iconv_open with #include <iconv.h>
The previously used AC_SEARCH_LIBS uses AC_LANG_CALL, which is discouraged
because it intentionally violates the C type system: it has no way of specifying
function parameters, so it does not include the required headers to suppress
type warnings:
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Generating-Sources.html

The new code does what AC_SEARCH_LIBS does, but uses AC_LANG_PROGRAM instead of
AC_LANG_CALL. It explicitly includes iconv.h and calls iconv_open with the
correct number and type of arguments.

This fixes compilation on systems where libiconv’s iconv.h is discovered first,
but glibc also provides iconv. Previously, this would result in configure
discovering glibc’s iconv, and make failing to compile because -liconv wasn’t
specified, but iconv.h pulled in libiconv.
2020-02-16 18:38:44 +01:00
Michael Stapelberg
f517b5aa57 Merge pull request #3918 from orestisfl/fno-common
Fix fno-common problems with gcc10
2020-02-15 12:25:58 +01:00
Ingo Bürk
c3bf7288b3 Merge pull request #3928 from Iskustvo/improve_window_properties_documentation
Improved documentation for "window_properties" field in GET_TREE reply.
2020-02-11 09:06:55 +01:00
Iskustvo
36a8bc6463 Improved documentation for "window_properties" field in GET_TREE reply. 2020-02-08 11:41:48 +01:00
Ingo Bürk
4338c3ea55 Merge pull request #3931 from acheronfail/chore/add-docs-for-window-type
docs: add window_type to ipc documentation
2020-02-07 10:44:42 +01:00
acheronfail
a1736f4df6 docs: add window_type to ipc documentation 2020-02-07 19:50:23 +11:00
Orestis Floros
b9b0774733 Merge pull request #3926 from stapelberg/next
configure: deal with git worktree checkouts, where .git is a file
2020-02-02 13:12:20 +01:00
Michael Stapelberg
2edae71570 configure: deal with git worktree checkouts, where .git is a file
fixes #3013
2020-02-02 11:17:02 +01:00
Orestis Floros
cb1012e608 Travis: Default to -fno-common
See #3914
2020-02-01 17:41:19 +01:00
Orestis Floros
2eac53fada atoms: Properly declare as global variables
See #3914
2020-02-01 17:34:01 +01:00
Orestis Floros
d14e59b3a7 i3bar: Make header declarations extern
See #3914
2020-02-01 17:33:53 +01:00
Orestis Floros
e9f011397a libi3: Make visual_type extern
See #3914
2020-02-01 17:32:54 +01:00
Orestis Floros
d11e862919 Delete duplicate definition of ewmh_window
See #3914
2020-02-01 17:32:53 +01:00
Matthew Martin
a2cba79f9c Prepend "exec " to default i3bar_command
Avoids leaving around a useless shell process.
2020-01-30 21:02:50 -06:00
Ingo Bürk
fc01ece365 Merge pull request #3909 from orestisfl/bug-3903
Do not error on exec not matching a container
2020-01-18 17:42:17 +01:00
Orestis Floros
f76b11327f Do not error on exec not matching a container
See #3903, #3905
2020-01-18 11:09:14 +01:00
Ingo Bürk
110bdcbee5 Merge pull request #3905 from Airblader/bug-3903
Respect match criteria for exec command
2020-01-16 22:19:25 +01:00
Ingo Bürk
f002584509 Respect match criteria for exec command
We currently do not evaluate match criteria for the exec command
since generally executing the same command multiple times is
unlikely to make sense.

However, it does make sense when the match is empty and this should
prevent the command from running, which currently does not happen.

For consisteny we execute the command as many times as there are
matched criteria, but print a warning if it matches more than one
container.

fixes #3903
2020-01-16 22:07:37 +01:00
Ingo Bürk
b3faf9fca9 Merge pull request #3906 from orestisfl/exit_codes
Exit codes
2020-01-16 09:47:54 +01:00
Orestis Floros
0ed94fc788 Use EXIT_SUCCESS/FAILURE instead of 0/1 2020-01-16 09:27:05 +01:00
Orestis Floros
f7aee6b908 Exit with success on -h 2020-01-16 09:21:16 +01:00
Ingo Bürk
d21c3a09f4 Merge pull request #3898 from dvarrazzo/socket-dir-docs
Fixed location of the IPC socket in the docs
2020-01-09 12:47:39 +01:00
Daniele Varrazzo
ddb5075399 Fixed location of the IPC socket in the docs 2020-01-08 17:59:37 +00:00
Ingo Bürk
dab223cabc Merge pull request #3894 from Iskustvo/extend_GET_WORKSPACES_response
Extended GET_WORKSPACE response with workspace ID.
2020-01-08 09:21:50 +01:00
Iskustvo
5835bbc385 Added workspace ID in GET_WORKSPACES response. 2020-01-08 09:07:53 +01:00
Martin T. H. Sandsmark
afab4d6789 Allow matching on empty properties (class, title, etc.)
Fixes #3308
2019-12-25 15:42:47 +01:00
Michael Stapelberg
d341b91b0a Merge pull request #3824 from orestisfl/ac_replace_funcs
Use AC_REPLACE_FUNCS
2019-12-25 12:27:21 +01:00
Ingo Bürk
50cd151523 Merge pull request #3868 from ben4ever/patch-1
userguide: Add missing anchor
2019-12-04 13:25:52 +01:00
Benjamin Dopplinger
314509d7d4 userguide: Add missing anchor 2019-12-04 21:02:01 +11:00
Ingo Bürk
8fdc38d25f Merge pull request #3797 from acheronfail/feat/add-window-type-ipc
feat: add window_type to ipc response
2019-11-29 08:16:57 +01:00
Ingo Bürk
1679bcc89a Merge pull request #3871 from geshido/ipc-marks-in-get-tree-reply
added marks field to get_tree reply in ipc documentation
2019-11-28 11:36:54 +01:00
Yury Ignatev
7427d61f7f added marks field to get_tree reply in ipc documentation 2019-11-28 16:17:23 +07:00
Ingo Bürk
71b82fa3b8 Merge pull request #3872 from stapelberg/spelling
travis/check-spelling.pl: check_spelling moved to Lintian::Spelling
2019-11-28 08:55:46 +01:00
Michael Stapelberg
f01a75cee8 travis/check-spelling.pl: check_spelling moved to Lintian::Spelling 2019-11-28 08:51:26 +01:00
Ingo Bürk
9a3eb4fc71 Merge pull request #3841 from DamienCassou/fix-pango-markup-url
Documentation: fix links pointing to Pango markup
2019-10-22 07:56:41 +02:00
Damien Cassou
b8de4bccd2 Documentation: fix links pointing to Pango markup 2019-10-22 06:45:40 +02:00
Ingo Bürk
7330778223 Merge pull request #3840 from orestisfl/unused-parameters
Remove various unused parameters
2019-10-21 08:41:26 +02:00
Orestis Floros
17d0cd7034 Remove various unused parameters 2019-10-20 16:14:20 +03:00
Orestis
428cb94e29 Merge pull request #3839 from orestisfl/remanage_window-crash
remanage_window: avoid crash when nc->window == NULL
2019-10-18 16:51:42 +03:00
Orestis Floros
812507c4a1 remanage_window: avoid crash when nc->window == NULL
Temporary solution until we find the root cause. Not that it is a bad
idea to check for NULL either way.

Related to #3731
2019-10-18 11:58:08 +03:00
Ingo Bürk
6011e245e9 Merge pull request #3835 from orestisfl/tree_flatten_crash
Fix crash with moving container that is to be flattened
2019-10-18 09:24:32 +02:00
Ingo Bürk
cb535a4267 Merge pull request #3837 from orestisfl/scratchpad-fullscreen
scratchpad_move: un-fullscreen correct container
2019-10-18 09:22:39 +02:00
Orestis Floros
95d4ce3ed6 scratchpad_move: un-fullscreen correct container
Fixes https://github.com/i3/i3/issues/2857#issuecomment-496264445
2019-10-17 18:14:21 +03:00
Ingo Bürk
879fd6c08b Merge pull request #3836 from orestisfl/userguide
userguide: Remove mention of config directives with 'command equivalents'
2019-10-17 12:06:46 +02:00
Orestis Floros
72765bbb94 userguide: Remove mention of config directives with 'command equivalents'
See #3657
2019-10-17 12:56:29 +03:00
Orestis
9138bb37f1 Merge pull request #3834 from Airblader/bug-3819
Reparent windows to their current position on unmanage
2019-10-16 10:42:35 +03:00
Ingo Bürk
9118ee6029 Merge pull request #3833 from orestisfl/move-to-position+scratchpad
Do not show scratchpad windows after 'move to position'
2019-10-16 09:06:05 +02:00
Orestis Floros
359d75cd3c Fix crash with moving container that is to be flattened
Same can happen with move_to_output_directed but it is not so easy to
write a test about it.

Fixes #3831
2019-10-16 01:32:05 +03:00
Ingo Bürk
1b3d8650a7 Reparent windows to their current position on unmanage
When unmanaging a window we need to reparent it back to the root
window. With this patch we do so at the current position of the
container such that we don't throw away the geometry position.

This fixes cases where clients withdraw a window and reparent it
later on, expecting to keep the same geometry (in particular dock
clients) but then end up on a wrong output.

fixes #3819
2019-10-15 22:32:48 +02:00
Orestis Floros
b48ff2c5ec Do not show scratchpad windows after 'move to position'
Fixes #3832
2019-10-15 18:40:59 +03:00
Ingo Bürk
cb9620c60a Merge pull request #3407 from orestisfl/tree_next
tree_next refactor & enhancements
2019-10-15 13:47:24 +02:00
Ingo Bürk
ebb8d89021 Merge pull request #3830 from orestisfl/i3bar-leak
Fix i3bar leak on handle_destroy_notify
2019-10-15 12:50:28 +02:00
Orestis Floros
33634fbacd Fix i3bar leak on handle_destroy_notify 2019-10-14 17:34:38 +03:00
Ingo Bürk
a638e0408e Merge pull request #3829 from orestisfl/move_to_mark_focus
_con_move_to_con: focus_next only if in different workspaces
2019-10-14 15:27:13 +02:00
Orestis Floros
2821270949 _con_move_to_con: focus_next only if in different workspaces 2019-10-14 15:38:44 +03:00
Orestis Floros
24a58d2952 Implement focus_wrapping workspace
I had a dilemma about the behaviour here:
1. Prohibit focus leaving the workspace in any case unless if
get_tree_next's initial argument is a workspace. This is what this
commit does (also i3-cycle).
2. Leave the workspace if no warp is possible (eg workspace with single
container or `focus right` with `V[a b c*]`).

Fixes #2180
2019-10-14 13:02:33 +03:00
Ingo Bürk
9c408396d9 Merge pull request #3828 from orestisfl/i3-nagbar
Minor i3-nagbar changes
2019-10-14 11:45:40 +02:00
Orestis Floros
ffde51e50f i3-nagbar: Fix small leak 2019-10-14 12:26:10 +03:00
Orestis Floros
a3f94783e5 i3-nagbar: get_window_position: Improve logging 2019-10-14 12:26:04 +03:00
Orestis Floros
b1723f0549 i3-nagbar: Don't use DLOG
debuglog() is empty and no option to enable it exists
2019-10-14 12:24:30 +03:00
Ingo Bürk
3127a94c0d Merge pull request #3827 from orestisfl/i3bar-leak
Fix small leak in i3bar's main
2019-10-14 09:54:32 +02:00
Orestis Floros
ee30c34b5c Fix small leak in i3bar's main
If -s is used, the socket_path returned by getenv is never freed.

Also some small rearrangements.
2019-10-14 03:54:48 +03:00
Orestis Floros
bbc4c99c72 Refactor tree_next
- Makes `tree_next` not recursive.
- Adds `focus next|prev [sibling]` command. See (1.) and (2.) in
https://github.com/i3/i3/issues/2587#issuecomment-378505551 (Issue also
requests move command, not implemented here).
- Directional focus command now supports command criteria.

Wrapping is not implemented inside a floating container. This was also
true before the refactor so I am not changing it here.
2019-10-14 03:31:24 +03:00
Orestis Floros
f402f45702 Introduce CMD_FOCUS_WARN_CHILDREN 2019-10-14 02:38:53 +03:00
Orestis Floros
1e8e4d3e7f Introduce direction / orientation / position conversion functions 2019-10-14 02:38:53 +03:00
Orestis Floros
e5c430e419 tree_move: Use direction_t 2019-10-14 02:31:11 +03:00
Orestis Floros
0cd7250f41 Add testcases/t/308-focus_wrapping.t
These tests pass with and without the following refactoring.
2019-10-14 02:30:06 +03:00
Orestis Floros
b0d6f44779 Use AC_REPLACE_FUNCS
strndup is removed from AC_CHECK_FUNCS since it will be provided if not
found.

Fixes #2610
2019-10-13 13:17:40 +03:00
Orestis Floros
70c850ac13 Remove memmem implementation
Not used after 3bd5e6e5c8
2019-10-13 13:10:06 +03:00
Ingo Bürk
5f54971425 Merge pull request #3821 from orestisfl/deterministic_tray_icon_order
reorder_trayclients_cmp: Correct comment
2019-10-11 18:43:38 +02:00
Orestis Floros
98d96c3a2c reorder_trayclients_cmp: Correct comment 2019-10-11 19:32:58 +03:00
Ingo Bürk
8088c357e4 Merge pull request #3820 from orestisfl/deterministic_tray_icon_order
Deterministic tray icon order
2019-10-11 17:37:42 +02:00
Orestis Floros
eda814755a Make tray icon order deterministic
Fixes #3573
2019-10-11 18:25:22 +03:00
Orestis Floros
d5a3b8af02 Introduce trayclient_and_output_from_window
Saves some code repetition
2019-10-11 16:12:48 +03:00
Orestis
0b4d4e799b Merge pull request #3817 from orestisfl/rect
Remove outdated comment from Rect
2019-10-09 16:12:40 +03:00
Orestis Floros
961f98eb15 Remove outdated comment from Rect
This has changed after #3787.

The packed attribute was added in
75aac5bc02 for _NET_WORKAREA. However,
eec80838ab removed _NET_WORKAREA support.
I did some quick greping for `memcpy.+Rect` and didn't find any similar
code that could theoretically lead to problems.
2019-10-09 16:08:18 +03:00
Ingo Bürk
736ac40b10 Merge pull request #3814 from orestisfl/net_active_fullscreen
handlers.c: new focus should not end up behind fullscreen
2019-10-09 13:25:38 +02:00
Orestis
5e1094e994 Merge pull request #3815 from xzfc/3694-baf-rename
When renaming a workspace, update the previous_workspace_name too
2019-10-09 12:38:48 +03:00
Orestis
ea216f88d8 Merge pull request #3559 from xzfc/3555-drag-threshold
Drag threshold
2019-10-09 12:38:30 +03:00
Albert Safin
7e4eb51d23 When renaming a workspace, update the previous_workspace_name too
Fixes #3694
2019-10-09 08:09:24 +00:00
Orestis Floros
6f82d21c39 handlers.c: new focus should not end up behind fullscreen
This was raised here:
https://www.reddit.com/r/i3wm/comments/df18aa/popup_during_fullscreen_not_behaving_the_way_i/

With this commit, _NET_ACTIVE_WINDOW requests are more similar to
focusing with cmd_focus.
2019-10-09 02:38:40 +03:00
Orestis Floros
34c217acc8 Introduce con_activate_unblock 2019-10-09 02:31:52 +03:00
Orestis
465447a96b Merge pull request #3812 from xzfc/move-to-parent
Fix "move con to parent" trick
2019-10-08 11:54:40 +03:00
Albert Safin
beb96ad18c Move container to marked workspace: refine corner case
This commit should fix "move con to parent" trick (see below) in the
case when con->parent->parent is a workspace.

The trick:

    mark _a, focus parent, focus parent, mark _b,
    [con_mark=_a] move window to mark _b, [con_mark=_a] focus

The trick got broken in commit 626af81232
in order to fix an i3 crash (#2003).  Reverting said commit fixes the
trick.  The crash is caused by the fact that empty workspace isn't
considered a split (checked in src/con.c:1324), so the moved window ends
up as a sibling of the target workspace, not as its child.
2019-10-07 18:15:03 +00:00
Ingo Bürk
ba0868e593 Merge pull request #3728 from cdlscpmv/next
Add setting for minimal width of workspace buttons
2019-10-06 00:22:44 +02:00
Albert Safin
371dc23101 Tiling resize drag: use threshold 2019-10-03 06:09:57 +00:00
Albert Safin
c6b56b09ab Floating move drag: use threshold 2019-10-03 06:09:57 +00:00
Albert Safin
551ec20941 drag_pointer(): add use_treshold parameter 2019-10-03 06:09:57 +00:00
Albert Safin
2795c51d4b drag_pointer(): drop unused parameter border 2019-10-03 06:05:34 +00:00
Albert Safin
454473ac6c Move drag_pointer() to its own source file
Move drag_pointer() and related definitions from floating.c to new file
drag_pointer.c since it's applicable not only to floating windows but
also to resizing of tiled windows.
2019-10-03 06:05:34 +00:00
Orestis
d22f0342b2 Merge pull request #3809 from xzfc/3606-floating-xterm
Fix regression: floating xterm created partially off screen
2019-10-02 10:52:40 +03:00
Albert Safin
67217822b8 do not try to center floating window on itself
Some apps including XTerm start with a WM_CLIENT_LEADER property
containing their own window ID.  Before this commit, i3 tried to center
such windows onto itself and did it wrong since
`leader->rect == {0,0,0,0}` at this moment.

The first affected commit is 128122e766,
however, before it such windows already was misplaced, but got sanitized
afterward [1].

[1]: 8a3ef3a81b/src/floating.c (L329-L335)

Fixes #3606
2019-10-02 04:00:05 +00:00
Orestis
94fdb92d7c Merge pull request #3799 from xzfc/3527-workspace-number
extract_workspace_names_from_bindings: handle optional flags
2019-09-28 08:41:27 +03:00
acheronfail
46cf9fb91b feat: add window_type to ipc response 2019-09-27 15:44:13 +10:00
Albert Safin
ff73ddeeee extract_workspace_names_from_bindings: handle optional flags
fixes #3527
2019-09-23 08:21:30 +00:00
Ingo Bürk
7db0d179a3 Merge pull request #3784 from Iskustvo/next
Added documentation for "fullscreen_mode" in GET_TREE reply.
2019-09-20 23:23:31 +02:00
Orestis
cfb74c01ff Merge pull request #3783 from erwinvaneijk/fix_lcov_version
fix lcov support
2019-09-03 11:52:20 +03:00
Ingo Bürk
0e73396d28 Merge pull request #3787 from orestisfl/rect
Remove packed attribute from Rect
2019-09-03 09:59:34 +02:00
Orestis Floros
a73510026f Remove packed attribute from Rect
Fixes #3785 -- the issue where the Travis build failed because of gcc's
-Werror=address-of-packed-member.

Adds an equality function to avoid relying on memcmp().
2019-09-03 10:43:36 +03:00
Iskustvo
148bdeefdc Added documentation for "fullscreen_mode" in GET_TREE reply. 2019-09-02 19:58:22 +02:00
Erwin J. van Eijk
1e4ffcafaa fix lcov support
Ubuntu 18.10 comes with lcov 1.13, which is now added.
2019-09-01 19:19:12 +02:00
Michael Stapelberg
39a65166c4 update debian/changelog 2019-08-30 23:46:42 +02:00
Michael Stapelberg
225ebb0d58 Merge branch 'release-4.17.1' 2019-08-30 23:06:59 +02:00
Michael Stapelberg
942a33d0ec Set non-git version to 4.17.1-non-git. 2019-08-30 23:06:59 +02:00
Michael Stapelberg
c0f987fd66 Update debian/changelog 2019-08-30 23:06:59 +02:00
Michael Stapelberg
2ec14630fd Merge branch 'master' into next 2019-08-30 23:06:59 +02:00
Michael Stapelberg
f0f3821ff0 release i3 4.17.1 2019-08-30 23:06:47 +02:00
Michael Stapelberg
e6662df114 default config: use workspace number, not just workspace
This is strictly better: if the configured name does not match the current name,
the correct workspace will still be used.

When creating a new workspace, the configured name is still used.
2019-08-30 18:06:11 +02:00
Michael Stapelberg
1059277f28 default config: mention loginctl lock-session alongside xss-lock 2019-08-30 18:05:58 +02:00
Michael Stapelberg
3d7b25a857 default config: add XF86AudioMicMute 2019-08-30 18:05:55 +02:00
Michael Stapelberg
fced643980 default config: immediately refresh i3status after volume changes 2019-08-30 18:05:52 +02:00
Ingo Bürk
c6b0c61e25 Merge pull request #3747 from stapelberg/default-config-numbers
default config: use workspace number, not just workspace
2019-08-28 08:58:44 +02:00
David Shen
482f9e0ba7 Unset _I3_RESTART_FD after restart (#3775)
Closes #3764
Closes #3765
2019-08-28 08:54:33 +02:00
David Shen
efe84764b0 Unset _I3_RESTART_FD after restart (#3775)
Closes #3764
Closes #3765
2019-08-28 08:54:10 +02:00
Orestis
7b33e06b9d Merge pull request #3776 from RedSoxFan/move-mark-scratchpad-hidden
cmd_move_to_mark: fix move to scratchpad hidden
2019-08-22 09:45:51 +03:00
Brian Ashworth
741e94ae4f cmd_move_to_mark: fix move to scratchpad hidden
This fixes the case where moving a container to a scratchpad hidden
container via a mark would cause the container to be tiling on the
__i3_scratch workspace. This still moves the container to the
__i3_scratch workspace, but properly adds it to the scratchpad so that
it becomes usable instead of requiring criteria to regain access to.
2019-08-21 19:58:49 -04:00
Ingo Bürk
a4b5deed73 Merge pull request #3771 from stapelberg/lock
default config: mention loginctl lock-session alongside xss-lock
2019-08-15 22:02:16 +02:00
Michael Stapelberg
61ae2f17df default config: mention loginctl lock-session alongside xss-lock 2019-08-15 21:16:12 +02:00
Ingo Bürk
81c90895ef Merge pull request #3770 from stapelberg/mic
default config: add XF86AudioMicMute
2019-08-15 21:12:02 +02:00
Michael Stapelberg
31fd13aa1b default config: add XF86AudioMicMute 2019-08-15 20:57:34 +02:00
Ingo Bürk
9e2f00e297 Merge pull request #3769 from stapelberg/refresh
default config: immediately refresh i3status after volume changes
2019-08-15 20:53:49 +02:00
Michael Stapelberg
98b50d7dd0 default config: immediately refresh i3status after volume changes 2019-08-15 20:33:33 +02:00
Ingo Bürk
ac9e55caa5 Merge pull request #3768 from orestisfl/get_first_output
get_first_output changes
2019-08-15 17:23:41 +02:00
Orestis Floros
14d2a4c7f6 Correctly select output when pointer query fails 2019-08-13 16:54:55 +03:00
Orestis Floros
fd7e51927d get_first_output: prefer primary output
Used in two cases:
- When the pointer location can't be found but some initial container
needs to be focused
- When moving disabled outputs
2019-08-13 16:44:45 +03:00
izzel
0845d7b264 Remanage window after property updates (like titles) (#3759) 2019-08-13 08:50:48 +02:00
Antoine
3b88e41dd8 move workspace to output: don’t create duplicatively numbered workspaces (#3746)
fixes #3745
2019-08-08 07:43:01 +02:00
Michael Stapelberg
840d9202d1 release.sh changes for v4.17 2019-08-03 15:29:04 +02:00
Michael Stapelberg
c36311f614 debian: update changelog 2019-08-03 15:22:06 +02:00
Michael Stapelberg
cddaa2c57b Update debian/changelog 2019-08-03 15:14:53 +02:00
Michael Stapelberg
f2b612d271 Merge branch 'release-4.17' 2019-08-03 15:14:52 +02:00
Michael Stapelberg
ea00565ad3 Merge branch 'next' into master 2019-08-03 15:14:52 +02:00
Michael Stapelberg
18f50893f6 Set non-git version to 4.17-non-git. 2019-08-03 15:14:52 +02:00
Michael Stapelberg
79c690248a release i3 4.17 2019-08-03 15:14:38 +02:00
Iskustvo
ac100e36d9 Updated the documentation for COMMAND reply. (#3754) 2019-08-02 14:56:48 -07:00
Ingo Bürk
8cc2743bd6 Merge pull request #3748 from stapelberg/default-config
default config: start xss-lock+i3lock, nm-applet, pactl (volume key)
2019-07-31 15:20:46 +02:00
Michael Stapelberg
72975d6764 default config: start xss-lock+i3lock, nm-applet, pactl (volume key)
This change will make things strictly better for new users (without an existing
configuration file) and has no effect on existing users.

The tools should be fairly uncontentious, I hope, especially as they only serve
as a starting point anyway: users can quickly delete what they don’t want, or
change it into what they prefer.

But having something is strictly better than having nothing :)

We make some space in the config file by removing the old paragraph about pixel
fonts, which seems rather outdated and irrelevant to me.
2019-07-31 15:06:27 +02:00
Michael Stapelberg
5bb7b73a4a restart: make reply an array, add forgotten test to git (#3750)
related to #3565
2019-07-29 13:21:34 -07:00
Michael Stapelberg
ecffbed45f default config: use workspace number, not just workspace
This is strictly better: if the configured name does not match the current name,
the correct workspace will still be used.

When creating a new workspace, the configured name is still used.
2019-07-28 08:58:39 -07:00
Michael Stapelberg
e4ecc6e4a1 Make restart IPC command send a reply once restart completed (!) (#3743)
This is achieved by retaining the IPC connection which is sending the restart
command across the restart.

This is the cleaner fix for https://github.com/i3/go-i3/issues/3

fixes #3565
2019-07-21 14:52:12 +02:00
Ingo Bürk
1eabe1b2b1 Merge pull request #3742 from stapelberg/docipc
docs/ipc: fix code block header/footer mismatches
2019-07-19 22:18:16 +02:00
Michael Stapelberg
1ac117bb51 docs/ipc: fix code block header/footer mismatches
This is required to get the document rendered with the asciidoctor
implementation of asciidoc.
2019-07-19 21:23:57 +02:00
Michael Stapelberg
865f807976 unflake t/291-swap.t (#3741) 2019-07-19 21:10:40 +02:00
Ingo Bürk
8b88b0cb3e Merge pull request #3740 from stapelberg/strace
strace: switch from deprecated -F to -fvy
2019-07-19 21:01:36 +02:00
Michael Stapelberg
48d3d17d47 strace: switch from deprecated -F to -fvy 2019-07-19 20:39:53 +02:00
Konst Mayer
94228fd902 Add setting for minimal width of workspace buttons 2019-06-25 13:10:01 +07:00
Ingo Bürk
ca82f95812 feat: added support for user-defined border widths in i3bar blocks (#3726)
This change introduces support for four new properties on the i3bar
protocol, namely "border_top", "border_right", "border_bottom"
and "border_left".

If a block is drawn with a border, these values define the width of
the corresponding edge in pixels. They all default to 1 if not
specified to preserve compatibility.

fixes #3722
2019-06-22 22:18:29 +02:00
Ingo Bürk
48af067dfe feat: support transparency (RGBA) in i3bar (#3727)
We introduce a --transparency flag for i3bar in order to enable a mode which
supports the use of RGBA colors.

An important constraint here is that tray icons will always have
a fully transparent background.

fixes #3723
2019-06-22 17:23:21 +02:00
Ingo Bürk
19ca55858c Merge pull request #3709 from okraits/patch-1
docs: describe for_window with the correct term
2019-06-03 08:19:38 +02:00
Oliver Kraitschy
e658788895 docs: describe for_window with the correct term
for_window is a directive or option, not a command.
2019-06-03 07:42:43 +02:00
Ingo Bürk
3c63e2cd7d Merge pull request #3706 from orestisf1993/swap
Fix: delete decoration cache after swap
2019-05-25 11:17:59 +02:00
Orestis Floros
573574b301 Fix: delete decoration cache after swap
Fixes a regression after 8e1687a where swapping 2 containers across
different workspaces would not update their titles.
2019-05-25 00:05:18 +03:00
Ingo Bürk
f2c7e26a0c Merge pull request #3701 from orestisf1993/click-events
i3bar: If click events disabled, use whole bar for other events
2019-05-14 15:23:28 +02:00
Orestis Floros
baf1067087 i3bar: If click events disabled, use whole bar for other events
Fixes #3700
2019-05-13 12:56:04 +03:00
Ingo Bürk
b6485c98a2 Merge pull request #3697 from orestisf1993/ewmh
Fix ewmh atom issues
2019-05-03 16:01:42 +02:00
Orestis Floros
c9efa6dffe Call all ewmh_update_* functions together when necessary
The testcase is changed because it was actually incorrect. Easy to
verify because:
> _NET_CURRENT_DESKTOP
> …
> The index of the current desktop. This is always an integer between 0
> and _NET_NUMBER_OF_DESKTOPS - 1.

Fixes #3696.
Also updates the viewports.

Finally, fixes an issue with _NET_CURRENT_DESKTOP not being updated
after a workspace rename. Example:
- workspaces 1, 2, 3
- rename workspace 1 to 5
- All workspaces changed their index but _NET_CURRENT_DESKTOP was not
updated
2019-05-03 16:19:11 +03:00
Orestis Floros
830465b39f ewmh: Cache idx to avoid xcb_change_property calls
Updates ewmh_update_current_desktop, ewmh_update_number_of_desktops
2019-05-03 16:16:22 +03:00
Orestis Floros
8c25bc1bd4 tree_close_internal: Log workspace name in EWMH message 2019-05-03 15:39:04 +03:00
Orestis Floros
4a37d20602 ewmh: Introduce FOREACH_NONINTERNAL macro 2019-05-03 15:38:37 +03:00
Orestis
a574346964 Merge pull request #3680 from bobnye/next
Fix memory leak

Fixes #3621
2019-04-11 10:29:43 +03:00
Jeremy Klotz
58c808a961 Fix memory leak 2019-04-10 19:56:30 -04:00
Ingo Bürk
56bbc528d7 Merge pull request #3674 from orestisf1993/janitorial
Janitorial
2019-04-03 19:13:10 +02:00
Orestis Floros
cc9b227978 Make small DLOG improvements
- manage_window: log the window in the start of the function so that the
reader knows what the rest of the messages refer to, even if the
function exits prematurely.
- con_is_floating: Message is spammy
2019-04-03 18:51:34 +03:00
Orestis Floros
8b88f00117 window.c: Reduce code in window_update_* functions 2019-04-03 18:51:34 +03:00
Orestis Floros
ea6068a02d Replace scalloc + strncpy with sstrndup 2019-04-03 18:51:34 +03:00
Ingo Bürk
88912d6f00 Merge pull request #3671 from orestisf1993/full_render_width
child_handle_button: Call only if x >= offset
2019-03-29 15:21:27 +01:00
Orestis Floros
8903f29795 child_handle_button: Call only if x >= offset
c2a1b6e9 was a bit overzealous, other actions should be executed if the
button was pressed after the workspace buttons but before the
statusline.

Also, should we allow other actions everywhere in the bar if click
events are disabled by the child?
2019-03-29 16:10:19 +02:00
Ingo Bürk
1b7e613d01 Merge pull request #3669 from orestisf1993/config
Allow checking for duplicate bindings with -C
2019-03-29 14:15:53 +01:00
Orestis Floros
08cdc3a6ae Allow checking for duplicate bindings with -C
- Having both parse_configuration and parse_file is excessive now
- We detect if we are parsing only by checking if conn is NULL, not with
use_nagbar
- font.pattern needs to be set to NULL because it is freed in
free_font()

Fixes #3660
2019-03-29 12:30:04 +02:00
Orestis Floros
7754de900a Move code clearing the config to a new function 2019-03-29 12:26:00 +02:00
Orestis Floros
4a2cacebf6 load_configuration: Remove conn argument 2019-03-29 02:49:10 +02:00
Orestis Floros
f9c4011691 Update configuration.h
- parse_configuration was mentioning outdated config file order
- kill_configerror_nagbar was not used anywhere
2019-03-29 02:49:10 +02:00
Ingo Bürk
a9e476e899 Merge pull request #3666 from orestisf1993/full_render_width
handle_button: Fix issues with clicks on statusline
2019-03-28 21:04:35 +01:00
Ingo Bürk
823345435b Merge pull request #3667 from orestisf1993/etc/config
etc/config: Mention ~/.config/i3/config
2019-03-28 21:03:35 +01:00
Ingo Bürk
4257b758a9 Merge pull request #3665 from lasers/add-markup
docs/i3bar-protocol: add markup to all possible entries example
2019-03-28 21:02:55 +01:00
Orestis Floros
6f1350865b etc/config: Mention ~/.config/i3/config 2019-03-28 21:29:09 +02:00
Orestis Floros
c2a1b6e91f handle_button: Introduce child_handle_button
Also fixes an issue where action would be called if the button press was
on a separator. For example, if a user scrolled on a separator, the
workspace would change.

Applies to --release commands as well.
2019-03-28 21:05:43 +02:00
Orestis Floros
03d2ccdeef handle_button: Use full render width for calculations
Fixes #3664

Also, click events' width will now always be >= min_width.
2019-03-28 21:05:29 +02:00
lasers
ae16a55616 docs/i3bar-protocol: add markup to all possible entries example 2019-03-28 11:43:08 -05:00
Ingo Bürk
feb2912e57 Merge pull request #3659 from orestisf1993/git-log-to-rev-list-3656
Use git plumbing commands to get the I3_VERSION
2019-03-22 14:53:59 +01:00
Orestis Floros
fefeedf8da Use git plumbing commands to get the I3_VERSION
Fixes #3656
2019-03-22 15:08:40 +02:00
Ingo Bürk
24a8eac134 Merge pull request #3658 from orestisf1993/workspace_move_to_output
Workspace move to output
2019-03-22 11:18:54 +01:00
Orestis Floros
d4e4cbfd25 workspace_move_to_output: Avoid operations when workspace already at destination
Closes #3635.
Probably the bug can still happen when a tree_close_internal happens
inside a workspace_show but modifying the code to avoid them seems to
not be worth it.
2019-03-22 10:47:49 +02:00
Orestis Floros
7fc3bf660e cmd_focus_output: Avoid assertion crash
Happened when the command criteria didn't match any windows. For
example: `[con_mark=doesnotexist] focus output left`.
2019-03-22 10:47:48 +02:00
Ingo Bürk
343007b9d4 Merge pull request #3657 from jeffhuxen/next
Added note which config directives could be used at runtime
2019-03-22 09:40:08 +01:00
Ingo Bürk
f6e42d103f Merge pull request #3643 from Iskustvo/next
Adding new IPC library(i3-ipc++) in documents.
2019-03-22 09:39:37 +01:00
Ingo Bürk
47d045d075 Merge pull request #3655 from orestisf1993/workspace_output_spaces
cfg_workspace: Accept outputs with spaces again
2019-03-22 09:38:02 +01:00
Orestis Floros
351d891f4c get_output_for_con: Assert result != NULL
- The result from con_get_output was always not NULL because
con_get_output asserts so
- get_output_by_name should always be able to get an output from the
corresponding container
- workspace_move_to_output doesn't return bool anymore since it can't
fail
2019-03-22 03:10:00 +02:00
Orestis Floros
d0ab51db85 workspace_move_to_output: Make stylistic changes 2019-03-22 03:09:27 +02:00
Jeffrey Huxen
ac2489240e Added to note to clarify which config directives could be used at runtime. 2019-03-21 17:07:23 -05:00
Iskustvo
214ed78154 Added new IPC library(i3-ipc++) in documents. 2019-03-21 22:44:00 +01:00
Orestis Floros
8ce99cdacb cfg_workspace: Accept outputs with spaces again
This is a regression from bce088679.

An other way to fix this would be to concatenate strings inside the
strtok loop when an output starts with a double quote but I'd rather
let the parser do the word splitting.

Fixes #3646
2019-03-21 21:31:30 +02:00
Ingo Bürk
3aa42cf795 Merge pull request #3654 from chrhasse/next
Add explicit reference to glib2 in automake
2019-03-21 08:44:13 +01:00
Christopher Hasse
4e5ce56188 Add explicit reference to glib2 to automake 2019-03-20 23:51:13 -05:00
Orestis
297abe0edd Merge pull request #3637 from i3/stapelberg-patch-1
x.c: correctly free con->frame_buffer in _x_con_kill
2019-03-19 11:16:30 +02:00
Michael Stapelberg
79b052230c x.c: correctly free con->frame_buffer in _x_con_kill
This fixes a crash which I could not reproduce in a testcase with reasonable effort, but the user reported the fix works.

Compare with src/x.c:946.

fixes #3554
fixes #3645
2019-03-19 09:50:22 +01:00
Michael Stapelberg
9bd2224520 travis: remove deprecated docker login -e flag (#3651) 2019-03-19 09:49:59 +01:00
Orestis
0cae9b236b Merge pull request #3640 from orestisf1993/partial-ucs2
convert_utf8_to_ucs2: Allow partial conversion
2019-03-19 10:36:52 +02:00
Orestis Floros
bd58d67ea8 convert_utf8_to_ucs2: Allow partial conversion
Fixes #3638.
2019-03-19 10:31:34 +02:00
Michael Stapelberg
6ec7b91cff fix travis build by switching away from deprecated-2017Q3 (#3650)
Also remove “sudo: false” as per
https://blog.travis-ci.com/2018-11-19-required-linux-infrastructure-migration
2019-03-19 09:30:04 +01:00
Ingo Bürk
80ecadbe31 Merge pull request #3614 from NilsIrl/next
Add proper return code for i3-msg
2019-03-11 19:38:10 +01:00
Ingo Bürk
9d9b552b70 Merge pull request #3632 from orestisf1993/workspace_init
create_workspace_on_output: send workspace init event
2019-02-23 21:52:22 +01:00
Orestis Floros
098b0e6976 create_workspace_on_output: send workspace init event
Fixes #3595
Like the issue mentions:
> instead of the newly created workspace (not referenced by variable
> here) the `"init"` event is fired with the current workspace (`ws`).

Plus, there was another issue where duplicate workspace init events
where being sent because of workspace_get().

304-ipc-workspace-init.t: Subtest "move workspace to output" fails with
current next.

Fixes #3631
No event was being sent here:
2d6e09a66a/src/randr.c (L487)

533-randr15.t: I confirmed that SKIP still works if the xrandr command
fails.
Added test fails with current next.
2019-02-23 12:00:55 +02:00
Nils ANDRÉ-CHANG
72ccd341fc Add proper return code for i3-msg 2019-02-21 19:52:55 +00:00
Michael Stapelberg
2d6e09a66a i3-dump-log: make log message a little more clear (#3618)
This came up when trying to debug an issue.
2019-02-12 09:22:26 +01:00
Ingo Bürk
e2d6117b8c Merge pull request #3607 from vacuus/3546-fix-misleading-doc
Clear up confusion between event and reply types.
2019-02-01 08:24:34 +01:00
Alejandro Angulo
85e6742686 Reword documentation to make clear the difference in enumeration between event and reply types. 2019-01-31 23:00:00 -08:00
Michael Stapelberg
a4309cb871 Merge branch 'release-4.16.1' 2019-01-27 16:45:31 +01:00
Michael Stapelberg
becd97e2fb Set non-git version to 4.16.1-non-git. 2019-01-27 16:45:31 +01:00
Michael Stapelberg
b4f9ff91d4 release i3 4.16.1 2019-01-27 16:45:19 +01:00
Orestis Floros
f7b6ae2836 Fix: render_con shows floating containers on wrong workspace
After 204eefc. Alternative fix:
    diff --git a/src/floating.c b/src/floating.c
    index f5c61782..6dd79668 100644
    --- a/src/floating.c
    +++ b/src/floating.c
    @@ -954,7 +954,7 @@ bool floating_reposition(Con *con, Rect newrect) {
             con->scratchpad_state = SCRATCHPAD_CHANGED;

         /* Workspace change will already result in a tree_render. */
    -    if (!reassigned) {
    +    if (!reassigned && workspace_is_visible(con_get_workspace(con))) {
             render_con(con);
             x_push_node(con);
         }
but I don't think that the extra complexity is worth it.

Change in handlers.c because of d2d6d6e0 where the bug also appears.

Fixes #3567
2019-01-23 21:30:52 +01:00
Orestis
f0e19d112c cmd_exit: Let i3_exit handle shutdown (#3600)
- __lsan_do_leak_check() will terminate the process, so move it to the
end of the function.
- ev_loop_destroy() must be called after ipc_shutdown() because the
latter calls ev_ functions.

Fixes #3599
2019-01-23 21:21:46 +01:00
Orestis Floros
4f768c6eda Fix crash with popups when fullscreen is non-leaf
Introduced in b3e69ed12

Fixes #3582
2019-01-23 21:21:34 +01:00
Orestis
54e7a31568 Use ipc queue for all messages (#3585)
I was able to reproduce #3579 in Linux by running:
`sudo sysctl net.core.wmem_default=10000`

If a subscription message was too big to be sent at once, it was
possible to break a client by sending a reply to an other message sent
by the client. Eg:
- Write 8192 out of 11612 bytes of a workspace event.
- Blockingly write the reply to a workspace change message.
- Write the rest 3420 bytes of the workspace event.

This commit fixes this by utilizing the ipc queue for all types of
writes.

ipc_receive_message can only be called from a callback started in
ipc_new_client. This callback uses the same file descriptor with the
client also created in ipc_new_client. When the client is deleted, the
read callback is now also stopped. Thus, we can assume that whenever
ipc_receive_message is called, the corresponding client should still
exist.

- ipc_client now contains pointers to both write and read watchers. When
freed, a client will stop both of them.
- IPC_HANDLERs now work with ipc_clients instead of fds.

Fixes #3579.
2019-01-23 21:21:28 +01:00
Orestis Floros
cf375927f0 attach_to_workspace: set new parent before tree_render
on_remove_child calls tree_close_internal which calls tree_render and
the tree is in an invalid state if con->parent still points to the old
parent.

Fixes #3556
2019-01-23 21:20:08 +01:00
Orestis Floros
f43f412771 Apply title_align to non-leaf containers
Additionally, marks will now display for non-leaf containers.

Fixes #3540.
2019-01-23 21:20:04 +01:00
Orestis Floros
0377970dab Truncate wm_name utf8 strings to first zero byte
Fixes #3515
2019-01-23 21:20:00 +01:00
Orestis
02bb2693f9 cmd_exit: Let i3_exit handle shutdown (#3600)
- __lsan_do_leak_check() will terminate the process, so move it to the
end of the function.
- ev_loop_destroy() must be called after ipc_shutdown() because the
latter calls ev_ functions.

Fixes #3599
2019-01-22 21:35:44 +01:00
Ingo Bürk
82a35a2418 Merge pull request #3590 from nejni-marji/next
Make binding modes case sensitive

closes #3587
2019-01-18 23:37:09 +01:00
Jonathan Woodlief
2a1ca0951e Update userguide to describe border styles better
Describe the difference between normal and pixel titlebars better

Thanks to @JonWoodlief
2019-01-18 23:35:47 +01:00
nejni-marji
22ac5827b0 Make binding modes case sensitive 2019-01-16 19:32:24 -06:00
Orestis
5aa0459be0 Use ipc queue for all messages (#3585)
I was able to reproduce #3579 in Linux by running:
`sudo sysctl net.core.wmem_default=10000`

If a subscription message was too big to be sent at once, it was
possible to break a client by sending a reply to an other message sent
by the client. Eg:
- Write 8192 out of 11612 bytes of a workspace event.
- Blockingly write the reply to a workspace change message.
- Write the rest 3420 bytes of the workspace event.

This commit fixes this by utilizing the ipc queue for all types of
writes.

ipc_receive_message can only be called from a callback started in
ipc_new_client. This callback uses the same file descriptor with the
client also created in ipc_new_client. When the client is deleted, the
read callback is now also stopped. Thus, we can assume that whenever
ipc_receive_message is called, the corresponding client should still
exist.

- ipc_client now contains pointers to both write and read watchers. When
freed, a client will stop both of them.
- IPC_HANDLERs now work with ipc_clients instead of fds.

Fixes #3579.
2019-01-12 13:13:03 +01:00
Ingo Bürk
e2e964151e Merge pull request #3584 from orestisf1993/popup-SIGSEGV
Fix crash with popups when fullscreen is non-leaf
2019-01-11 14:01:56 +01:00
Orestis Floros
0abb4f7e88 Fix crash with popups when fullscreen is non-leaf
Introduced in b3e69ed12

Fixes #3582
2019-01-11 14:46:13 +02:00
Orestis
00bb9a8483 Merge pull request #3574 from pclouds/no-newline-in-errx
Remove \n from errx and die messages
2019-01-02 14:30:17 +02:00
Nguyễn Thái Ngọc Duy
6462cf1ca3 Remove \n from errx and die messages
errx() already appends \n internally. "\n" in the error message will
result in a blank line after the message. die() is just a wrapper around
errx() so it receives the same treatment.
2019-01-02 14:23:56 +02:00
Ingo Bürk
3e3257af18 Merge pull request #3563 from CyberShadow/doc-mark-todo
userguide: Un-hide a TODO block completed in 2011
2018-12-16 09:36:02 +01:00
Ingo Bürk
982ede5901 Merge pull request #3568 from orestisf1993/floating_reposition-render_con
Fix: render_con shows floating containers on wrong workspace
2018-12-16 09:33:25 +01:00
Orestis Floros
318528e3fc Fix: render_con shows floating containers on wrong workspace
After 204eefc. Alternative fix:
    diff --git a/src/floating.c b/src/floating.c
    index f5c61782..6dd79668 100644
    --- a/src/floating.c
    +++ b/src/floating.c
    @@ -954,7 +954,7 @@ bool floating_reposition(Con *con, Rect newrect) {
             con->scratchpad_state = SCRATCHPAD_CHANGED;

         /* Workspace change will already result in a tree_render. */
    -    if (!reassigned) {
    +    if (!reassigned && workspace_is_visible(con_get_workspace(con))) {
             render_con(con);
             x_push_node(con);
         }
but I don't think that the extra complexity is worth it.

Change in handlers.c because of d2d6d6e0 where the bug also appears.

Fixes #3567
2018-12-16 03:49:21 +02:00
Ingo Bürk
a68542c8f7 Merge pull request #3566 from orestisf1993/focus-events
Focus events
2018-12-15 18:29:46 +01:00
Orestis Floros
fb1ae61d1c Invalidate last_focused when focusing the EWMH support window
Fixes #3562
2018-12-14 23:47:48 +02:00
Orestis Floros
dd708199ea Fix: killing unfocused window shouldn't produce focus event 2018-12-14 23:46:21 +02:00
Orestis Floros
f70c3b168d Update tree_close_internal documentation in tree.h
After f90840337
2018-12-14 23:46:21 +02:00
Vladimir Panteleev
7d89e90137 userguide: Un-hide a TODO block completed in 2011
The userguide contained a commented-out section for marks, which
included the line:

> TODO: make i3-input replace %s

The line was added in a26a11c609 (May
2011), at which point i3-input did not have a -F switch. The switch
was added only in 1737a78fcd (September
2011), but the documentation was never updated to enable the
commented-out examples.
2018-12-14 13:16:11 +00:00
Orestis
e6be6fea74 Merge pull request #3560 from CyberShadow/doc-mark-replace
userguide: Document mark --replace flag
2018-12-14 10:39:49 +02:00
Vladimir Panteleev
fdda9763b7 userguide: Document mark --replace flag
- Explicitly document --replace, which was previously only mentioned
  in the command syntax.

- Improve wording: "a window can only have one mark" is slightly
  misleading because it appears to describe the limitation as a
  property of the model, whereas this actually pertains the mark
  command.
2018-12-14 08:33:42 +00:00
Ingo Bürk
be6619ff11 Merge pull request #3557 from orestisf1993/regress-float-move
attach_to_workspace: set new parent before tree_render
2018-12-12 21:02:41 +01:00
Orestis Floros
605b6ba00f attach_to_workspace: set new parent before tree_render
on_remove_child calls tree_close_internal which calls tree_render and
the tree is in an invalid state if con->parent still points to the old
parent.

Fixes #3556
2018-12-12 19:12:01 +02:00
Orestis
376833db45 Merge pull request #3510 from orestisf1993/tree.t
Introduce cmp_tree test function
2018-12-12 13:19:43 +02:00
Orestis Floros
90c08a52f0 Introduce cmp_tree test function
Related to #3503
2018-12-12 13:09:15 +02:00
Ingo Bürk
32188d7b2c Merge pull request #3551 from xzfc/baf-restart
Preserve back_and_forth during restart
2018-12-11 20:53:08 +01:00
Albert Safin
64ab1f42b7 Preserve back_and_forth during restart
Add new key "previous_workspace_name" to the json dump of the root container.
2018-12-11 20:46:06 +07:00
Ingo Bürk
6a4d41c5c2 Merge pull request #3553 from stapelberg/hidpi
userguide: add a section about hidpi displays
2018-12-10 18:34:51 +01:00
Michael Stapelberg
d3e954befd userguide: add a section about hidpi displays
This is a continuation of #3438.
2018-12-10 18:18:23 +01:00
Ingo Bürk
f08119298e Merge pull request #3549 from xzfc/small-fixes
Small fixes
2018-12-09 18:13:13 +01:00
Ingo Bürk
b35c56687d Merge pull request #3550 from tlercher/3535-display-check
Fix #3535 - Check for DISPLAY when requesting version information
2018-12-09 18:10:42 +01:00
TAL
b479dc1a0f Fix #3535 - Check for DISPLAY when requesting version information 2018-12-09 02:20:47 +01:00
Albert Safin
27030c8566 Code style: fix misaligned and misindented comments 2018-12-09 08:04:55 +07:00
Albert Safin
b6282b47bc Remove unused con_get_next()
This function has unused for a long time since the commit
8f4b9ddaa4.
2018-12-09 08:04:41 +07:00
Albert Safin
0eb07dea5c Remove unnecessary code in route_click()
This case is handled by resize_find_tiling_participants() anyway which
is introduced in the commit dbec5eb905.
2018-12-09 07:48:40 +07:00
Albert Safin
9a1eb7a783 commands.c: Add missing error replies 2018-12-09 07:41:19 +07:00
Orestis
b192bf4bd2 Merge pull request #3547 from stapelberg/conn
Bugfix: use restore_conn, not conn
2018-12-08 14:49:04 +02:00
Michael Stapelberg
01c1b5dec2 Bugfix: use restore_conn, not conn
Using the wrong X11 connection breaks the libev event handling model:
xcb_flush() must be called immediately before handing control to libev.

Before this fix:

1. xcb_prepare_cb would read and flush conn
2. restore_xcb_prepare_cb would read and flush restore_conn,
   BUT also inadvertantly call xcb_flush(conn), resulting in new
   events being filled into the XCB event queue
3. libev waits for new events
4. after 1 minute, libev times out and the events are processed

Diagnosed using strace on testcases/complete-run.pl.

related to commit 0d8b6714e3

related to #3510
2018-12-08 13:31:53 +01:00
Orestis
620e90bed8 Merge pull request #3541 from orestisf1993/title_align
Apply title_align to non-leaf containers
2018-12-05 13:09:09 +02:00
Orestis Floros
a81e22a277 Apply title_align to non-leaf containers
Additionally, marks will now display for non-leaf containers.

Fixes #3540.
2018-12-04 20:50:32 +02:00
Ingo Bürk
52d785fb37 Merge pull request #3514 from xzfc/2742-shape
Add input and bounding shapes support (#2742)
2018-12-03 20:16:47 +01:00
Albert Safin
1a85619498 Add input and bounding shapes support (#2742)
Basic idea: if the window has a shape, set the parent container shape as
the union of the window shape and the shape of the frame borders.

Co-authored-by: Uli Schlachter <psychon@znc.in>
2018-12-01 11:52:41 +07:00
Albert Safin
9273f67734 Log window id in state_for_frame() 2018-12-01 10:31:11 +07:00
Michael Stapelberg
7ade46c61f switch to clang-format-6.0 (#3533) 2018-11-28 17:38:16 +01:00
Ingo Bürk
a080551f26 Merge pull request #3432 from orestisf1993/aspect-ratio
Fix aspect ratio bugs
2018-11-17 16:08:22 +01:00
Ingo Bürk
8ad84f06c9 Merge pull request #3524 from orestisf1993/regress-randr
randr.c: Fix regression with focusing NULL container
2018-11-15 12:57:59 +01:00
Orestis Floros
a84b30f8a9 randr.c: Fix regression with focusing NULL container
This was introduced in db3b9e4187 which
removed the NULL check for next.

Fixes #3523.
2018-11-15 13:49:26 +02:00
Ingo Bürk
299e9b9fdd Merge pull request #3521 from c-edw/feature/StripWorkspaceDocs
Update userguide docs for strip_workspace_*.
2018-11-13 10:24:11 +01:00
Connor E
3463406df7 Update userguide docs for strip_workspace_*. 2018-11-13 08:46:16 +00:00
Orestis Floros
d2d6d6e0a8 Re-render floating cons alone when possible 2018-11-12 19:05:51 +02:00
Orestis Floros
100d05a2a6 render_con: Get rid of render_fullscreen argument
Only true for the fullscreen container and doesn't affect any of its
children. Thus, we can get the same result by checking
->fullscreen_mode.
2018-11-12 19:05:50 +02:00
Orestis Floros
29f2510fa9 Fix aspect ratio bugs
- ICCCM says: > If a base size is not provided, the minimum size is to
be used in its place and vice versa.
i3 didn't obey the "vice versa" part. Min size and base size are both
saved without replacements in window_update_normal_hints,
floating_check_size makes the needed replacements if either was not
provided.
- Aspect ratio is now saved correctly in manage_window because
window_update_normal_hints is called.
- i3 didn't save the aspect ratio if the window conformed the given
aspect ratio range when handle_normal_hints was called. If the window
was resized to a size outside of the given bounds, i3 didn't correct it.
- Aspect ratio now affects only tiling windows, like the rest of the
normal size hints
- The aspect ratio calculation is now done without a loop

A real life example of how these changes affect the workflow:
An mpv window, when playing a video, sets its min == max aspect ratio
during mapping. i3 ignored these hints. When resized, the window's
aspect ratio was not preserved. With this commit, resizing floating mpv
windows will always preserve the aspect ratio.
2018-11-12 18:45:00 +02:00
Orestis Floros
f397698d43 floating_resize: Use uint32_t 2018-11-12 18:45:00 +02:00
Orestis Floros
01960f956f floating_check_size: Use window variable 2018-11-12 18:44:45 +02:00
Ingo Bürk
90c39a4bf6 Merge pull request #3484 from xzfc/3476-export-i3sock
Export I3SOCK
2018-11-10 22:12:01 +01:00
Ingo Bürk
56bb806b52 Merge pull request #3397 from orestisf1993/randr-enable-disable
Fix bugs in enabling & disabling randr outputs
2018-11-10 21:56:34 +01:00
Ingo Bürk
cf553ce31e Merge pull request #3516 from orestisf1993/truncate-utf8
Truncate wm_name utf8 strings to first zero byte
2018-11-09 21:01:57 +01:00
Orestis Floros
11bc25b70b Truncate wm_name utf8 strings to first zero byte
Fixes #3515
2018-11-09 19:42:32 +02:00
Orestis
665b16807f Merge pull request #3511 from aksel/247-gaps-resize-fix
For resizing, convert pixel diff to percentage, based on parent.
2018-11-09 00:31:06 +02:00
aksel
bbfa140c0f For resizing, convert pixel diff to percentage, based on parent.
Previously, it first calculated one of the containers' next percentage, and then subtracted the previous percentage to find the actual change.

Now it directly calculates the change, and subtracts and adds the change to the two affected containers.

Added util function con_rect_size_in_orientation.

Removed px_resize_to_percent; inlined, using con_rect_size_in_orientation.

Also, prematurely return when pixel diff is 0, as no action is necessary.

This is related to [this issue on i3-gaps](https://github.com/Airblader/i3/issues/247).
2018-11-08 23:15:23 +01:00
Ingo Bürk
44e8fddc28 Merge pull request #2954 from orestisf1993/swap-for-floating
Rewrite con_swap to work only with queue operations
2018-11-07 13:13:41 +00:00
Ingo Bürk
4e1c20c871 Merge pull request #3508 from orestisf1993/load_layout-marks
load_layout: Correctly mark non-leaf containers
2018-11-07 07:11:21 +00:00
Orestis Floros
eb53ec83b9 load_layout: Correctly mark non-leaf containers
Example problematic layout:
    {
        "layout": "splith",
        "marks": ["H1"],
        "nodes": [
            {
                "swallows": [
                    {
                        "class": "^a$"
                    }
                ]
            }
        ]
    }

Since the marks were added to the json_node during end_map, the
container that ended up getting the "H1" mark was the child instead of
the parent.
2018-11-07 02:32:12 +02:00
Ingo Bürk
3649ecb71e Merge pull request #3482 from hamishimac/next
Do not assume STDIN_FILENO is available for input from child
2018-11-05 22:32:54 +01:00
Ingo Bürk
21cbb1000d Merge pull request #3504 from Foxboron/morten/i3-man-path
Change config order in manpage
2018-11-05 22:32:27 +01:00
Ingo Bürk
584ca21032 Merge pull request #3485 from xzfc/3412-outer-border
Draw outer header borders for all layouts
2018-11-05 22:31:35 +01:00
Orestis
f4a1482000 Merge pull request #3505 from stapelberg/release-docs
release.sh: save docs first
2018-11-05 20:45:59 +02:00
Michael Stapelberg
3a3f0f18e6 release.sh: save docs first
Otherwise, as @orestisf1993 pointed out, the saved documentation will have the
wrong version number.
2018-11-05 19:32:29 +01:00
Albert Safin
7926c817a2 Draw outer header borders for all layouts 2018-11-05 20:17:01 +07:00
Morten Linderud
e3ad800902 Change config order in manpage
This brings the headline for the configuration files inline with the
recent move to XDG directories.

Signed-off-by: Morten Linderud <morten@linderud.pw>
2018-11-05 14:15:07 +01:00
Ingo Bürk
6e998cf4e3 Merge pull request #3499 from orestisf1993/docs
userguide: break long comment
2018-11-04 15:53:15 +01:00
Michael Stapelberg
07e5747c8c travis: move (failing) ubuntu build from xenial to bionic
Ubuntu’s apt started refusing to load package files from unauthenticated
repositories, but the package for which we did that (xcb-xrm) is available in
newer versions of Ubuntu, so I just removed that part altogether.

Apparently this has been broken since April, and nobody noticed :-/
2018-11-04 15:24:10 +01:00
Michael Stapelberg
86bcb21dbc update release.sh for the 4.16 release 2018-11-04 15:07:24 +01:00
Michael Stapelberg
cb09db94dc update debian/changelog 2018-11-04 14:55:50 +01:00
Michael Stapelberg
e6f2255ed2 Update debian/changelog 2018-11-04 14:47:46 +01:00
Michael Stapelberg
3ae8a45c56 Merge branch 'release-4.16' 2018-11-04 14:47:46 +01:00
Michael Stapelberg
1847938d4e Merge branch 'next' into master 2018-11-04 14:47:46 +01:00
Michael Stapelberg
a26a342b35 Set non-git version to 4.16-non-git. 2018-11-04 14:47:46 +01:00
Michael Stapelberg
d617f71b22 release i3 4.16 2018-11-04 14:47:34 +01:00
Orestis Floros
af10b710bf userguide: break long comment 2018-11-04 12:23:45 +02:00
Orestis
dc16df439e Update ewmh focused only when new focus is different (#3496)
Fixes #3495.
2018-11-03 13:39:49 +01:00
Orestis
a0105dd2f2 Merge pull request #3497 from stapelberg/clang-format
switch to clang-format-4.0
2018-11-03 10:42:50 +02:00
Michael Stapelberg
eedb257655 switch to clang-format-4.0
clang-format-3.8 is old enough to have vanished from Debian testing, which we
use for our CI.
2018-11-03 09:16:16 +01:00
Ingo Bürk
f16afef7b3 Merge pull request #3486 from orestisf1993/regress-move-floating
Fix regression with moving floating windows
2018-10-29 14:59:25 +01:00
Orestis Floros
64c493ef1f Fix regression with moving floating windows
This fixes a regression introduced in 6d983b5. Consider 2 outputs:
fake-0: workspace '1'
fake-1: workspaces '2','3'
Workspace 1 focused, workspace 2 visible.
Open a floating window in 1 and move it to 3. Now, the floating window
appears in workspace 2 and disappears once focus is switched to
that workspace.

Instead of focusing 'old_focus' which might refer to a container in a
different output, we should restore focus by focusing the previously
focused workspace of the output.
2018-10-29 15:46:28 +02:00
Ingo Bürk
04d1fcbe2d Merge pull request #3483 from soumya92/next
Update badges in README
2018-10-26 20:46:53 +02:00
Soumya
ce7e1b9177 Update badges in README
issuestats.com seems to have moved on, using shields.io instead.
2018-10-26 09:58:04 -07:00
Hamish Macdonald
5084a881af Do not assume STDIN_FILENO is available for input from child 2018-10-26 09:31:43 -04:00
Albert Safin
aa20358620 Export I3SOCK (#3476) 2018-10-26 15:40:59 +07:00
Ingo Bürk
37e2b58226 Merge pull request #3465 from soumya92/next
Add "modifiers" to events sent by i3bar
2018-10-26 09:49:35 +02:00
Soumya
3745e6f484 Add "modifiers" to events sent by i3bar 2018-10-25 16:02:06 -07:00
Orestis
2ddf4f2c6d Merge pull request #3473 from soumya92/pango-font-alignment
Always center text vertically
2018-10-24 22:57:31 +03:00
Orestis
5d70e2850f Merge pull request #3475 from Gravemind/fix-i3bar-re-hidden-on-any-modifier
i3bar: Fix i3bar re-hidden by any modifier (#3474)
2018-10-23 18:41:11 +03:00
Ingo Bürk
64e7646c7e Merge pull request #3452 from orestisf1993/title_align
Add title_align config directive
2018-10-23 16:41:54 +02:00
Ingo Bürk
48524e1f0a Merge pull request #3451 from orestisf1993/tray
Close & reopen tray selwin when needed
2018-10-23 15:45:45 +02:00
Orestis Floros
e240c118c7 Close & reopen tray selwin when needed
Fixes #1329
Fixes #3317 (duplicate)
Examples where the tray "disappeared":
- Start without a "tray_output", reload config with "tray_output none",
remove "tray_output none" and reload.
- Start with "tray_output primary" (or "tray_output <output>"), disable
the primary output and then reconnect it.

Fixes #2010
Cached in output_for_tray
2018-10-23 16:41:09 +03:00
Ingo Bürk
ffc7ea8c50 Merge pull request #3469 from yablonsky/patch-1
Update userguide "Focus Parent": add the default
2018-10-23 15:37:12 +02:00
Ingo Bürk
0ed29f5678 Merge pull request #3448 from orestisf1993/sticky
Fix sticky focus when switching to workspace on different output
2018-10-23 15:31:57 +02:00
Ingo Bürk
66d504f3cd Merge pull request #3445 from orestisf1993/flaky
Fix flakyness in t/189-floating-constraints.t
2018-10-23 15:30:11 +02:00
Ingo Bürk
74a7bf31a5 Merge pull request #3444 from orestisf1993/move
Some move.c fixes
2018-10-23 15:29:48 +02:00
Ingo Bürk
db0add0f11 Merge pull request #3433 from orestisf1993/janitorial
Janitorial
2018-10-23 15:27:50 +02:00
Gravemind
c40c79538e i3bar: Fix i3bar re-hidden by any modifier (#3474)
The bug was introduced in 4.15-next fe6b3b7474
2018-10-23 15:17:30 +02:00
Soumya
81eea19e1e Always center text vertically 2018-10-22 12:59:08 -07:00
Andriy Yablonskyy
b971c0e50f add missing parenthesis 2018-10-21 13:42:19 -04:00
Andriy Yablonskyy
3de950e0d9 Update userguide "Focus Parent": add the default
While reading the UserGuide, I had to refer to the TL;DR image on top to find the default keybind for "Focus Parent" since it's not mentioned in the text.
This pr fixes it.
2018-10-21 13:38:58 -04:00
Ingo Bürk
a319860cd1 Merge pull request #3467 from orestisf1993/userguide
userguide: Use anchor for list of commands
2018-10-21 12:28:11 +02:00
Orestis Floros
5295266cf2 userguide: Use anchor for list of commands
Fixes #3464
2018-10-21 13:20:45 +03:00
Michael Stapelberg
02284acba8 debian/control: remove dependency on x11-utils (#3455)
This was a introduce in commit a61e34d277 in 2009,
and we haven’t used xmessage in any way in a long time.

fixes https://bugs.debian.org/910997
2018-10-15 18:00:43 +02:00
Orestis
7013ea6c99 Merge pull request #3456 from stapelberg/travis
travis: fix mk-build-deps call by providing changelog file
2018-10-15 11:16:20 +03:00
Michael Stapelberg
40bf2192f0 travis: fix mk-build-deps call by providing changelog file
mk-build-deps started using the changelog file to get the version number, but a
bug prevents it from falling back correctly to 1.0 if no changelog is
present. This has been fixed upstream in
4b15abd4f0,
but we can just ship the changelog file until that fix lands.
2018-10-15 08:40:00 +02:00
Orestis Floros
07dfb8450b Fix typo: childs -> children 2018-10-13 21:10:11 +03:00
Orestis Floros
204eefc679 floating_reposition: avoid extra tree_render 2018-10-13 21:10:11 +03:00
Orestis Floros
36a972d851 Use open_floating_window arguments for rect 2018-10-13 21:10:10 +03:00
Orestis Floros
8c17e4e38d manage_window: cleaner variable declarations 2018-10-13 21:10:10 +03:00
Orestis Floros
966915cfb2 borders_to_hide doesn't need to be initialized 2018-10-13 21:10:10 +03:00
Orestis Floros
4219eb213b root is externally declared 2018-10-13 21:10:10 +03:00
Orestis Floros
052e96d323 Use lround instead of (long)round 2018-10-13 21:10:10 +03:00
Orestis Floros
e4d2b38552 Make comment style more consistent 2018-10-13 21:10:10 +03:00
Orestis Floros
a65914f338 Fix missing prototypes
i3 will now compile with no warnings when -Wmissing-prototypes is used.
2018-10-13 21:10:10 +03:00
Orestis Floros
2a9522dda4 Enforce strict prototypes
i3 will now compile with no warnings when -Wstrict-prototypes is used.
2018-10-13 21:10:09 +03:00
Orestis Floros
a15fff2370 Use path_exists 2018-10-13 21:10:09 +03:00
Orestis Floros
50880db2c5 Reduce some code around frees 2018-10-13 21:10:09 +03:00
Orestis
565d38c5af Merge pull request #3454 from alanbarr/cppcheck_fixes_2
Cppcheck Fixes
2018-10-13 21:07:17 +03:00
Alan Barr
7c0994dafc Fixes for undefined behaviour on signed shift (#3453)
Fixes for undefined behaviour on signed shift

Change literal 1 to unsigned to allow safe bitshift of 31.
Caught by cppcheck.

Make 0xFF unsigned to prevent a left shift into signed bit.
Spotted by @orestisf1993
2018-10-13 21:04:40 +03:00
Alan Barr
687238b79b Typecast void* before doing pointer arithmetic
Caught by cppcheck
2018-10-13 17:41:50 +01:00
Alan Barr
88c378154a Remove redundant NULL check
copy has been used before this point - so it is too late to be concerned
about a NULL pointer now.

This is OK as sstrdup() calls err() on NULL return from the underlying
strdup() call.

Raised by cppcheck.
2018-10-13 17:41:50 +01:00
Aestek
6d82753d53 Add title_align config directive
Controls the window titles alignment in title bars. Possible values are:
- left
- center
- right

Co-authored-by: Orestis Floros <orestisf1993@gmail.com>
- Made title_align a config directive instead of a command. Helps with
some tree_render() issues we had.
- Made title_max_width the same for all 3 cases.
- Modified title offset calculations and added explanations for each
case.
- Append title_padding to mark_width if a mark exists.

Fixes #1750
2018-10-12 19:58:48 +03:00
Orestis Floros
b09090fa7d Fix sticky focus when switching to workspace on different output
See the testcase for the exact steps to reproduce the problem.
2018-10-11 12:27:57 +03:00
Orestis Floros
6728696ec8 output_push_sticky_windows: Make a bit easier to understand 2018-10-11 12:27:56 +03:00
Orestis Floros
ba8c64c4d9 285-sticky.t: Use kill_all_windows 2018-10-11 12:04:38 +03:00
Orestis Floros
e2d095cb7a Fix flakyness in t/189-floating-constraints.t
Related to #3009.
2018-10-10 19:15:45 +03:00
Orestis Floros
8e1687a317 Rewrite con_swap to work only with queue operations
Benefits are that we don't open a fake container and don't call many
complicated functions that can lead to redraws (x_push_changes calls) as
discussed in #2954.

Fixes #2810:
Windows exchange floating mode & window rects.
Swap will still not work with CT_FLOATING_CONs but this doesn't make
much sense.

Fixes #3280:
The behaviour is not very user friendly but swap behaves exactly as it
should. The rest is a tree_flatten issue. Attached pictures in #2954.
2018-10-10 17:09:26 +03:00
Orestis Floros
11dd2dbc66 tree_move: Don't change focus order when swapping containers
The call to ewmh_update_wm_desktop is removed since the change happens
under the same parent.
2018-10-09 22:39:38 +03:00
Orestis Floros
9380a75186 move.c: Fix move_to_output_directed problems
- Use workspace_show that correctly updates _NET_CURRENT_DESKTOP, warps
mouse.
- Use TAILQ_INSERT_TAIL only for focus_head. Focus order is not related
to direction.
- Call con_focus only if con was focused before. See testcase for
directional move with command criteria.
- Correct first call of move_to_output_directed in tree_move which
didn't call ipc_send_window_event("move", con) and
ewmh_update_wm_desktop().
- Don't produce events when the move doesn't happen. Correct
276-ipc-window-move.t as well.
2018-10-09 22:35:04 +03:00
Orestis
dfe89cc4f1 i3-nagbar: add option for button that runs commands without a terminal (#3258)
Fixes #2199.
2018-10-07 22:43:24 +02:00
Orestis
c583f81c80 Merge pull request #3441 from stapelberg/template
add specific GitHub issue templates
2018-10-07 22:09:28 +03:00
Orestis
f20467ac86 Merge pull request #3440 from stapelberg/disable
configure.ac: add conditionals for building docs/mans
2018-10-07 22:02:43 +03:00
Michael Stapelberg
824d691640 add specific GitHub issue templates
I learnt about this from the GitHub blog:
https://blog.github.com/2018-05-02-issue-template-improvements/
2018-10-07 20:41:42 +02:00
Orestis
2be4975f18 resolve_tilde: strncpy + strlen is pointless (#3436)
strlen already assumes that the string is NULL-terminated.

Like in https://github.com/i3/i3status/pull/312 but for whatever reason
gcc didn't warn about this here.
2018-10-07 20:26:37 +02:00
Orestis
18dbfe699a userguide: Mention know issues for assign (#3434)
Fixes #3222
Fixes #3293
Related to #2060
2018-10-07 20:24:09 +02:00
Michael Stapelberg
acea46e16a configure.ac: add conditionals for building docs/mans
fixes #3378
2018-10-07 20:09:35 +02:00
Orestis
5720ba65ab Merge pull request #3435 from vivien/i3-msg/subscribe
i3-msg/subscribe
2018-10-05 12:16:04 +03:00
Vivien Didelot
cff4fadd72 i3-msg: add support for SUBSCRIBE message type
If i3-msg is invoked with -t subscribe, it will wait for the first event
matching the given payload, before exiting.

For instance, get the number of the next focused workspace with:

    i3-msg -t subscribe '[ "workspace" ]' | jshon -e current -e num

Like inotifywait, the -m flag allows to wait indefinitely for events,
instead of exiting right after receiving the first one.

For example, continuously monitor the names of focused windows with:

    i3-msg -t subscribe -m '[ "window" ]' | jq .container.name
2018-10-04 12:54:45 -04:00
Vivien Didelot
d722d1b0e6 i3-msg: check reply in quiet mode
i3-msg currently exits right after sending the IPC message if the quiet
flag is set. This means that if an error occurred when issuing a
command, e.g. "i3-msg -q foobar", it gets silently ignored.

What we really want is to just skip printing but still check the reply.

At the same time, explicitly print the reply when we need to, instead of
using an exit label.
2018-10-03 10:43:09 -04:00
Orestis
3b73edb511 Merge pull request #3430 from Synray/aspect_ratio
[RFC] Correctly calculate max_aspect
2018-10-02 03:04:21 +03:00
Thomas Fischer
0ede8b9365 Correctly calculate max_aspect 2018-09-28 17:34:18 -07:00
Michael Stapelberg
b8b5a61a2d Merge pull request #3415 from orestisf1993/g_utf8_make_valid
Check g_utf8_make_valid availability
2018-09-28 18:00:06 +02:00
Ingo Bürk
ebf40889a1 Merge pull request #3424 from orestisf1993/con_num_windows
con_num_windows: Count floating windows
2018-09-28 09:27:58 +02:00
Orestis Floros
5e1d327e43 con_num_windows: Count floating windows
Fixes #3423.
2018-09-26 20:04:17 +03:00
Ingo Bürk
27afc572c1 Merge pull request #3421 from Streetwalrus/iconic-state
Reject requests for WM_STATE_ICONIC
2018-09-26 09:07:16 +02:00
Dan Elkouby
6877205ac1 Reject requests for WM_STATE_ICONIC
For compatiblity reasons, Wine will request iconic state and cannot
ensure that the WM has agreed on it; immediately revert to normal to
avoid being stuck in a paused state.
2018-09-25 15:04:55 +03:00
Orestis Floros
daf5ca111f Provide g_utf8_make_valid if not available
See #3415 for licensing discussion.

Fixes Airblader/i3#236
2018-09-25 10:28:20 +03:00
Orestis Floros
aa8215194c Fix typo: terminaison -> termination 2018-09-24 20:53:36 +03:00
Ingo Bürk
bec227236b Merge pull request #3420 from orestisf1993/sncontext==NULL-3419
i3-nagbar & i3-config-wizard: check sncontext != NULL
2018-09-23 20:12:16 +02:00
Orestis Floros
d080f58299 i3-nagbar & i3-config-wizard: check sncontext != NULL
From
07237ff25d/libsn/sn-common.c (L87-L171)
it appears that SnDisplay can't be NULL, so I skipped the check.

Fixes #3419
2018-09-23 17:06:29 +03:00
Ingo Bürk
ac88d06632 Merge pull request #3416 from orestisf1993/530-bug-2229.t
530-bug-229.t: Get rid of smartmatch
2018-09-20 18:52:33 +02:00
Orestis Floros
bf9da466db 530-bug-229.t: Get rid of smartmatch 2018-09-20 19:37:50 +03:00
Orestis
7c21b5995d Merge pull request #3400 from Synray/next
Respect max size from WM_NORMAL_HINTS
2018-09-20 11:36:22 +03:00
Thomas Fischer
690e6d1f0e Respect max size in WM_NORMAL_HINTS 2018-09-20 11:31:19 +03:00
Ingo Bürk
bde4f40b67 Merge pull request #3408 from orestisf1993/__focused__-crash
match_matches_window: Check if focused->window exists
2018-09-19 14:42:28 +02:00
Ingo Bürk
ea559966b5 Merge pull request #3410 from orestisf1993/min_width
docs/i3bar-protocol: Mention skipping blocks with empty full_text
2018-09-17 16:06:27 +02:00
Ingo Bürk
2b898f4c90 Merge pull request #3386 from orestisf1993/click-event
Fix "relative_x" and "width" of click events
2018-09-16 15:48:36 +02:00
Orestis Floros
9b06f1ab05 docs/i3bar-protocol: Mention skipping blocks with empty full_text
Closes #3405.
2018-09-16 15:04:20 +03:00
Orestis Floros
fed059a2b7 Fix "relative_x" and "width" of click events
Now clicks begin at the start of the "actual" block, offsets and
separators don't trigger click events. The width property is now just
the width of the block, including border.

Fixes #3380.
2018-09-16 14:58:20 +03:00
Orestis Floros
515dd45f59 match_matches_window: Check if focused->window exists
Fixes #3406.
2018-09-16 14:55:27 +03:00
Ingo Bürk
633583de4a Merge pull request #3409 from orestisf1993/sb_hoff_px
i3bar: Include sb_hoff_px only when needed
2018-09-16 11:11:47 +02:00
Orestis Floros
9936d049cf i3bar: Include sb_hoff_px only when needed
Fixes #3404.
2018-09-15 13:27:18 +03:00
Ingo Bürk
18f705a978 Merge pull request #3403 from orestisf1993/issue-3402
_con_move_to_con: Move upwards only on CT_FLOATING_CON
2018-09-14 15:17:13 +02:00
Orestis Floros
d407393d0d _con_move_to_con: Move upwards only on CT_FLOATING_CON
If target is inside a floating container but not its direct child, the
move can be completed as is.

Fixes #3402.
2018-09-14 16:13:41 +03:00
Ingo Bürk
c7132ec5b0 Merge pull request #3401 from orestisf1993/dump-asy-floating
dump-asy.pl: Include floating_nodes
2018-09-14 13:29:07 +02:00
Orestis Floros
702e83c95e dump-asy.pl: Include floating_nodes 2018-09-14 14:05:51 +03:00
Ingo Bürk
ede954128a Merge pull request #3342 from orestisf1993/tree_close_internal
Simplify tree_close_internal
2018-09-14 12:24:54 +02:00
Ingo Bürk
badcb152f9 Merge pull request #3399 from orestisf1993/156-fullscreen-focus
Make t/156-fullscreen-focus.t easier to work with
2018-09-14 08:19:00 +02:00
Ingo Bürk
9c2ff947e1 Merge pull request #3398 from orestisf1993/i3-save-tree
i3-save-tree: Exclude unsupported "transient_for" property
2018-09-14 08:18:32 +02:00
Orestis Floros
68628e153f Make t/156-fullscreen-focus.t easier to work with
- Add routine that will refocus the expected window on test failure.
Thus, failure on one test will not make others fail.
- Remove some redundant commands, prefer fresh_workspace for screen
changing.
- Kill previous windows between sections if the next section does not
depend on the previous layout.
2018-09-13 17:18:34 +03:00
Orestis Floros
f6bb1e22bb init_ws_for_output: Remove content argument 2018-09-12 16:53:20 +03:00
Orestis Floros
5976381012 output_init_con: Restore focus if possible
Before this, i3 would focus newly created workspaces on output init
2018-09-12 16:47:18 +03:00
Orestis Floros
db3b9e4187 randr_disable_output: Always restore focus
con_detach and con_attach modify the focus stack.

This will make sure that the currently focused workspace will remain
focused after disabling an output.
2018-09-12 16:46:47 +03:00
Orestis Floros
4d21f4cfc2 init_ws_for_output: use workspace_move_to_output
This fixes a crash produced with the following config:
    # i3 config file (v4)
    workspace 1 output $screen1
    workspace 2 output $screen2

    exec --no-startup-id "i3-msg workspace 1, open && i3-msg workspace 2 && xrandr --output $screen2 --off && xrandr --output $screen1 --auto --output $screen2 --auto --right-of $screen1 "

Which results in:
ERROR: AddressSanitizer: heap-use-after-free on address …
READ of size 8 at 0x614000001f48 thread T0
    #0 0x5563df6e73a8 in init_ws_for_output i3/src/randr.c:468
    #1 0x5563df6ef3b4 in randr_query_outputs i3/src/randr.c:940
    #2 0x5563df68dbe1 in handle_screen_change i3/src/handlers.c:450

… is located 264 bytes inside of 448-byte region …
freed by thread T0 here:
    #1 0x5563df634b0a in con_free i3/src/con.c:96
    #2 0x5563df7151e6 in tree_close_internal i3/src/tree.c:344
    #3 0x5563df7280fe in workspace_show i3/src/workspace.c:499
    #4 0x5563df6e7315 in init_ws_for_output i3/src/randr.c:457
    #5 0x5563df6ef3b4 in randr_query_outputs i3/src/randr.c:940
    #6 0x5563df68dbe1 in handle_screen_change i3/src/handlers.c:450

Which is similar to #3228, #3248.
2018-09-12 16:46:47 +03:00
Orestis Floros
a66048a956 i3-save-tree: Exclude unsupported "transient_for" property
Even if i3 supported matching windows through "transient_for", it
wouldn't be useful for the purpose of i3-save-tree.
2018-09-12 14:13:56 +03:00
Ingo Bürk
484854d52f Merge pull request #3395 from lousyd/next
clarify JSON standard non-compliance
2018-09-12 10:24:30 +02:00
Ingo Bürk
1a6c971052 Merge pull request #3396 from orestisf1993/commands
commands.c: Improve error replies
2018-09-12 10:24:06 +02:00
Orestis Floros
e67be1ccd3 commands.c: Improve error replies
- Improve / add various error messages.
- Replace all `LOG(…); ysuccess(false);` with `yerror(…);`.
- switch_mode: Remove redundant "ERROR:" ELOG string.
- cmd_move_con_to_workspace*: Make sure that we don't try to move an
empty workspace to another workspace. This can be problematic when we
match a workspace using command criteria (eg marks) and the target is a
non-existing workspace. We create the new workspace but since nothing is
moved there, we are left with an empty workspace. See added testcase.
2018-09-11 08:35:58 +03:00
Todd Walton
3bfcbb88bf clarify JSON standard non-compliance
Modified section on the layout file's non-compliance with the JSON
standard. The section previously stated that having multiple top-level
JSON texts is non-compliant. This isn't the case. It's just that most
JSON parsers will treat that as if it is non-compliant.
2018-09-10 16:31:25 -04:00
Michael Stapelberg
83327abae4 Merge pull request #3394 from orestisf1993/validate-utf8
libi3: validate UTF8 strings
2018-09-10 09:00:54 +02:00
Orestis Floros
6a1f653508 libi3: validate UTF8 strings
Will validate container / window titles.

Fixes #3156.
2018-09-10 02:00:32 +03:00
Orestis Floros
a3dcee35f3 tree_restore: Check croot
Related to #2414, #3156.
2018-09-09 16:11:48 +03:00
Ingo Bürk
9dc4df81ea Merge pull request #3391 from orestisf1993/yajl-utf8
tree_append_json: Allow strings that are not valid UTF8
2018-09-06 14:15:54 +02:00
Orestis Floros
be6faa3161 tree_append_json: Allow strings that are not valid UTF8
Fixes #3156.

I couldn't reproduce the problem in a "natural" way so I cheated:
1. Start i3 with gdb
2. Set breakpoing on tree_restore
3. Run, open window, i3-msg restart
5. Open the file in *path with a hex editor
6. Edit the "name" field of the window and insert bytes that are not
valid UTF8
7. Continue

After parsing fails, all nodes including croot are incomplete, meaning
they have to be deleted. We can't recover in any reasonable way so we
have to allow non-UTF8 characters to avoid this situation altogether.
2018-09-06 14:58:31 +03:00
Orestis Floros
e8d2b9b7b5 tree_append_json: don't focus freed container 2018-09-06 14:48:21 +03:00
Ingo Bürk
cb6da7169a Merge pull request #3389 from orestisf1993/resize-ensure-1px
Ensure containers have a size of at least 1px after resize
2018-09-06 08:41:00 +02:00
Ingo Bürk
9edb7c7a3b Merge pull request #3390 from orestisf1993/resize-tile
resize set for tiling: default to px when not specified
2018-09-06 08:38:53 +02:00
Ingo Bürk
7257c3b528 Merge pull request #3388 from orestisf1993/cmd_rename_workspace
cmd_rename_workspace: correct order of events
2018-09-06 08:38:03 +02:00
Orestis Floros
64142eeef2 resize set for tiling: default to px when not specified 2018-09-06 05:58:51 +03:00
Orestis Floros
23c1c13d34 Ensure containers have a size of at least 1px after resize
Fixes #2226.
Fixes #2776.
Fixes #3241.
Related to #3194.
2018-09-06 04:56:31 +03:00
Orestis Floros
6846ac98c0 cmd_rename_workspace: correct order of events
1. Rename happens
2. Workspace is moved because of assignments
3. Workspace closes because it is empty (#3248)

Fixes #3248.
2018-09-06 03:42:07 +03:00
Orestis Floros
7c3c50c5cc Improve comment from #3245 2018-09-06 03:42:06 +03:00
Michael Stapelberg
09683d21a9 configure.ac: fix AC_SEARCH_LIBS([shm_open]) for static linking (#3379)
Without specifying -pthread, the conftest fails and -lrt is missing during
compilation of i3, resulting in a failing build.
2018-08-31 08:59:08 -06:00
Ingo Bürk
9595263142 Merge pull request #3376 from orestisf1993/floating-disable-scratchpad
Don't disable floating in internal workspaces
2018-08-28 13:30:57 +02:00
Orestis Floros
9718e38a7a Don't disable floating in internal workspaces 2018-08-28 11:26:20 +03:00
Ingo Bürk
f454a5c2dd Merge pull request #3375 from orestisf1993/ipc_client_timeout
ipc_client_timeout: Fix build when not on linux
2018-08-28 10:20:45 +02:00
Orestis Floros
37b879f4ad ipc_client_timeout: Fix build when not on linux
Also moved the 'end' label because it is unused otherwise.

Reported here: https://github.com/Airblader/i3/issues/233
2018-08-27 22:21:59 +03:00
Ingo Bürk
08a53611f9 Merge pull request #3374 from orestisf1993/startup-notification
Support startup-notification in i3-nagbar & i3-config-wizard
2018-08-27 11:19:26 +02:00
Orestis Floros
bf1cb39b4b Support startup-notification in i3-nagbar & i3-config-wizard
The default i3 config uses the `exec` command without `--no-startup-id`
to launch:
1. i3-nagbar
4cba9fcbda/etc/config (L150)
2. i3-config-wizard
4cba9fcbda/etc/config (L194)

A user that opens i3 for the first time will be greeted with a "loading"
cursor because of i3-config-wizard.
2018-08-25 14:54:16 +03:00
Orestis Floros
a8b90317a0 i3-config-wizard: fix small memleak 2018-08-25 14:54:16 +03:00
Ingo Bürk
4cba9fcbda Merge pull request #3368 from orestisf1993/render_root
(floating) global fullscreen bugs & others
2018-08-24 09:49:41 +02:00
Ingo Bürk
9a53d65e18 Merge pull request #3372 from orestisf1993/direction
Resize tile px
2018-08-24 09:43:20 +02:00
Orestis Floros
096cff0aad Make resize set ppt more accurate
See the testcase for the usecase.
2018-08-24 04:13:25 +03:00
Orestis Floros
51d230ad4c Make resize set px work with tiling containers 2018-08-24 04:13:25 +03:00
Orestis Floros
f28c50b631 541-resize-set-tiling.t: fix "my" variable mask warnings 2018-08-24 04:13:25 +03:00
Orestis Floros
423e20b960 cmd_resize* statics: remove useless 'way' argument 2018-08-24 04:13:25 +03:00
Orestis Floros
26bbaf6237 Make cmd_resize_tiling_width_height work with pixels 2018-08-24 04:13:25 +03:00
Orestis Floros
2ead7745d6 Make cmd_resize_tiling_direction work with pixels
Introduces resize_neighboring_cons in resize.c which is also used by
resize_graphical_handler.

Co-authored-by: Andrew Laucius <andrewla@gmail.com>
Authored original code and tests in #3240. I rewrote most of the
resizing code and fixed the failing tests.
2018-08-24 04:13:03 +03:00
Orestis Floros
ea43507bed precalculate_sizes: don't malloc needlessly 2018-08-24 04:12:24 +03:00
Orestis Floros
7b9318a541 precalculate_sizes: round sizes instead of flooring them
This will lead to more accurate and consistent container sizes.

Needed to fix the failing test of #3240.
2018-08-24 04:12:14 +03:00
Orestis Floros
db294f4505 Improve resize_graphical_handler code style
- int return type is not useful
- Consistent comment style
2018-08-23 22:04:22 +03:00
Orestis Floros
9522b46f1b Introduce parse_direction
Also fixes the following bug: in the fix for #1011 in
cmd_resize_floating direction "width" is not considered.

Influenced by #3240.
2018-08-23 15:45:24 +03:00
Orestis Floros
6e1b79e057 Introduce orientation_from_direction 2018-08-23 15:36:23 +03:00
Ingo Bürk
72cc719c5d Merge pull request #3369 from orestisf1993/clang-format
Apply compatible changes from clang-format 6.0.1
2018-08-22 20:29:32 +02:00
Orestis Floros
e6202d43f5 Apply compatible changes from clang-format 6.0.1
These are the changes that clang-format 6.0.1 makes to the codebase that
clang-format-3.8 doesn't change back.

Useful for those that use a more recent version of clang-format in their
local machines.
2018-08-22 14:51:17 +03:00
Orestis Floros
e1a83d057f handle_configure_request: check for scratchpad once 2018-08-22 14:23:01 +03:00
Orestis Floros
9190a9ab70 handle_configure_request: use 'goto out' 2018-08-22 14:11:26 +03:00
Orestis Floros
9ae84593ba handle_configure_request: reuse 'workspace' variable 2018-08-22 14:10:42 +03:00
Orestis Floros
0ac75bea5a con_border_style: check con->fullscreen_mode directly 2018-08-22 14:09:05 +03:00
Orestis Floros
efc78de4ee Introduce con_get_fullscreen_covering_ws
This commit will also fix the following bugs:
1. click.c: Users could drag global fullscreen floating containers.
2. render.c: Floating containers would get rendered with a global fullscreen container in another
workspace.
2018-08-22 14:05:50 +03:00
Orestis Floros
b3e69ed12a render_root: fix popup_during_fullscreen logic
The first issue is that there seems to be a typo: fullscreen->window
should have been child->window. The corrected check is redundant since
the while loop checks if the transient_con has a window.

The second issue is that popup_during_fullscreen is never checked even
though the behaviour should be exclusive to the "smart" option.
2018-08-22 03:45:35 +03:00
Ingo Bürk
2f3c8b6484 Merge pull request #3365 from orestisf1993/DRAG_REVERT
floating_drag_window: return on DRAG_REVERT
2018-08-21 20:39:26 +02:00
Ingo Bürk
e906cdad66 Merge pull request #3366 from orestisf1993/NUM_HANDLERS
property_notify: use NUM_HANDLERS
2018-08-21 20:38:31 +02:00
Ingo Bürk
6d3fc089f9 Merge pull request #3367 from orestisf1993/dragloop_callback
Call dragloop callback on DRAG_SUCCESS
2018-08-21 20:37:56 +02:00
Orestis Floros
2c78f2458c Call dragloop callback on DRAG_SUCCESS
A race condition is possible. For example, if we first receive a
XCB_MOTION_NOTIFY event and then, while drain_drag_events is still
running, a XCB_BUTTON_RELEASE event the first event is never handled
because we return.

This fixes the flakiness of the tests in #3085.
2018-08-21 21:19:57 +03:00
Orestis Floros
5d89bd344f floating_drag_window: return on DRAG_REVERT
Right now tree_render() is called twice on DRAG_REVERT since
floating_reposition calls it.
Also, on DRAG_REVERT the scratchpad state shouldn't change since the
user canceled the action.
2018-08-21 21:06:00 +03:00
Orestis Floros
b1aa2fb1c4 property_notify: use NUM_HANDLERS 2018-08-21 21:04:46 +03:00
Ingo Bürk
e8dee4308a Merge pull request #3364 from orestisf1993/warp-randr_query
randr_query_outputs: con_activate -> workspace_show
2018-08-17 11:55:15 +02:00
Orestis Floros
789a09a6e7 Use con_focus instead of con_activate for workspace 2018-08-17 12:49:34 +03:00
Orestis Floros
ba29290123 Typo: output -> content 2018-08-17 12:49:34 +03:00
Orestis Floros
7010644964 randr_query_outputs: con_activate -> workspace_show
workspace_show will call x_set_warp_to if needed.

Fixes #3333
2018-08-17 12:49:15 +03:00
Ingo Bürk
2d3c2f0615 Merge pull request #3363 from orestisf1993/regress-scratchpad-focus
Call con_activate after moving scratchpad window to current ws
2018-08-17 11:42:29 +02:00
Orestis Floros
cac28b69d4 Call con_activate after moving scratchpad window to current ws
Fixes #3361
2018-08-17 12:34:20 +03:00
Ingo Bürk
4b3ff9cdd4 Merge pull request #3353 from orestisf1993/free_ws_assignments
Free ws_assignments on reload
2018-08-09 16:49:21 +02:00
Orestis Floros
01e971b51e Free ws_assignments on reload
This fixes an unreported bug where deleting a workspace assignment and
reloading the config file would keep the assignment.
2018-08-09 17:28:05 +03:00
Michael Stapelberg
5a54a1ab04 Merge pull request #3263 from orestisf1993/misbehaving-ipc-queue-2999
Kill misbehaving subscribed clients instead of hanging
2018-08-08 19:14:15 +02:00
Orestis Floros
37d0105c83 Kill misbehaving subscribed clients instead of hanging
This change only affects clients that are subscribed to events, which
should be the main cause of our problems.

In the common case (no buffered data) the behaviour doesn't change at
all: the message is sent directly, no ev_io / ev_timeout callback is
enabled. Once a write to a client's socket is not completed fully
(returns with EAGAIN error), we put the message in the tail of a queue
and init an ev_io callback and a corresponding timer. If the timer is
triggered first, the socket is closed and the client connection is
removed. If the socket becomes writeable before the timeout we either
reset the timer if we couldn't push all the buffered data or completely
remove it if everything was pushed.

We could also replace ipc_send_message() for all client connections in
i3, not just those subscribed to events.

Furthermore, we could limit the amount of messages stored and increase
the timeout (or use multiple timeouts): eg it's ok if a client is not
reading for 10 seconds and we are only holding 5KB of messages for them
but it is not ok if they are inactive for 5 seconds and we have 30MB of
messages held.

Closes #2999
Closes #2539
2018-08-08 19:14:56 +03:00
Harry Lawrence
3ea3935e6a Added libiconv to search libs for OpenBSD patch (#3336) 2018-08-04 18:27:25 +01:00
Ingo Bürk
65eb54c0ba Merge pull request #3319 from Stunkymonkey/format_placholders-case_sensitive
make format_placeholders case-sensitive
2018-08-04 09:23:11 +02:00
Ingo Bürk
d47b841f1a Merge pull request #3344 from downzer0/chore/i3-sensible-terminal--hyper
enhancement: adds hyper as a sensible terminal option
2018-08-02 17:05:29 +02:00
downzer0
42c5feb22f enhancement: adds hyper as a sensible terminal option
- hyper.is
2018-08-01 08:21:44 -05:00
Orestis Floros
b0bbe53d04 Introduce free_ipc_client 2018-07-31 14:39:07 +03:00
Orestis Floros
f908403376 Simplify tree_close_internal
This commit makes multiple changes in tree_close_internal. I didn't
split them because they are not completely independent.

- Remove force_set_focus parameter
This parameter was always set to `false` throughout the code base except
for one case where it was set to `(con == focused)`, when killing a
floating con's parent (the one with type CT_FLOATING_CON). But this case
is not needed anymore since the special handling of CT_FLOATING_CONs in
con_next_focused was removed in #2941.
- Assume that con_next_focused does not returned a container of type
CT_DOCKAREA. This is reasonable since con_next_focused uses the
focus_head stack and has special handling of CT_DOCKAREA containers.
- Remove is_mapped
This variable was only used in the if block towards the end of
tree_close_internal. Ignoring the, now removed, dockarea code and the
use of force_set_focus this block performed only one useful action:
focus the `next` container when `con == focused`. `con == focused` was a
necessary and sufficient condition for the con_activate call:
if `con != focused` we could reach the inner if blocks because of the
other conditions but would never focus another container. If `con ==
focused` then all other conditions would be irrelevant.
- Remove special handling of floating containers
Since the `next` focused container is calculated through the parent for
floating containers, I moved this code to con_next_focused.
Also, because of the removal of force_set_focus, it appears that we can
call con_on_remove_child for floating containers as well.
2018-07-30 19:41:24 +03:00
Ingo Bürk
715cea61af Merge pull request #3340 from PandorasFox/next
fix height offset calculation in pango text drawing
2018-07-29 12:10:26 +02:00
Cassandra Fox
ad236dbaec fix height offset calculation in pango text drawing 2018-07-28 19:31:32 -07:00
Ingo Bürk
d7022c7011 Merge pull request #3329 from lasers/next
docs/i3bar-protocol: fix typo
2018-07-16 16:11:04 +02:00
lasers
809eea2630 docs/i3bar-protocol: fix typo 2018-07-16 08:54:08 -05:00
Ingo Bürk
a1351138d1 Merge pull request #3254 from orestisf1993/issue-555
Multiple assignments of workspaces to outputs (#555)
2018-07-12 16:18:13 +02:00
Orestis Floros
bce088679a Allow multiple assignments of workspaces to outputs
Also makes get_assigned_output work with the primary output:
    workspace X output primary
will now work.

Fixes #555.
2018-07-12 17:07:01 +03:00
Ingo Bürk
dbf4e1b95d Merge pull request #3327 from orestisf1993/rename-mouse-bug
cmd_rename_workspace: always call con_focus
2018-07-12 06:27:56 +02:00
Ingo Bürk
4808334b66 Merge pull request #3328 from orestisf1993/next
Fix ISSUE_TEMPLATE typo
2018-07-12 06:27:13 +02:00
Orestis Floros
4cd223f80a Fix ISSUE_TEMPLATE typo 2018-07-12 03:49:07 +03:00
Orestis Floros
d1652ca7cd cmd_rename_workspace: always call con_focus
This was introduced in 252db3b8c (#3245). That commit moved the
con_activate line inside the loop, meaning it wouldn't always be called.

When the mouse moved after a rename with focus_follows_mouse enabled,
check_crossing_screen_boundary (src/handlers.c:111) called
con_descend_focused that used the wrong focus order.

I also change con_activate to con_focus since we don't really want to
raise floating containers there.

Fixes #3325
2018-07-12 03:42:38 +03:00
Felix Buehler
37ea56c221 make format_placeholders case-sensitive 2018-07-10 23:24:50 +02:00
Ingo Bürk
b8505bb611 Merge pull request #3324 from orestisf1993/xdg_config
Correct XDG paths precedence for config files
2018-07-10 08:23:32 +02:00
Orestis Floros
fd70ea6b31 Correct XDG paths precedence for config files
Fixes #3323
2018-07-10 05:04:34 +03:00
Orestis Floros
d525eb80ae Use get_assigned_output for numbers
This prohibits the usage of workspaces assigned to other outputs in
create_workspace_on_output.

Eg, with config:
    workspace 1 output fake-0
    workspace 2 output fake-0
and 2 screens workspace 2 would be used for the second screen even
though it is assigned to the first one.

Also introduces a test for workspace assignments that includes the case
described above and some tests that don't fail in the next branch.
2018-06-27 14:56:50 +03:00
Orestis Floros
1d5b43c18f Move get_output_for_workspace() to i3test 2018-06-27 14:56:50 +03:00
Orestis Floros
bc439de755 Introduce get_assigned_output
This also replaces code in create_workspace_on_output() that is
theoretically more efficient but:
1. It isn't a huge difference since it depends on the number of outputs,
that shouldn't be high.
2. get_assigned_output will be modified and used for #555, then its
logic should be followed in create_workspace_on_output() too.

Another note for create_workspace_on_output: if assigned is not NULL the
condition (assigned != output->con) should never be false, ie if there
is an assigned output to this name, it isn't the current one. This
happens because the current callers check for assignments before calling
create_workspace_on_output().
2018-06-27 14:56:31 +03:00
Ingo Bürk
6339427f01 Merge pull request #3179 from orestisf1993/issue-2733
Correctly handle bindings for the same key with and without --release
2018-06-22 14:39:02 +02:00
Ingo Bürk
d8bb8273da Merge pull request #3313 from czak/fix-border-artifacts
Border artifacts when moving window
2018-06-22 13:48:15 +02:00
Łukasz Adamczak
606050a700 Consider rect changed when its position changes 2018-06-22 12:34:11 +02:00
Ingo Bürk
6c34063f95 Merge pull request #3309 from orestisf1993/detectable-autorepeat
Enable detectable autorepeat
2018-06-20 08:38:46 +02:00
Ingo Bürk
8bd31842e1 Merge pull request #3310 from KJoke70/patch-1
Update i3-msg.man: added get_config and send_tick
2018-06-15 14:55:49 +02:00
Martin
5debba0d1c Update i3-msg.man: added get_config and send_tick
Added get_config and send_tick which are mentioned [here](https://i3wm.org/docs/ipc.html).
2018-06-15 14:37:14 +02:00
Orestis Floros
b87bc70cd6 Enable detectable autorepeat
https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat

Detectable autorepeat should only affect --release bindings. Currently,
when a user keeps a key pressed, we get multiple KeyPress and KeyRelease
events. With this change, we still get multiple KeyPress events, which
means that you can still keep a key pressed to repeatedly execute a
normal binding, but only one KeyRelease event when the key is physically
released.

Unfortunately, this change is not currently testable because detectable
autorepeat doesn't seem to work under Xephyr. AwesomeWM experienced the
same problem:
6f2424e901

Fixes #3306
2018-06-15 13:56:31 +03:00
Ingo Bürk
997459a1db Merge pull request #3307 from orestisf1993/link
Fix link
2018-06-07 22:52:05 +02:00
Orestis Floros
5ab8c766c4 Fix link
Equivalent from the same version:
https://cgit.freedesktop.org/xorg/xserver/tree/xkb/xkbEvents.c?h=xorg-server-1.17.2#n927
2018-06-07 23:07:16 +03:00
Ingo Bürk
00a8a91c00 Merge pull request #3303 from orestisf1993/back_and_forth
docs: link workspace_auto_back_and_forth from workspace command
2018-06-02 17:17:15 +02:00
Orestis Floros
97536f04df docs: link workspace_auto_back_and_forth from workspace command
The current text is confusing. '--no-auto-back-and-forth' doesn't
disable the 'workspace back_and_forth' command, the flag is not even
valid for that command.
2018-06-02 18:03:34 +03:00
Ingo Bürk
05a1dc0f6e Merge pull request #3301 from Streetwalrus/swallow-reframe
Reframe swallowed windows if depth doesn't match
2018-06-02 14:51:18 +02:00
Dan Elkouby
7ac37d8ae4 Reframe swallowed windows if depth doesn't match
X will not allow a window with ParentRelative background to be created
or reparented under a window with mismatching color depth.
Deal with this by destroying the container frame and creating a new one
with the right depth upon swallowing.
Defer destruction of the frame window until after the updated tree has
been rendered to avoid some distracting flickering.

Fixes #3297
2018-06-02 14:32:47 +03:00
Ingo Bürk
26f50898fd Updated ISSUE_TEMPLATE.md (#3295) 2018-05-20 16:51:26 +02:00
Ingo Bürk
ef378d87b6 Merge pull request #3282 from orestisf1993/strncpy-to-memcpy
Replace strncpy call with memcpy when result is not NUL-terminated
2018-05-09 14:34:00 +02:00
Orestis Floros
f4981f97bc Replace strncpy call with memcpy when result is not NUL-terminated
This fixes a new warning from GCC 8.1, -Wstringop-truncation:
https://gcc.gnu.org/gcc-8/changes.html
https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Warning-Options.html#index-Wstringop-truncation

Replacing with memcpy is what gcc suggests:
> As another example, the following call to strncpy results in copying
> to d just the characters preceding the terminating NUL, without
> appending the NUL to the end. Assuming the result of strncpy is
> necessarily a NUL-terminated string is a common mistake, and so the
> call is diagnosed. To avoid the warning when the result is not
> expected to be NUL-terminated, call memcpy instead.
>    void copy (char *d, const char *s)
>    {
>      strncpy (d, s, strlen (s));
>    }
2018-05-08 17:05:46 +03:00
Orestis
1cdb1ab721 Merge pull request #3279 from Streetwalrus/next
Activate the focused child when scrolling over tab/stack decorations
2018-05-05 13:49:13 +03:00
Dan Elkouby
94bc401680 Activate the focused child when scrolling over tab/stack decorations
fbce834b introduced a bug where scrolling over the decoration while
another container is focused would not focus the tabbed/stacked
container itself, but would instead move focus through the currently
focused container.
2018-05-05 13:30:48 +03:00
Ingo Bürk
d302af2312 Merge pull request #3272 from orestisf1993/fake-outputs
Fix: ConfigureNotify can crash i3 with fake-outputs
2018-05-04 21:58:01 +02:00
Ingo Bürk
ae9e2dd86f Merge pull request #3277 from orestisf1993/resize-set
Resize set improvements
2018-05-04 21:57:12 +02:00
Orestis Floros
c50bf50f09 resize set: accept 'width' and 'height' keywords
Fixes #3275
2018-05-02 19:02:38 +03:00
Orestis Floros
b901fc9464 resize set for floating: interpret 0 as 'no change'
Fixes #3276
2018-05-02 19:02:38 +03:00
Orestis Floros
64b8b4b766 252-floating-size.t: Reduce code duplication 2018-05-02 18:12:10 +03:00
Ingo Bürk
981e901b79 Merge pull request #3274 from orestisf1993/DEPENDS
Fix DEPENDS table
2018-05-01 19:13:08 +02:00
Orestis Floros
37e3663c77 Fix DEPENDS table
- Align right border
- Add a missing '/' in libsn's and util-xrm's link for consistency
- Replace wrong character for border next to pango's min version
- Correct the Pod::Simple link
2018-05-01 13:49:55 +03:00
Oliver Graff
252db3b8cf Don't refocus a workspace cleaned up by workspace_show during rename
When moving a workspace to the current output by way of a rename, if the
current workspace is empty, it will be removed by `workspace_show`.
Attempting to restore focus to this removed workspace causes a crash.
Follow the pattern in workspace.c:996 to only restore the original focus if the
original workspace still exists.

Add a test to ensure that the renamed workspace moves to its appropriate
output and that a crash does not occur.

Fixes #3228
2018-05-01 11:25:13 +03:00
Ingo Bürk
e8057b2fbc Merge pull request #3270 from orestisf1993/ADD_TRANSLATED_KEY
Define ADD_TRANSLATED_KEY once
2018-04-30 10:02:34 +02:00
Orestis Floros
1f74f8d2c1 Fix: ConfigureNotify can crash i3 with fake-outputs
handle_screen_change() and handle_configure_notify() call
randr_query_outputs() where root_output is not initialized because
randr_init() is never called when config.fake_outputs is not NULL.
2018-04-30 03:54:38 +03:00
Orestis
6f11b6fa4a send_tick: set "first" field (#3271)
According to the docs, the tick event should return:
    {
     "first": false,
     "payload": "arbitrary string"
    }
2018-04-28 14:47:28 +02:00
Orestis Floros
1681ab4496 Define ADD_TRANSLATED_KEY once 2018-04-28 12:21:39 +03:00
Ingo Bürk
5813525c62 Merge pull request #3268 from orestisf1993/janitorial
Janitorial
2018-04-27 11:14:45 +02:00
Ingo Bürk
19596981a0 Merge pull request #3267 from orestisf1993/cmd_shmlog
cmd_shmlog: use parse_long()
2018-04-27 08:38:29 +02:00
Orestis Floros
16f8fe28d9 main.c: remove redundant 'focused' declaration
Previously declared in tree.h:17.
2018-04-27 01:16:42 +03:00
Orestis Floros
0b5a2092a0 Fix redundant casts to the same type
Found using clang-tidy's google-readability-casting.
2018-04-27 00:09:42 +03:00
Orestis Floros
aca7790217 Fix redundant return statements
… at the end of a function with a void return type.

Found using clang-tidy's readability-redundant-control-flow.
2018-04-27 00:09:42 +03:00
Orestis Floros
2f2053284e cmd_shmlog: use parse_long() 2018-04-26 23:47:45 +03:00
Ingo Bürk
55dd5b8d84 Merge pull request #3261 from orestisf1993/swap-3259
Don't call con_fullscreen_permits_focusing with ignore_focus
2018-04-22 16:35:25 +02:00
Orestis Floros
b5f887287a Don't call con_fullscreen_permits_focusing with ignore_focus
When we don't modify the focus we aren't risking giving focus to a
container behind the current fullscreen one.

_con_move_to_con can with ignore_focus is called through the swap
command or through con_move_to_workspace for floating containers. This
change shouldn't break the expectations of the callers there.

Fixes issue #3259.
2018-04-22 16:56:36 +03:00
Orestis Floros
799e3951a2 con_swap: exit when first _con_move_to_con fails
This is enough to fix the crash discussed in #3259 even though the next
commit can fix it independently. This commit is useful because it
generally makes sense to abort the command when the first call to
_con_move_to_con fails.
2018-04-22 03:48:50 +03:00
Ingo Bürk
5a0f02b7ff Merge pull request #3230 from hwangcc23/fix-3227
Make "scratchpad show" return correct info
2018-04-21 17:57:54 +02:00
Ingo Bürk
53648511b3 Merge pull request #3256 from orestisf1993/REQUIRED_OPTION
Remove obsolete macro REQUIRED_OPTION
2018-04-21 17:56:06 +02:00
Ingo Bürk
4b95e2c1e0 Merge pull request #3260 from orestisf1993/cmd_border
cmd_border: improve width selection
2018-04-21 17:55:51 +02:00
Orestis Floros
bd7a5ee48a cmd_border: improve width selection
- 'border toggle' now accepts an optional pixel argument which will be
ignored when switching to BS_NONE.
- 'border pixel' now defaults to 1 pixel instead of 2.
- Calling 'border normal' or 'border pixel' will use the configured
default_border_width if one exists. Also applies to floating windows.
2018-04-21 16:50:57 +03:00
hwangcc23
4869becfee Make "scratchpad show" return correct info
Fix the issue #3227(https://github.com/i3/i3/issues/3227).

1).Make cmd_scratchpad_show() use the information coming from scratchpad_show().
2).Add a test case 298-scratchpad-show.t.
2018-04-20 22:30:41 +08:00
Orestis Floros
8fba543719 Remove obsolete macro REQUIRED_OPTION
Was used for the removed option 'terminal' and for 'font'. 'font' is no
longer this aggressive and doesn't use the macro.

Killing i3 when an option is missing would be super backwards
incompatible so I doubt we are going to use this ever again.
2018-04-20 13:05:23 +03:00
Ingo Bürk
a40bcef438 Merge pull request #3255 from orestisf1993/FOR_TABLE
Remove obsolete macro FOR_TABLE
2018-04-20 05:30:51 +02:00
Orestis Floros
0254228861 Remove obsolete macro FOR_TABLE
Was added in 38c8541807, should have been
removed in c145f7e529.
2018-04-20 06:13:40 +03:00
Orestis
ff543b8b56 Merge pull request #3253 from stapelberg/sync
Makefile.am: add forgotten include/sync.h
2018-04-19 21:20:44 +03:00
Michael Stapelberg
0c3f5f343c Makefile.am: add forgotten include/sync.h 2018-04-19 20:10:54 +02:00
Ingo Bürk
26ba03930f Merge pull request #3250 from rtgnx/next
docs/ipc: update tree node with window_properties
2018-04-18 22:30:22 +02:00
Adrian Cybulski
7381ae3e20 docs/ipc: update tree node with window_properties 2018-04-18 12:11:07 +01:00
Ingo Bürk
3c66f615e2 Merge pull request #3246 from orestisf1993/bar-modifier-3234
i3bar: make modifier behave like floating_modifier
2018-04-17 13:13:18 +02:00
Orestis Floros
fe6b3b7474 i3bar: make modifier behave like floating_modifier
Pressed modifiers are determined like in click.c:handle_button_press.

Fixes #3234.
2018-04-17 02:00:03 +03:00
Ingo Bürk
67a60a9454 Merge pull request #3244 from orestisf1993/issue-3220
i3bar: don't reset verbosity when parsing config values
2018-04-16 11:59:49 +02:00
Orestis Floros
0a72f2d535 i3bar: don't reset verbosity when parsing config values
When i3bar is called with the -V flag but there is no 'verbose yes'
directive in the bar {} config, the verbosity config value is reset.

This will introduce the opposite, negligible issue: you can't disable
i3bar's verbosity by deleting the 'verbose yes' directive in the bar {}
config. To fix this we would need an enum for config.verbose.

Closes #3220.
2018-04-16 01:37:18 +03:00
Ingo Bürk
ab47d664c2 Merge pull request #3243 from avindra/next
man: Fix title markers
2018-04-15 21:43:52 +02:00
Takashi Iwai
1f551052de man: Fix title markers
The title marker lines have to be aligned with the previous lines.
The error was caught by asciidoctor, which tends to be picker than
asciidoc.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
2018-04-15 15:34:40 -04:00
Ingo Bürk
1e5aaa2d10 Merge pull request #3236 from hwangcc23/fix-3220
Add an i3bar flag: --verbose
2018-04-14 14:39:54 +02:00
hwangcc23
e26fd91cf8 Add an i3bar flag: --verbose
Fix the issue #3220. (https://github.com/i3/i3/issues/3220)
2018-04-13 23:09:44 +08:00
Ingo Bürk
b688164235 Merge pull request #3231 from orestisf1993/target-is-a-workspace
Fix crash when moving container to marked workspace
2018-04-07 21:13:41 +02:00
Orestis Floros
626af81232 Fix crash when moving container to marked workspace
Was a small typo.

This also has the (positive) side-effect of allowing to move all the
content of a marked workspace next to the target container, see added
tests.
2018-04-07 21:58:55 +03:00
Ingo Bürk
a92acadfc0 Merge pull request #3223 from orestisf1993/minor
Minor changes
2018-04-05 10:59:34 +02:00
Orestis
bfe047e8bc Merge pull request #3221 from ograff/issue-3208
Issue #3208
2018-04-05 11:32:38 +03:00
Oliver Graff
e4a184e77e Workspace renaming: Interpret outputs as nondirectional
Currently when renaming outputs, an output assignment of "left" will
cause the workspace to move left. Treat this assignment as a proper name
instead (even though it is unlikely an output will be named "left").

Move logic for determining output to move to out of
`workspace_move_to_output`

Add test for ignoring direcionality during rename.

Fixes #3208.
2018-04-04 13:37:59 -04:00
Orestis Floros
0aa636b207 Prefer compiler warnings to assertions for unhandled switch cases
Using 'default:' cases can hide logical errors which would lead to i3
crashes for users. With this change the compiler will print a warning
when a case is not handled. For example, if I add a new value in the
Font.type enum:
../../i3/libi3/font.c: In function ‘draw_text’:
../../i3/libi3/font.c:378:5: warning: enumeration value ‘NEWFONT’ not handled in switch [-Wswitch]
     switch (savedFont->type) {
     ^~~~~~
2018-04-04 19:20:55 +03:00
Orestis Floros
393412a204 A__NET_REQUEST_FRAME_EXTENTS: use render_font_height() 2018-04-04 18:09:34 +03:00
Ingo Bürk
bc760c2036 Merge pull request #3215 from orestisf1993/focus-next-prev
Small window decoration scrolling bugfix
2018-04-03 20:42:00 +02:00
Orestis Floros
96ee336a0b Use con_orientation instead of ternary operator 2018-04-01 12:18:27 +03:00
Orestis Floros
fbce834b20 Window decoration scrolling: don't focus sibling
The current behaviour is buggy in the following layout:
T [ A* V [ B C ] ], where the focus stack in V is B > C.
When the user scrolls down, focus correctly moves to B but if the user
scrolls down again the whole vertical container is focused.

This happens because 'bool scroll_next_possible' is false but
con_activate is called on the tabbed container's sibling - the vertical
container.
2018-04-01 12:18:27 +03:00
Ingo Bürk
666aa9e0dd Merge pull request #2941 from orestisf1993/issue-2938
Fix focus order in floating_disable & floating_enable for unfocused windows
2018-03-31 20:34:17 +02:00
Ingo Bürk
8a805cdd5c Merge pull request #3214 from stapelberg/sync
unflake t/525-i3bar-mouse-bindings.t
2018-03-30 21:33:03 +02:00
Michael Stapelberg
874151bb09 t/525-i3bar-mouse-bindings.t: sync with i3 _and_ i3bar
See the comment in the code for rationale.
2018-03-30 21:14:53 +02:00
Michael Stapelberg
145ac532aa i3bar: forward the sync request via IPC, not X11
i3bar’s X11 output is not what our testcases are testing — the state
manipulations which i3bar triggers via IPC messages to i3 are what we are
interested in.
2018-03-30 21:14:51 +02:00
Michael Stapelberg
eca8fae2de introduce the sync IPC command
Sending the sync command via IPC ensures pending IPC messages are handled by i3
before the sync response is read. This is rarely useful for direct IPC
connections to i3, but becomes useful when synchronizing with i3bar, which might
have pending IPC messages in response to button clicks.
2018-03-30 21:09:52 +02:00
Michael Stapelberg
725ee3ce62 move i3 sync code into sync_respond (for following commits) 2018-03-30 21:05:32 +02:00
Orestis Floros
791e407fd3 Remove special handling of floating containers in con_next_focused
Explanation for the changed test:
After $third is switched to floating, the test moves focus to $second.
So, the parent of $second (the stacked container) is above $third in the
focus stack and it's children ($first, $second) should get focused
before $second. When $second is switched to floating the correct focus
order for the workspace should be $second->parent (floating con is the
parent) > $first->parent (stacked con) > $third.

Fixes #1975
2018-03-30 18:29:33 +03:00
Orestis Floros
2c6da57e81 Add testcases for toggling floating windows from different workspaces 2018-03-30 18:29:33 +03:00
Orestis Floros
3a89f88fb6 Fix focus order in floating_enable for unfocused windows
Partially fixes issue #2938
2018-03-30 18:29:32 +03:00
Orestis Floros
10a3c1e827 Fix focus order in floating_disable for unfocused windows
Partially fixes issue #2938
2018-03-30 18:20:40 +03:00
Orestis Floros
60875c7bcb Use con_detach instead of TAILQ_REMOVE in floating 2018-03-30 18:20:40 +03:00
Joona
4e0bf58109 Add --modifier flag to i3-config-wizard (#3210)
Add --modifier flag to i3-config-wizard

The --modifier flag accepts either alt or win, and will generate the
configuration file without opening a window.

Also adds i3-config-wizard's flags to the manpage.

Fixes #3136.
2018-03-30 13:57:41 +03:00
Ingo Bürk
63133c878f Merge pull request #3213 from orestisf1993/issue-2535
Fix memory leak when _XKB_RULES_NAMES can't be found
2018-03-30 12:48:12 +02:00
Orestis Floros
4143f3abfc Fix memory leak when _XKB_RULES_NAMES can't be found
Steps to reproduce:

1. Force the branch to be taken:

diff --git a/src/bindings.c b/src/bindings.c
index fe77bc8f..caa5848c 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -941,7 +941,7 @@ bool load_keymap(void) {

     struct xkb_keymap *new_keymap = NULL;
     int32_t device_id;
-    if (xkb_supported && (device_id = xkb_x11_get_core_keyboard_device_id(conn)) > -1) {
+    if (0) {
         if ((new_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0)) == NULL) {
             ELOG("xkb_x11_keymap_new_from_device failed\n");
             return false;

2. Run `python2 ./xproperty.py _XKB_RULES_NAMES ''` (from
https://github.com/siemer/xproperty) in the xinitrc
3. Memory sanitizers detect memory leaks.

Note: We don't (and didn't) pass NULL in xkb_keymap_new_from_names() but
an xkb_rule_names structures with NULL fields (fill_rmlvo_from_root only
fills its argument when there are no errors) should be equivalent:
767fa86d42/NEWS (L349-L351)
> The function xkb_keymap_new_from_names() now accepts a NULL value for
the 'names' parameter, instead of failing. This is equivalent to passing
a 'struct xkb_rule_names' with all fields set to NULL.

Fixes #2535.
2018-03-29 17:46:41 +03:00
Ingo Bürk
77bfa595df Merge pull request #3200 from orestisf1993/_con_move_to_con
_con_move_to_con: don't change focus when moving to active workspace
2018-03-29 12:06:29 +02:00
Ingo Bürk
145a93d5b4 Merge pull request #3207 from orestisf1993/get_workspace_by_
Introduce get_workspace_by_* functions
2018-03-29 12:06:05 +02:00
Orestis
6dfa348960 Merge pull request #3192 from Exagone313/next
translate_keysyms: fix potential memory leak
2018-03-29 12:16:12 +03:00
Orestis Floros
0b5799412a Introduce get_existing_workspace_by_num 2018-03-28 15:18:43 +03:00
Orestis Floros
6a2728ba79 Introduce get_existing_workspace_by_name 2018-03-28 15:18:43 +03:00
Orestis Floros
6d983b5ee0 _con_move_to_con: don't change focus when moving to active workspace
Seems to be the intention, indicated by this comment (con.c:1307-1309):
    /* For split containers, we use the currently focused container within it.
     * This allows setting marks on, e.g., tabbed containers which will move
     * con to a new tab behind the focused tab. */

Related to #3085.
2018-03-28 15:10:11 +03:00
Elouan Martinet
e6bd2006bc Fix potential memory leak
xkb_state_new uses calloc and may fail in a rare case, which would cause a memory leak.
Note that xkb_state_unref checks if the parameter given is not null (!state) before freeing.
Calls to xkb_state_new have been grouped to remove code duplication.

Signed-off-by: Elouan Martinet <exa@elou.world>
2018-03-27 10:23:16 +00:00
Ingo Bürk
45be56be33 Merge pull request #3205 from orestisf1993/free
cmd_append_layout: resolve_tilde already allocates memory
2018-03-27 09:02:28 +02:00
Orestis Floros
e424a31307 cmd_append_layout: resolve_tilde already allocates memory
Fixes a small memory leak with all append_layout commands.
2018-03-27 03:37:57 +03:00
Ingo Bürk
6f4b0e1fdd Merge pull request #3204 from orestisf1993/focus_next
_con_move_to_con: focus_next isn't always con_next_focused(con)
2018-03-26 21:35:12 +02:00
Orestis
a0309cbd52 xcb_drag_prepare_cb: drain events (#3193)
As discussed in PR #3085, X11 events can appear while
dragloop->callback() is running.

Co-authored-by: Michael Stapelberg <michael@stapelberg.de>
2018-03-26 17:59:34 +02:00
Orestis Floros
c7dde08673 _con_move_to_con: focus_next isn't always con_next_focused(con)
con_next_focused uses con's parent. But since con can be inside an
unfocused container this means that one of it's siblings could become
focused in the current workspace.
2018-03-26 00:09:26 +03:00
Ingo Bürk
f560519f5c Merge pull request #3203 from orestisf1993/free
memory leaks
2018-03-25 20:12:16 +02:00
Orestis Floros
b0997234ab con_toggle_layout: free(tm_dup) outside loop 2018-03-25 20:48:20 +03:00
Orestis Floros
e19a120961 Free A_TO_WORKSPACE_NUMBER assignments 2018-03-25 20:35:53 +03:00
Orestis Floros
a5014dc7f8 cfg_workspace: memleak on duplicate workspace assignment
assignment->output is set but lost since TAILQ_INSERT_TAIL is never
called when duplicate is set.
This essentially happens on every reload.
2018-03-25 20:27:07 +03:00
Orestis Floros
ee1f551195 startup.c: free timer
Small memleak. The timer is not called used again since ev_timer_init is
called with repeat = 0.
2018-03-25 20:04:31 +03:00
Ingo Bürk
6c3533b615 Merge pull request #3202 from orestisf1993/issue-3201
Prefer fullscreen floating containers when on directional focus
2018-03-25 14:31:39 +02:00
Orestis Floros
37106aa84b Prefer fullscreen floating containers when on directional focus
Fixes #3201
2018-03-25 14:47:45 +03:00
Ingo Bürk
b849fe3e44 Merge pull request #3196 from orestisf1993/_con_move_to_con
_con_move_to_con cleanup
2018-03-24 18:49:26 +01:00
Ingo Bürk
16a707cd19 Merge pull request #3199 from orestisf1993/workspace_show
workspace_show: remove redundant if
2018-03-24 18:39:37 +01:00
Orestis Floros
9e3b48dd22 con_activate -> con_focus when it is used as a building block 2018-03-24 15:21:11 +02:00
Orestis Floros
9a1fcff4e0 _con_move_to_con: remove outdated comment 2018-03-24 15:21:11 +02:00
Orestis Floros
037b1c3710 _con_move_to_con: showing target_ws is useless
The current_ws is shown latter anyway:
    if (!ignore_focus) {
        workspace_show(current_ws);
        ...

This also causes the following bug:
- Open a window in an empty workspace
- Switch to another workspace
- seturgent to the first window
- Move another window to the first workspace
- Urgent flag is now reset
2018-03-24 15:19:49 +02:00
Orestis Floros
f46bb0396e workspace_show: remove redundant if 2018-03-24 15:15:02 +02:00
Ingo Bürk
a41912430a Merge pull request #3198 from orestisf1993/_workspace_show
_workspace_show -> workspace_show
2018-03-24 13:47:59 +01:00
Orestis Floros
4097769105 _workspace_show -> workspace_show
a9b57a44a9 removed the extra parameter of
workspace_show.
2018-03-24 14:26:11 +02:00
Ingo Bürk
83ac1c0e72 Merge pull request #3184 from orestisf1993/issue-1341
floating_enable & floating_maybe_reassign_ws changes
2018-03-23 19:17:12 +01:00
Orestis Floros
8e9b26fc90 floating_maybe_reassign_ws: use get_output_from_rect
This significantly reduces the number of ELOGs while dragging floating
containers. The behaviour is improved since floating containers in the
edge of the screen will still get reassigned to their closest workspace.

For example, consider this setup:
fake-outputs 500x500+0+0,500x500+500+0

Now, open a window in the right output and run:
i3-msg floating enable, move position 0 px 450 px
The window is on the bottom edge of the left workspace but if you run:
i3-msg focus mode_toggle
focus will go to the right workspace since floating_maybe_reassign_ws
didn't change the assigned workspace of the floating container.
2018-03-23 17:42:39 +02:00
Orestis Floros
128122e766 floating_enable: change reassign logic
This allows the floating container's top left corner to be mapped
outside any output as long as they are contained partially by one. This,
for example, will allow:
mpv --geometry +1+1 video.mp4

For windows mapped to (0, 0) see comment in floating.c:270-273:
/* Some clients (like GIMP’s color picker window) get mapped
 * to (0, 0), so we push them to a reasonable position
 * (centered over their leader) */

 The floating_reassign_ws call is removed since we try to place the new
 floating container in the current output:
 /* Sanity check: Are the coordinates on the appropriate output? If not, we
  * need to change them */

Fixes #1341
2018-03-23 17:42:39 +02:00
Orestis Floros
8a3ef3a81b Introduce get_output_from_rect 2018-03-23 17:42:39 +02:00
Orestis Floros
e09861f73f contained_by_output: return output and rename to output_containing_rect 2018-03-23 17:40:03 +02:00
Ingo Bürk
8e198a2105 Merge pull request #3195 from orestisf1993/issue-2993
Improve directional moving of fullscreen containers
2018-03-23 14:52:48 +01:00
Ingo Bürk
9f273f3356 Merge pull request #3178 from orestisf1993/pr-2314
Support _NET_WM_STATE_FOCUSED
2018-03-23 14:50:46 +01:00
Orestis Floros
3ccaf11eab Improve directional moving of fullscreen containers
Fixes #2993.
2018-03-23 15:46:40 +02:00
Tony Crisci
c42de09b1b Support _NET_WM_STATE_FOCUSED
_NET_WM_STATE_FOCUSED is set on _NET_WM_STATE to indicate that the
window is focused. It must be set when the window is newly focused and
removed once the window no longer has focus.

> _NET_WM_STATE_FOCUSED indicates whether the window's decorations are
> drawn in an active state. Clients MUST regard it as a read-only hint.
> It cannot be set at map time or changed via a _NET_WM_STATE client
> message.

For example, this is used by GTK applications to show the decoration in
an active or inactive state. This change can be tested by opening a GTK
application (like evince), focusing the window and unfocusing the
window, and observing a change in the window decorations.

Fixes #2273
2018-03-23 14:30:57 +02:00
Ingo Bürk
7411dfa5ef Merge pull request #3185 from orestisf1993/cmd_move_window_to_position
Remove 'method' from cmd_move_window_to_position
2018-03-21 08:38:41 +01:00
Orestis Floros
5e8a3f3f0c cmd_move_window_to_position: improve error message 2018-03-20 16:59:06 +02:00
Orestis Floros
174dc389ff Remove 'method' from cmd_move_window_to_position
For command:
move window to [absolute] position X px Y px
if the optional keyword 'absolute' is provided the end result is the
same even though it is implemented differently. Only difference is that
with absolute the floating window can move completely outside of any
output.

This commit removes the 'method' argument and only keeps the sane
implementation.
2018-03-20 16:59:06 +02:00
Ingo Bürk
ddc80ab305 Merge pull request #3191 from orestisf1993/userguide
Fix userguide link
2018-03-20 08:39:23 +01:00
Orestis Floros
dc0337d2e5 Reset B_UPON_KEYRELEASE_IGNORE_MODS bindings when switching modes
With example config:
    mode "a_mode" {
        bindcode 27 --release mode "default"
    }
    bindsym $mod+r mode "a_mode"

The first time $mod+r is pressed "a_mode" is activated like normal. When
r (bindcode 27) is pressed to exit the mode:
- On the KeyPress event the corresponding bind->release is correctly
marked as B_UPON_KEYRELEASE_IGNORE_MODS.
- On the KeyRelease event the command 'mode "default"' is executed but
bind->release is still B_UPON_KEYRELEASE_IGNORE_MODS since they are only
reset on KeyPress events.
The second time $mod+r is pressed and "a_mode" is activated and when the
r key is released the 'mode "default"' is executed even though the mods
are not matching since bind->release == B_UPON_KEYRELEASE_IGNORE_MODS.

This still doesn't catch 2 cases:
1. When the order is: press $mod -> press r -> release $mod -> release
    r. Since 'r' is released without any modifiers the binding matches.
2. With:
        mode "resize" {
            bindsym --release r mode "default"
        }
        bindsym r mode "resize"
    This is arguably correct: on the KeyPress event we switch to the mode and
    on the KeyRelease we switch back.
2018-03-20 04:09:34 +02:00
Orestis Floros
ff579ef22f Correctly handle bindings for the same mod key with and without --release
Before this commit, get_binding() exited on the first match without
marking the rest --release bindings with B_UPON_KEYRELEASE_IGNORE_MODS.

Similarly, once it found a --release binding during a KeyPress event it
would stop searching for a matching key press binding.

Example config, placing the --release line first will trigger the second
problem:

# i3 config file (v4)
bindsym Super_L exec notify-send "press"
# or
# bindcode 133 exec notify-send "press"
bindsym --release Super_L exec notify-send "release"
# or
# bindcode --release 133 exec notify-send "release"

Fixes #2733
2018-03-20 04:09:25 +02:00
Orestis Floros
130b3ce3a9 Check for B_UPON_KEYRELEASE_IGNORE_MODS with bindsyms
From 548d74015c:
> 1. press $mod, press x, release x, release $mod
> 2. press $mod, press x, release $mod, release x

case (2.) didn't work, now it should be fixed.
2018-03-20 04:00:47 +02:00
Orestis Floros
b467937808 Fix userguide link
[[move_to_outputs]] doesn't work currently:
https://i3wm.org/docs/userguide.html#move_to_outputs
This does:
https://i3wm.org/docs/userguide.html#_moving_containers_workspaces_to_randr_outputs

This combines a 'BlockId Element' with an 'anchor'. Both should work
now.
2018-03-19 18:30:22 +02:00
Ingo Bürk
670dfa0bba Merge pull request #3189 from orestisf1993/run_assignments
run_assignments: check for A_COMMAND early
2018-03-19 14:32:54 +01:00
Ingo Bürk
b4e24a6d5f Merge pull request #3188 from orestisf1993/free_ran_assignments
Free ran_assignments
2018-03-19 07:04:45 +01:00
Ingo Bürk
b721a40fdb Merge pull request #3187 from orestisf1993/assign-memleak
Fix memleak: FREE(assign->dest.output)
2018-03-19 07:03:47 +01:00
Orestis Floros
6306acdb65 run_assignments: check for A_COMMAND early 2018-03-19 03:17:32 +02:00
Orestis Floros
98df2e21fa Free ran_assignments
When we run 'reload' all the assignments are freed:
e3e09119bf/src/config.c (L99-L109)

Assignments are saved to each window after they are executed:
e3e09119bf/src/assignments.c (L41-L46)

This means that the pointers stored in window->ran_assignments are
invalid (shouldn't be dangerous currently but could lead to a segfault
if the code is modified) after a 'reload'.
2018-03-19 03:00:35 +02:00
Orestis Floros
1fe4e635b5 Fix memleak: FREE(assign->dest.output) 2018-03-19 02:02:59 +02:00
Ingo Bürk
e3e09119bf Merge pull request #3186 from orestisf1993/i3-msg
i3-msg: only print input + errorposition if they exist
2018-03-18 07:51:50 +01:00
Orestis Floros
124e64767e i3-msg: only print input + errorposition if they exist
Before:
$ i3-msg floating disable, move window to position 100 px 100 px
ERROR: Your command: (null)
ERROR:               (null)
ERROR: Cannot change position of a window/container because it is not floating.
[{"success":true},{"success":false,"error":"Cannot change position of a window/container because it is not floating."}]

After:
$ i3-msg floating disable, move window to position 100 px 100 px
ERROR: Cannot change position of a window/container because it is not floating.
[{"success":true},{"success":false,"error":"Cannot change position of a window/container because it is not floating."}]
2018-03-18 03:38:06 +02:00
Tony Crisci
9cd4b53231 testcases: remove assumption from state atoms test
Remove the assumption that only two atoms can possibly be set in
t/253-multiple-net-wm-state-atoms.t so that the tests will pass when
more atoms are supported that may be set during this test.
2018-03-18 00:11:55 +02:00
Ingo Bürk
a9512c6345 Merge pull request #3180 from chrisduerr/next
Add alacritty to `i3-sensible-terminal`
2018-03-17 07:31:48 +01:00
Christian Duerr
b266574c30 Add alacritty to i3-sensible-terminal 2018-03-16 22:53:39 +01:00
Michael Stapelberg
8f5c1cb6b8 Merge pull request #2975 from orestisf1993/move-con_focus
Fix move's focus bugs
2018-03-16 09:31:53 +01:00
Orestis Floros
9d22d2efce Reduce repetition in get_binding() 2018-03-16 03:08:47 +02:00
Ingo Bürk
965ef8d33f Merge pull request #3177 from orestisf1993/trailing
Remove trailing whitespace from Perl scripts
2018-03-15 20:41:47 +01:00
Orestis Floros
3f4268561d Remove trailing whitespace from Perl scripts 2018-03-15 21:33:45 +02:00
Orestis Floros
d66fa51f33 Don't call con_focus in tree_move
Fixes:
- Issue where moving an urgent (unfocused) window resets it's urgency
hint.
- Moving an unfocused container to a new parent should not move it to
the top of the focus stack.
2018-03-15 19:57:30 +02:00
Orestis Floros
6222ab1084 Correct insert_con_into's focus handling
Change from always putting con on the head of the new parent. Important
for moving unfocused containers.
2018-03-15 19:49:17 +02:00
Ingo Bürk
c1e622be27 Merge pull request #3176 from orestisf1993/dump-asy-marks
dump-asy.pl: Add marks
2018-03-14 14:24:00 +01:00
Ingo Bürk
6cc3a2bfe8 Merge pull request #3175 from orestisf1993/dump-asy
dump-asy.pl: Add options
2018-03-14 14:23:39 +01:00
Orestis Floros
774a61b47e dump-asy.pl: Add marks 2018-03-14 14:59:26 +02:00
Orestis Floros
dda340cbc6 dump-asy.pl: Add --save option 2018-03-14 14:43:12 +02:00
Orestis Floros
883cf4041d dump-asy.pl: Add --gv option 2018-03-14 14:32:16 +02:00
Orestis Floros
9521f69e11 dump-asy.pl: Add POD usage 2018-03-14 12:12:44 +02:00
Ingo Bürk
c0bcd37153 Merge pull request #3172 from klorax/patch-1
Docs [#3164]: Clarification about X resource value
2018-03-11 19:54:39 +01:00
Klorax
9017a17e39 Docs [#3164]: Clarification about X resource value
Clarification about X resource value: they are loaded verbatim and must therefore be in the format that i3 uses.
Solves #3164.
2018-03-11 18:04:32 +01:00
Ingo Bürk
dfc330fcb8 Merge pull request #3167 from hwangcc23/fix-3163
Add strip_workspace_name
2018-03-11 16:33:10 +01:00
hwangcc23
2269b2e795 Add strip_workspace_name
See the issue #3163 (https://github.com/i3/i3/issues/3163).

Add strip_workspace_name to strip off the workspace name.
2018-03-11 12:17:42 +08:00
Ingo Bürk
c54f500839 Merge pull request #3171 from i3/revert-3170-master-merge
Partially revert "Fix incorrect merge *sigh*"
2018-03-10 21:48:14 +01:00
Michael Stapelberg
010e86605d Partially revert "Fix incorrect merge *sigh*" 2018-03-10 21:45:42 +01:00
Ingo Bürk
74c0e1b866 Merge pull request #3170 from stapelberg/master-merge
Fix incorrect merge *sigh*
2018-03-10 21:37:53 +01:00
Michael Stapelberg
ffcf2bca85 Fix incorrect merge *sigh* 2018-03-10 21:35:14 +01:00
Ingo Bürk
69eec7e5b2 Refocus focused window for FOCUS_IN events on the root window. (#3097)
This deals with (admittedly somewhat misbehaving) clients which
use XSetInputFocus to take focus, but then don't properly restore
focus. This has been observed with TK apps, but also, e.g., Steam.

fixes #2722
fixes #3096
2018-03-10 19:18:44 +01:00
Ingo Bürk
ec5a048792 Merge pull request #3166 from Hritik14/next
Fixed typo
2018-03-10 19:11:55 +01:00
Ingo Bürk
eafe55a9d8 Merge pull request #3168 from stapelberg/release-fixes
Release fixes
2018-03-10 19:08:19 +01:00
Michael Stapelberg
a05ba370cd update release.sh after release 2018-03-10 18:53:20 +01:00
Michael Stapelberg
c74dd61f59 release: new-enough dput no longer needs an explicit file name 2018-03-10 18:53:04 +01:00
Michael Stapelberg
a07980f70b release: also build a Debian source-only upload 2018-03-10 18:52:50 +01:00
Michael Stapelberg
8513107f09 release: disable git’s rename protection (prevented merging) 2018-03-10 18:52:27 +01:00
Michael Stapelberg
e6b2fefe26 debian: update changelog 2018-03-10 18:35:11 +01:00
Michael Stapelberg
de0ff844e0 Update debian/changelog 2018-03-10 18:29:21 +01:00
Michael Stapelberg
b96529503f Merge branch 'release-4.15' 2018-03-10 18:29:21 +01:00
Michael Stapelberg
cdf9a8f77e Merge branch 'next' into master 2018-03-10 18:29:21 +01:00
Michael Stapelberg
5a32c1282a Set non-git version to 4.15-non-git. 2018-03-10 18:29:21 +01:00
Hritik Vijay
8ee4a4a3e1 Fixed typo 2018-03-10 02:38:47 +05:30
Michael Stapelberg
2eca0f0287 Merge branch 'release-4.14.1' 2017-09-24 19:21:41 +02:00
Michael Stapelberg
f7270b3324 Set non-git version to 4.14.1-non-git. 2017-09-24 19:21:41 +02:00
Michael Stapelberg
83a62267dc release i3 4.14.1 2017-09-24 19:21:26 +02:00
Michael Stapelberg
918ac865df docs/ipc: document the GET_CONFIG request (#2984)
This was neglected in commit a6d8ed9b1a

related to #2856
2017-09-24 17:26:06 +02:00
Michael Stapelberg
1aaf9f2e52 tests: replace http:// with https:// where appropriate
This was done automatically using:

% sed -i 's,http://build.i3wm.org,https://build.i3wm.org,g' testcases/t/*.t
2017-09-24 17:07:16 +02:00
Michael Stapelberg
aa0b1f599f Replace http:// with https:// where applicable
The testcases will be updated automatically in a separate commit.
2017-09-24 17:07:15 +02:00
Orestis Floros
eadc9a8461 Check container existance during drag events
This fixes a crash that occurs when disabling floating for a container
while it is being moved or resized.

@Deiz describes the problem:
> It occurs because the command that disables floating runs before the
event loop. So, the window is tiled, its floating parent is destroyed,
but then a key event is handled which causes the position/size of the
now-destroyed parent to be modified.

Fixes #1627
2017-09-24 17:07:13 +02:00
Orestis Floros
2e83d2193e Add con_exists function
Checks the all_cons queue and returns true if a given con is found.
2017-09-24 17:07:12 +02:00
Orestis Floros
8653bfe8d3 Raise floating window to top when it gets focus
Applied for:
1. '[...] focus' for a floating container raises it to the top.
2. Focusing a window through a focus event raises it to the top.

Fixes #2572
2017-09-24 17:07:07 +02:00
Martin T. H. Sandsmark
683e33199d Don't put new floating windows on top unless they're focused 2017-09-24 17:06:59 +02:00
Vladimir Panteleev
8144a0f480 Do not canonicalize special output names
canonicalize_output_name allowed the "primary" special output name to
be canonicalized, thus converting it to the name of whatever output
was the primary output at the time. This caused settings
(specifically, i3bar output and tray_output settings) to be stored as
specific output names, instead of the intended special names whose
referred output may change as the system's configuration (i.e. current
primary output) changes.

Add a check to canonicalize_output_name to return the name as-is if it
is the special name "primary".
2017-09-19 18:58:35 +02:00
Vladimir Panteleev
e4bfb4dae3 fake_outputs: Allow designating a fake output as primary
Allow appending 'P' to the fake output specification to set the
created output's "primary" flag, to allow writing test cases that
depend on the presence of a primary output.
2017-09-19 18:58:32 +02:00
Vladimir Panteleev
c932c88ea9 fake_outputs: Don't read past the end of string
fake_outputs_init would unconditionally increase the string read
pointer variable (walk) by one character more than the number of
characters that have been read, to skip past the character delimiting
records (a comma). However, when the input string was not terminated
by a comma, it would cause the function to read past the null
terminator instead.

Avoid this by explicitly checking for the expected delimiter.
2017-09-19 18:58:28 +02:00
Vladimir Panteleev
4ddf18ef6b fake_outputs: Use %n format specifier instead of sprintf
fake_outputs_init used a sprintf invocation with a throw-away buffer
to estimate how many characters the sscanf invocation consumed. This
was unnecessary, and also potentially incorrect, as differences
between the read and formatted strings (such as leading zeros) could
lead to fake_outputs_init to lose its track.

Instead, use the %n format specifier which allows saving the number of
characters consumed by sscanf so far. %n is part of C99.
2017-09-19 18:58:25 +02:00
Michael Stapelberg
da72a5be91 tests: unflake tests by not starting i3bar 2017-09-19 16:13:27 +02:00
Michael Stapelberg
69a6887ab2 tests: remove the (broken) exit_gracefully check
I previously tried to fix the check, but could only come up with a fix which
required removing our module pre-loading, which makes the tests considerably
more expensive. Instead, let’s just remove the check.
2017-09-19 16:13:24 +02:00
Michael Stapelberg
e5ee11d896 tests: use i3_config arg instead of precisely one launch_with_config
This way, tests are shorter, and i3test’s invocation of launch_with_config
parallelizes work better, using dont_block => 1.
2017-09-19 16:13:21 +02:00
Michael Stapelberg
28bfeadbb0 i3test::XTEST: don’t “use i3test” to avoid clobbering state
Before this commit, the $i3_autostart variable was accidentally overridden.
2017-09-19 16:13:17 +02:00
Michael Stapelberg
5d9db61dda Reorder tests to not use the same number (#2947)
Distinct numbers make re-running individual tests easier by helping with
tab-completion.

Completeness verified using:
% for i in $(seq 0 600)
do
  files=$(ls testcases/t/$(printf "%03d" $i)-*.t 2>&- | wc -l)
  [ "$files" != "0" ] && [ "$files" != "1" ] && echo "clash: $i"
done
2017-09-19 16:13:14 +02:00
Michael Stapelberg
31834b3ce4 Kill windows between tests 2017-09-19 16:12:42 +02:00
Michael Stapelberg
4fd05e4db2 i3test: add kill_all_windows convenience function 2017-09-19 16:12:38 +02:00
Michael Stapelberg
dbd3ca749c 529-net-wm-desktop: avoid timeout, avoid restarts, split
This shaves off almost half a second of the wall-clock time (from 5.9s to 5.6s).
2017-09-19 16:12:34 +02:00
Michael Stapelberg
e46dc19f82 165-for_window: merge config and re-use i3 instance, split remainder
This reduces total test wall-clock time by 1.5s (from 7.5s down to 5.9s).
2017-09-19 16:12:31 +02:00
Michael Stapelberg
ee1546386b t/265-swap: don’t start new i3 instances with the same config
$config is never touched after being initially set up.
Not restarting i3 between each test case reduces the runtime of this test by an
order of magnitude.
2017-09-19 16:12:26 +02:00
Michael Stapelberg
501dfd6eb8 ipc: document how to detect i3’s byte order in memory-safe languages (#2961)
related to issue #2958
2017-09-19 15:47:06 +02:00
Michael Stapelberg
7726b9a759 Bugfix: avert crash by fixing focus when creating output containers (#2966)
fixes #2854
2017-09-19 15:47:01 +02:00
Michael Stapelberg
0b6d851d7c Bugfix: don’t invalidate layout upon invalid 'layout toggle' params (#2965)
fixes #2903
2017-09-19 15:46:58 +02:00
Michael Stapelberg
910bcd68bc docs/ipc: "urgent": complete the list of container types (#2967)
Thanks chressie!
2017-09-19 15:46:53 +02:00
Kent Fredric
5acddc259b Migrate tooling to ExtUtils::MakeMaker (#2963) 2017-09-19 15:46:49 +02:00
Michael Stapelberg
3bc91118c8 ipc: rename COMMAND to RUN_COMMAND for consistency (#2956)
All other message types are verbs, only our first-ever message COMMAND wasn’t.

While we’re here, also change the message type dictionary into a table with
clickable links to the corresponding reply type.

Authors of downstream IPC libraries are encouraged to keep the old name around
so as to not break existing code, but mark it as deprecated.
2017-09-19 15:46:38 +02:00
Orestis Floros
395dc7bebd Fix use of err after it is freed 2017-09-19 15:46:32 +02:00
Orestis Floros
b5583d6cf4 Fix wrong call to free
To confirm, assign n to a constant value and try to use the
append_layout command.

Without the change i3 crashes.
2017-09-19 15:46:28 +02:00
Orestis Floros
5dad79ff34 Prevent freeing of uninitialized pointer
> variable 'buf' is used uninitialized whenever 'if' condition is true

Note: freeing a NULL pointer is fine.
2017-09-19 15:46:24 +02:00
Michael Stapelberg
f1e9da71f0 ipc: tree reply: document focus, nodes and floating_nodes (#2955)
These haven’t ever changed, but were only included in the example, not in the
list, so people might not have realized that these are safe for use.
2017-09-19 15:46:19 +02:00
Vladimir Panteleev
ba7a76e367 Fix erratic behavior with single container child jumping outputs
This fixes a regression introduced in commit
4e88c10564: when attempting to move the
single child of a container in the direction of another output, i3
would move the window to the output, despite the window not being at
the edge of its output, instead of moving it to its parent container.

The bug occurred because the check for moving containers across
outputs with non-default workspace layouts (issue #1603) did not
actually verify that the moved window lies at the edge of the
workspace, despite what its comment said.

Fixes issue #2466.
2017-09-19 15:46:07 +02:00
Vladimir Panteleev
8e520deb89 Fix typo in con_parent_with_orientation description 2017-09-19 15:46:04 +02:00
Michael Stapelberg
b421799d9c tests: unflake t/257-keypress-group1-fallback.t (#2946)
fixes #2944
2017-09-19 15:45:42 +02:00
Michael Stapelberg
51da57d5e6 validate JSON before loading
This commit also introduces slurp() which reads a file in its entirety. Using
this function instead of doing IO in the functions in load_layout.c again and
again makes the code cleaner (fixing at least two memory leaks) and avoids
re-reading the same file 3 times.

related to #2755
2017-09-13 18:46:17 +02:00
Michael Stapelberg
f120a9d929 Bugfix: free incomplete containers when JSON parsing fails
related to #2755
2017-09-13 18:46:12 +02:00
Orestis Floros
d35de66f1e scalloc parse_config input to make sure it terminates with '\0'
Otherwise strchr() can crash for files that don't end with '\n' because
it won't find a null char to terminate at.

Fixes #2934
2017-09-13 18:46:04 +02:00
Orestis Floros
919ac9c7ef Don't insert newline at end of config with launch_with_config 2017-09-13 18:46:02 +02:00
Vladimir Panteleev
2159306b94 docs/userguide: Document that i3 can accept RandR output names 2017-09-13 18:45:46 +02:00
Vladimir Panteleev
92ff6fbe24 533-randr15.t: Add test for bar output name canonicalization 2017-09-13 18:45:46 +02:00
Vladimir Panteleev
fb1d9efb27 533-randr15.t: Stop hard-coding the output name
Refactor away all mentions of DP3.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
f5e9b518da 533-randr15.t: Add a fake output connected to the fake monitor
Add an output ID to the simulated RRGetMonitors reply, then add a
simulated RRGetOutputInfo reply describing the added output.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
21dd8c475a testcases/lib: Add inject_randr15_outputinfo argument
Allow tests to specify a file name for inject_randr15's
--getoutputinfo_reply command-line parameter.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
7fb027ad37 inject_randr1.5: Intercept X11 error responses in addition to replies
Allow clients to send garbage to the server, then intercept the
server's error response and substitute it with the supplied simulated
reply data.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
80a937f43c inject_randr1.5: Add RRGetOutputInfo reply injection
Add a --getoutputinfo_reply switch to indicate a filename containing
the RRGetOutputInfo reply data to inject.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
38447ab78c inject_randr1.5: Refactor reading and storing reply buffer to a struct
Allows easier introduction of additional reply buffers in upcoming
changes.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
16e0d5ec06 ipc: Canonicalize output names in bar configuration
Convert the output names specified in the "output" and "tray_output"
fields in bar blocks in i3's configuration to the referred output's
primary name. This allows specifying names other than the primary
output's name in the given fields without changing the IPC protocol.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
c35cacfd78 randr: Look up alternative output names when searching outputs
Update get_output_by_name to look at all additional names added by the
change in the previous commit, not just the primary one.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
08ad82c3bb randr: Register monitors' output names as additional i3 output names
In addition to the name of the monitor itself (which is still used as
the i3 output's primary name), register RandR output names associated
with the RandR monitor as alternative i3 output names.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
6c0e715877 Store output names as a linked list
Currently, only one name is ever added, and only the first name is
ever accessed; actually using the capability to store and access
multiple names comes in the following commits.
2017-09-13 18:45:46 +02:00
Vladimir Panteleev
1b419431cd Introduce output_primary_name function
Currently simply returns output->name, but this will make it easier to
change how output names are stored in the following commits.

Also replace reading output->name with invocations of
output_primary_name. Code which writes output->name is unchanged. Done
using a mostly mechanical replacement of output->name to
output_primary_name(output).
2017-09-13 18:45:46 +02:00
Michael Stapelberg
d0c9e81f04 testsuite: install Module::Install so that AnyEvent-I3/Makefile.PL works (#2940)
As per https://perlmaven.com/cant-locate-inc-module-install-in-inc, the inc/
directory should not be under version control.

fixes #2914
2017-09-13 18:42:47 +02:00
Orestis
0631568b2d Fix userguide bug (#2932)
Fixes #2931
2017-09-13 18:42:43 +02:00
Vladimir Panteleev
c3c94a8e1a docs/hacking-howto: Update section topology
- Promote the "How to build?" sub-section to a top-level
  section ("Building i3")

- Convert the "Introduction" sub-section as the intro to the remaining
  contents of the "Using git / sending patches" section

- Keep "Which branch to use?" as a level-3 sub-section, thus making it
  a sub-section of what used to be the "Introduction" sub-section.
2017-09-13 18:42:37 +02:00
Vladimir Panteleev
83d61e4b81 docs/hacking-howto: Promote "How to build?" sub-section
Move the "How to build?" sub-section to the top of its parent section.
2017-09-13 18:42:32 +02:00
Vladimir Panteleev
bf59c0fbfc docs/hacking-howto: Promote "Using git / sending patches" section
Move the contents of the "Using git / sending patches" section to the
top of the document.
2017-09-13 18:42:27 +02:00
Michael Stapelberg
6203c6cb39 tests: run 533-randr15.t at the very end
The test runs `xrandr setmonitor`, which will otherwise affect any test
scheduled after 533-randr15.t, causing flakyness in t/217-NET_CURRENT_DESKTOP.t
for example.
2017-09-13 18:42:22 +02:00
Michael Stapelberg
6dc164a652 tests: unflake t/263-edge-borders.t 2017-09-13 18:42:18 +02:00
Michael Stapelberg
429af6dbb3 tests: re-seed random number generator in workers 2017-09-13 18:42:13 +02:00
Vladimir Panteleev
2eaf58a553 docs/testsuite: Correct Xephyr package name on Arch Linux (#2913)
The package is called `xorg-server-xephyr`, not `xorg-xserver-xephyr`.
2017-09-13 18:41:51 +02:00
Michael Stapelberg
155e307a3f testcases/Makefile.PL: tell MakeMaker this is a pure-Perl distribution (#2922)
fixes #2914
2017-09-13 18:41:46 +02:00
Orestis
7cb9465db9 Add files generated by make check in AnyEvent-I3/ to .gitignore (#2915) 2017-09-13 18:41:31 +02:00
Michael Stapelberg
083b6a31f4 Include AnyEvent-I3 directory in dist tarballs (#2916)
fixes #2905
2017-09-13 18:41:26 +02:00
Michael Stapelberg
4b0a6ba769 travis: downgrade temporarily due to asan issue
fixes #2912
2017-09-13 18:41:21 +02:00
Michael Stapelberg
a542b3d26c i3bar: ensure get_buffer does not leak memory
This fixes an AddressSanitizer warning which recently popped up.

related to #2907
2017-09-13 18:41:13 +02:00
Orestis Floros
b48cbe42af Set marks to NULL after freeing
realloc() was being called on an already freed pointer.

Fixes #2900
2017-09-07 14:56:17 +02:00
Orestis Floros
f26b00cb67 Improve 267-regress-mark-restart.t
Another window with a mark is needed for issue #2900.
2017-09-07 14:56:12 +02:00
Orestis
369c9ed50f Check if con_id exists in cmd_swap (#2898)
Also adds some testcases for swap using con_id.

Fixes #2895
2017-09-06 07:36:22 +02:00
Ingo Bürk
dedfda1e01 Invert condition to log debug message in correct situation (#2896) 2017-09-06 07:36:18 +02:00
hwangcc23
09ee12d8e5 Properly initialize sigaction struct
The code in handle_signal() wasn't clearing the struct sigaction before passing it to sigaction().
This meant that we would block a random set of signals while executing the default handler, or jump to the uninitialized __sa_sigaction__ (instead of sa_handler).
Initialize properly as we do in setup_signal_handler().
2017-09-06 07:36:13 +02:00
Theo Buehler
e8dbf0171d Avoid use of uninitialized in init_dpi_end
If conn == NULL or display == NULL, init_dpi() jumps to init_dpi_end
before (declaring and) initializing resource. In init_dpi_end, there
is a free(resource) call conditionally on resource != NULL, so this
may lead to a bogus free. Found by clang -Wsometimes-uninitialized.
2017-09-06 07:36:08 +02:00
Michael Stapelberg
e1f6a3e3d3 Update debian/changelog 2017-09-04 07:53:39 +02:00
Michael Stapelberg
7af2faebd8 Merge branch 'next' into master 2017-09-04 07:53:39 +02:00
Michael Stapelberg
7785e7be7d Update debian/changelog 2016-11-08 19:54:15 +01:00
Michael Stapelberg
1994eea5da Merge branch 'next' into master 2016-11-08 19:54:14 +01:00
Michael Stapelberg
0e29101ae5 fix i3 4.12 merge issue in src/commands.c (Thanks Airblader) 2016-03-06 16:59:46 +01:00
Michael Stapelberg
7a057de969 Update debian/changelog 2016-03-06 16:17:28 +01:00
Michael Stapelberg
988cc3ccaf Merge branch 'next' into master 2016-03-06 16:17:27 +01:00
Michael Stapelberg
1f9f44b694 travis: install clang-format-3.5 from llvm repository
Ubuntu utopic disappeared from archive.ubuntu.com, it’s EOL.
2015-10-28 22:13:34 +01:00
Michael Stapelberg
82806f3857 Bugfix: correctly compare modifier mask when identifying keybindings
fixes #2002
2015-10-28 21:56:55 +01:00
Ingo Bürk
4779e59c50 Fix multiple memory leaks with regular expressions. 2015-10-28 21:56:53 +01:00
Ingo Bürk
a22dec02f8 Refactor parsing of matches to avoid code duplication. 2015-10-28 21:56:52 +01:00
Ingo Bürk
f02413b4cf Fix crash when trying to split and float a dock container.
Since splitting a docking container was allowed and successful, the check
to prevent floating it fails to work. This causes a crash because the
workspace of the container cannot be determined as the dockarea is higher
up in the tree than the workspace it belongs to.

This patch extends to sanity check to nested dock containers when trying to
float a container and also disallows manually splitting a docked container
or changing its layout.

fixes #2034
2015-10-28 21:56:50 +01:00
Ingo Bürk
1f953719c9 Mark assignment as run before executing it.
We need to store the information that an assignment was run for a window
before actually executing the command. Otherwise, if the command causes
a change that causes assignments to be run again, the window might be
matched again, causing an infinite loop and hence i3 to freeze or crash.
2015-10-28 21:56:49 +01:00
Ingo Bürk
0aa8d05b54 Fixed logging statement.
Assignments don't necessarily represent workspace assignments, but could
also be used, e.g., for no_focus. Hence, there's no point in logging
dest.workspace for all assignments.
2015-10-28 21:56:47 +01:00
Ingo Bürk
7c75d61a39 Activate root output if RandR request fails.
fixes #2011
2015-10-28 21:56:46 +01:00
Adaephon-GH
76db8b73ae Make rendering of key bindings more consistent
- Render key names and key bindings verbatim if they could be used like
  that in the configuration (no special format for "colloquial" names:
  Alt, Windows, ...)
- Use only lower case letters for key bindings
2015-10-28 21:56:45 +01:00
Adaephon-GH
2e5cfdeea0 Improve placement of explicit IDs for headings
In some cases the IDs of section titles was placed after the section
title. With that in the rendered HTML the ID was placed on the paragraph
and not on the heading. This led to heading not being shown when the
corresponding link was clicked.
2015-10-28 21:56:43 +01:00
Adaephon-GH
2a22b5d561 Quote __focused__ to prevent parsing by asciidoc
Text between two "__" is rendered as italics by asciidoc. This affects
the display of the new __focused__ special value for criteria.
2015-10-28 21:56:41 +01:00
Michael Stapelberg
724cfebe5e fix a memory leak in handle_get_bar_config 2015-10-28 21:56:39 +01:00
Michael Stapelberg
5648221d06 Fix memleak in translate_keysyms 2015-10-28 21:56:34 +01:00
Ingo Bürk
27535398f5 Turn "char *" into "const char *" for all command parser functions. 2015-10-28 21:56:17 +01:00
Ingo Bürk
9978050d91 Migrate the move command to use typed numbers. 2015-10-28 21:56:16 +01:00
Ingo Bürk
a271666fa7 Migrate the resize command to use typed numbers. 2015-10-28 21:56:14 +01:00
Ingo Bürk
f5f5683fa7 Allow the commands parser to use "number" arguments by making the stack typed. 2015-10-28 21:56:11 +01:00
Adaephon-GH
5049990284 Fix erroneous headline for moving to mark
The headline indicated that it would be possible to move containers and *workspaces* to marks but the following text clearly shows that it should state containers and *windows*.
2015-10-28 21:55:07 +01:00
Ingo Bürk
0a16a4b5e5 Add proper documentation for binding modes.
fixes #1996
2015-10-28 21:55:05 +01:00
Ingo Bürk
ab9d74b434 Fix moving windows to a marked workspace by mark.
When a window is moved to a mark and the marked container is a workspace,
we can skip any other logic and just call con_move_to_workspace directly.

fixes #2003
2015-10-28 21:55:03 +01:00
Ingo Bürk
bfd9960df2 Suppress no_focus for first window on a workspace.
With this patch, the no_focus directive will be ignored if the
to-be-opened window is the first on its workspace as there's no
reason the user would not want to focus it in this case.
This improves usability when, for example, using a tabbed
workspace_layout.

fixes #1987
2015-10-28 21:55:00 +01:00
Michael Stapelberg
94bdf607bb Use sasprintf() 2015-10-28 21:54:58 +01:00
Michael Stapelberg
62bb7af5c3 Bugfix: add keymap fall back (_XKB_RULES_NAMES, then defaults)
fixes #1983
2015-10-28 21:54:55 +01:00
Michael Stapelberg
6d385e65aa Merge pull request #1974 from sur5r/master
Fix formatting of description list
2015-10-02 19:52:10 +02:00
Jakob Haufe
d584d0f2db Fix formatting of description list 2015-10-01 21:34:16 +02:00
Michael Stapelberg
d76b7fab45 Update debian/changelog 2015-09-30 08:55:24 +02:00
Michael Stapelberg
96e1b80371 Merge branch 'next' into master 2015-09-30 08:55:24 +02:00
576 changed files with 25180 additions and 12895 deletions

View File

@@ -1,11 +1,14 @@
BasedOnStyle: google
AllowShortBlocksOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortBlocksOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: false
IndentWidth: 4
PointerBindsToType: false
BasedOnStyle: google
ColumnLimit: 0
SpaceBeforeParens: ControlStatements
ForEachMacros: [ TAILQ_FOREACH, TAILQ_FOREACH_REVERSE, SLIST_FOREACH, CIRCLEQ_FOREACH, CIRCLEQ_FOREACH_REVERSE, NODES_FOREACH, NODES_FOREACH_REVERSE, FOREACH_NONINTERNAL]
IndentWidth: 4
InsertBraces: true
PointerBindsToType: false
SortIncludes: false
SpaceBeforeParens: ControlStatements
TypenameMacros: [ SLIST_HEAD, SLIST_ENTRY, LIST_HEAD, LIST_ENTRY, SIMPLEQ_HEAD, SIMPLEQ_ENTRY, TAILQ_HEAD, TAILQ_ENTRY, CIRCLEQ_HEAD, CIRCLEQ_ENTRY ]

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
.git

View File

@@ -4,7 +4,7 @@
Note that bug reports and feature requests for related projects should be filed in the corresponding repositories for [i3status](https://github.com/i3/i3status) and [i3lock](https://github.com/i3/i3lock).
## i3 bug reports and feature requests
## i3 bug reports
1. Read the [debugging instructions](https://i3wm.org/docs/debugging.html).
2. Make sure you include a link to your logfile in your report (section 3).
@@ -18,6 +18,20 @@ Note that bug reports and feature requests for related projects should be filed
encountered the issue you are about to report while using a compositor,
please try reproducing it without a compositor.
## i3 feature requests
1. Read the [project goals](https://i3wm.org) on the website and make sure that
they are compatible with the feature you want to suggest.
2. We are generally happy with the current feature set of i3 and instead focus
on maintenance such as stability and fixing bugs. New features will rarely
be considered if they require additional configuration and/or commands, or
if they add significant complexity (either through the exposed configuration
or mental complexity) to the project.
3. Explain in detail what problem the feature addresses and why existing
features fall short.
4. Consider whether the feature could instead be implemented using the
[IPC](https://i3wm.org/docs/ipc.html) or other external tooling.
## Pull requests
* Before sending a pull request for new features, please check with us that the
@@ -26,10 +40,19 @@ Note that bug reports and feature requests for related projects should be filed
* Use the `next` branch for developing and sending your pull request.
* Use `clang-format` to format your code.
* Run the [testsuite](https://i3wm.org/docs/testsuite.html)
* If your changes should be reported on the next release's changelog, also
add a small single-line file starting with a number (see examples) containing
a short explanation of your change either in the
[changes](../release-notes/changes) or the
[bugfixes](../release-notes/bugfixes/) folder. Example of changes that should
be reported are bug fixes present in the latest stable version of i3 and new
enhancements. Example of changes that should not be reported are minor code
improvements, documentation, regression and fixes for bugs that were
introduced in the `next` branch.
## Finding something to do
* Find a [reproducible bug](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Areproducible+label%3Abug+) from the issue tracker. These issues have been reviewed and confirmed by a project contributor.
* Find an [accepted enhancement](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Aaccepted+label%3Aenhancement) from the issue tracker. These have been approved and are ok to start working on.
There's a very good [overview of the codebase](https://i3wm.org/docs/hacking-howto.html) available to get you started.
There's an [overview of the codebase](https://i3wm.org/docs/hacking-howto.html) available to get you started.

View File

@@ -1,18 +1,73 @@
Output of `i3 --moreversion 2>&- || i3 --version`:
<!--
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
-->
_REPLACE: i3 version output_
## I'm submitting a…
<!--
Check one of the following options with "x".
URL to a logfile as per https://i3wm.org/docs/debugging.html:
Please note that at this point we focus on maintaining i3 and fixing bugs, and will rarely consider features which require further configuration or significant complexity.
In such cases you should consider and present specific benefits derived from adding this feature such that it can be weighed against the cost of additional complexity and maintenance.
-->
<pre>
[ ] Bug
[ ] Feature Request
[ ] Documentation Request
[ ] Other (Please describe in detail)
</pre>
_REPLACE: URL to logfile_
## Current Behavior
<!--
Describe the current behavior,
e.g., »When pressing Alt+j (focus left), the window above the current window is focused.«
-->
**What I did:**
## Expected Behavior
<!--
Describe the desired behavior you expect after mitigation of the issue,
e.g., »The window left next to the current window should be focused.«
-->
_REPLACE: e.g. "Im pressing Alt+j (focus left)"_
## Reproduction Instructions
<!--
For bug reports, please provide detailed instructions on how the bug can be reproduced.
For feature requests you can remove this section.
**What I saw:**
E.g., »Open three windows in a V[A H[B C]] layout on a new workspace«
-->
_REPLACE: e.g. "i3 changed focus to the window ABOVE the current window"_
## Environment
<!--
Please include your exact i3 version.
Note that we only support the latest major release and the current development version. If you are using an older version of i3, please first update to the current release version and reproduce the issue there.
-->
Output of `i3 --moreversion 2>&-`:
<pre>
i3 version:
</pre>
**What I expected instead:**
_REPLACE: e.g. "Focus should be on the window to the left"_
<!--
For bug reports, please include your (complete) i3 config with which the issue occurs. You can either paste the file directly or provide a link to a service such as pastebin.
If you would like to help debugging the issue, please try to reduce the config such that it is as close to the default config as possible while still reproducing the issue. This can help us bisect the root cause.
-->
<pre>
</pre>
<!--
Providing a logfile can help us trace the root cause of an issue much quicker. You can learn how to generate the logfile here:
https://i3wm.org/docs/debugging.html
Providing the logfile is optional.
-->
<pre>
Logfile URL:
</pre>
<!--
Please also answer the questions below to help us process your issue faster. If you have any other information to share, please add it here as well.
-->
<pre>
- Linux Distribution & Version:
- Are you using a compositor (e.g., xcompmgr or compton):
</pre>

107
.github/ISSUE_TEMPLATE/bug_report.yml vendored Executable file
View File

@@ -0,0 +1,107 @@
name: Bug Report
description: Create a report to help us improve.
labels: [bug]
body:
- type: checkboxes
id: terms
attributes:
label: Welcome
options:
- label: Yes, I'm using the latest major release or the current development version. These are the only supported versions.
required: true
- label: Yes, I've searched similar issues and discussions on GitHub and didn't find any.
required: true
- type: textarea
id: current
attributes:
label: Current Behavior
placeholder: |-
Describe the current behavior,
e.g., »When pressing Alt+j (focus left), the window above the current window is focused.«
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Behavior
placeholder: |-
Describe the desired behavior you expect after mitigation of the issue,
e.g., »The window left next to the current window should be focused.«
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Reproduction Instructions
placeholder: |-
Please provide detailed instructions on how the bug can be reproduced.
E.g., »Open three windows in a V[A H[B C]] layout on a new workspace«
validations:
required: true
- type: textarea
id: version
attributes:
label: i3 version
description: |-
Paste the output of
```
i3 --moreversion 2>&-
```
render: text
validations:
required: true
- type: textarea
id: config
attributes:
label: Config file
description: |-
Please include your (complete) i3 config with which the issue occurs.
If you would like to help debugging the issue, please try to reduce the config such that it is as close to the default config as possible while still reproducing the issue. This can help us bisect the root cause.
render: text
validations:
required: true
- type: input
id: distro
attributes:
label: Linux distribution & Version
validations:
required: true
- type: dropdown
id: compositor
attributes:
label: Are you using a compositor?
description: |-
Try running
```shell
pidof picom
pidof compton
```
If any IDs show up, you are running a compositor
options:
- I don't know
- I am sure I don't run any compositor
- picom
- compton
- Other
validations:
required: true
- type: input
id: verbose-output
attributes:
label: Logfile
description: |-
Providing the URL to a logfile can help us trace the root cause of an issue much quicker. You can learn how to generate the logfile here:
https://i3wm.org/docs/debugging.html
Providing the logfile is optional.
validations:
required: false

7
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
contact_links:
- name: Userguide
url: https://i3wm.org/docs/userguide.html
about: i3 Users Guide
- name: Ask a question or request support for using i3
url: https://github.com/i3/i3/discussions/new
about: Ask a question or request support for using i3

57
.github/ISSUE_TEMPLATE/feature_request.yml vendored Executable file
View File

@@ -0,0 +1,57 @@
name: Feature request
description: Suggest an idea for this project
labels: [enhancement]
body:
- type: checkboxes
id: terms
attributes:
label: Welcome
options:
- label: Yes, I've searched similar issues and discussions on GitHub and didn't find any.
required: true
- type: checkboxes
id: impact
attributes:
label: Impact
description: |-
Please note that at this point we focus on maintaining i3 and fixing bugs, and will rarely consider features which require further configuration or significant complexity.
In such cases you should consider and present specific benefits derived from adding this feature such that it can be weighed against the cost of additional complexity and maintenance.
Keep in mind that i3 provides a powerful way to interact with it through its IPC interface: https://i3wm.org/docs/ipc.html.
options:
- label: This feature requires new configuration and/or commands
required: false
- type: textarea
id: current
attributes:
label: Current Behavior
placeholder: |-
Describe the current behavior,
e.g., »When pressing Alt+j (focus left), the window above the current window is focused.«
validations:
required: true
- type: textarea
id: desired
attributes:
label: Desired Behavior
placeholder: |-
Describe the desired behavior you expect after mitigation of the issue,
e.g., »The window left next to the current window should be focused.«
validations:
required: true
- type: textarea
id: version
attributes:
label: i3 version
description: |-
Paste the output of
```
i3 --moreversion 2>&-
```
render: text
validations:
required: true

98
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,98 @@
name: GitHub Actions
on:
push:
branches: [ next, master, actions ]
pull_request:
branches: [ next ]
jobs:
build:
name: build and test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
compiler: [gcc, clang]
env:
CC: ${{ matrix.compiler }}
DOCKER_PASS: ${{ secrets.DOCKER_PASS }}
DOCKER_EMAIL: ${{ secrets.DOCKER_EMAIL }}
DOCKER_USER: ${{ secrets.DOCKER_USER }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
BALTO_TOKEN: ${{ secrets.BALTO_TOKEN }}
steps:
- uses: actions/checkout@v4
- run: git fetch --prune --unshallow
- name: construct container name
run: |
echo "BASENAME=i3wm/travis-base:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base.Dockerfile)" >> $GITHUB_ENV
echo "BASENAME_UBUNTU=i3wm/travis-base-ubuntu:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base-ubuntu.Dockerfile)" >> $GITHUB_ENV
- name: fetch or build Docker container
run: |
docker pull ${{ env.BASENAME }} || ./travis/docker-build-and-push.sh ${{ env.BASENAME }} travis/travis-base.Dockerfile
- name: fetch or build extra Docker containers
if: github.ref == 'refs/heads/next' && matrix.compiler == 'gcc'
run: |
docker pull ${{ env.BASENAME_UBUNTU }} || ./travis/docker-build-and-push.sh ${{ env.BASENAME_UBUNTU }} travis/travis-base-ubuntu.Dockerfile
- name: build i3
run: |
docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${{ env.BASENAME }} /bin/sh -c 'rm -rf build; mkdir -p build && cd build && CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Werror -fno-common -D_FORTIFY_SOURCE=3" meson setup .. -Ddocs=true -Dmans=true -Db_sanitize=address --buildtype=debugoptimized && ninja -v'
- name: Upload docs html for manual inspection
uses: actions/upload-artifact@v4
with:
name: i3-docs
path: |
build/*.html
if: matrix.compiler == 'gcc'
- name: check spelling
run: |
docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${{ env.BASENAME }} ./travis/check-spelling.pl
- name: run i3 tests
run: |
docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${{ env.BASENAME }} ./travis/run-tests.sh
- name: Archive test logs
uses: actions/upload-artifact@v4
with:
name: test-logs
path: build/testsuite-*
if: ${{ failure() }}
- name: build dist tarball
run: |
docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${{ env.BASENAME }} /bin/sh -c 'rm -rf distbuild; mkdir distbuild && cd distbuild && meson setup .. -Ddocs=true -Dmans=true && meson dist --no-tests'
- name: build Debian packages
if: github.ref == 'refs/heads/next' && matrix.compiler == 'gcc'
run: |
echo "::group::Debian amd64"
docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${{ env.BASENAME }} ./travis/debian-build.sh deb/debian-amd64/DIST
echo "::endgroup::"
echo "::group::Ubuntu amd64"
docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${{ env.BASENAME_UBUNTU }} ./travis/debian-build.sh deb/ubuntu-amd64/DIST
echo "::endgroup::"
- name: push Debian packages to balto
if: github.ref == 'refs/heads/next' && matrix.compiler == 'gcc'
run: |
travis/push-balto.sh
- name: build docs
if: github.ref == 'refs/heads/next' && matrix.compiler == 'gcc'
run: |
docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${{ env.BASENAME }} ./travis/docs.sh
- name: push docs to GitHub pages
if: github.ref == 'refs/heads/next' && matrix.compiler == 'gcc'
run: |
travis/deploy-github-pages.sh
formatting:
name: Check formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: check & print release notes
run: ./release-notes/generator.pl
- name: Install dependencies
run: |
sudo apt-get install -y clang-format-15
- name: Check formatting
run: clang-format-15 --dry-run --Werror $(git ls-files '*.c' '*.h')
- name: Verify safe wrapper functions are used
run: ./travis/check-safe-wrappers.sh

34
.gitignore vendored
View File

@@ -40,31 +40,13 @@ docs/*.html
i3-command-parser.stamp
i3-config-parser.stamp
.clang_complete
compile_commands.json
/.ccls-cache
/.clangd
LAST_VERSION
################################################################################
# https://raw.githubusercontent.com/github/gitignore/master/Autotools.gitignore
################################################################################
# http://www.gnu.org/software/automake
Makefile.in
/ar-lib
/test-driver
# http://www.gnu.org/software/autoconf
/autom4te.cache
/autoscan.log
/autoscan-*.log
/aclocal.m4
/compile
/config.h.in
/config.guess
/config.sub
/configure
/configure.scan
/depcomp
/install-sh
/missing
/stamp-h1
# We recommend building in a subdirectory called build.
# If you chose a different directory name,
# it is up to you to arrange for it to be ignored by git,
# e.g. by listing your directory in .git/info/exclude.
/build

View File

@@ -1,74 +0,0 @@
sudo: false
dist: trusty
# TODO: remove “group” once trusty kernel is no longer affected by
# https://github.com/google/sanitizers/issues/837
group: deprecated-2017Q3
services:
- docker
language: c
compiler:
- gcc
- clang
addons:
apt:
packages:
# For https support in HTTP::Tiny.
- libio-socket-ssl-perl
env:
global:
- BASENAME="i3wm/travis-base:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base.Dockerfile)"
- BASENAME_386="i3wm/travis-base-386:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base-386.Dockerfile)"
- BASENAME_UBUNTU="i3wm/travis-base-ubuntu:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base-ubuntu.Dockerfile)"
- BASENAME_UBUNTU_386="i3wm/travis-base-ubuntu-386:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base-ubuntu-386.Dockerfile)"
- secure: "B5IICA8MPx/FKaB50rTPqL8P1NU+Q0yuWl+lElL4+a9xSyLikfm3NzUPHoVwx8lNw2AVK6br7p0OmF7vMFjqAgrgc1cajTtEae5uFRKNUrWLpXM046YgNEYLLIHsQOjInxE+S4O6EFVzsUqsu8aeo2Xhq4sm4iUocG7e5isYgYo=" # DOCKER_PASS
- secure: "EIvrq8PG7lRjidppG0RCv4F0X4GP3DT9F5+ixVuGPfhK/hZT3jYC2AVY9G+NnUcXVwQEpW92rlqpftQ/qZ13FoyWokC8ZyoyD06fr5FPCfoFF3OczZwAJzZYkObI/hE9+/hXcylx/Os6N4INd2My1ntGk3JPsWL9riopod5EjSg=" # DOCKER_EMAIL
- secure: "hvhBunS4xXTgnIOsk/BPT7I7FrJhvVwCSt5PfxxvMqNaztOJI9BuK7ZrZ5Cy38KyHwlh3VHAH5AaCygJcPauoSQCV3bpnlbaWn3ruq2F0Q697Q5uNf73liXzyUqb9/Zvfvge4y4WWOhP5tVz1C6ZBe/NfhU7pqKLMA+6ads+99c=" # DOCKER_USER
- secure: "uJuuefmnJUuEH15ZD8xQilibx7EeBvMHBLoIZ8bgGHeleEImBD0XbD1ypvhYJKpviOmw5BkZmc9bVO8DGDEHYbSlIa2xDlF6vGrwgCEaxcMIhOAhv+dW9C/maJVieLOEPM01/fK2qdKESZaLvlopkWmxZwDyMObI9L7AMW9zQD8=" # BINTRAY_USER
- secure: "L3aPSNLySPXtWCW+xf8h/AAdquwNgxyTQpYOwexJmTPav82Qx8uQlp1yJkUmt+a+FLZDFfQeMivaHq0311RvuQVmkAJx49DjaddrwqOJut2UPsoVDn1WeuAcSHIXOq/0H+zgFMr/PGY0HXIsw1mTMhgheGJNqg09BvYWROCEAcA=" # BINTRAY_KEY
- secure: "sBMVn4C/WRWgoAytEFGx4CC5O55Q63h02AcuBnb1jXcBm0RenoBpzUPtxSseJwDPUA1o/UkuEDDjm3PosT5NF+dvED01VDFMsPVE11K0u6+avYy3jYXqyUEDW3G2o6Wo/2aqNjmd++8jskBdS9+Cx9gaFbgxfzSp0Yfu3oJm/4c=" # GH_TOKEN
install:
- if [ -a .git/shallow ]; then git fetch --unshallow; fi
- docker pull ${BASENAME} || ./travis/docker-build-and-push.sh ${BASENAME} travis/travis-base.Dockerfile
- ./travis/skip-pkg.sh || docker pull ${BASENAME_UBUNTU} || ./travis/docker-build-and-push.sh ${BASENAME_UBUNTU} travis/travis-base-ubuntu.Dockerfile
- ./travis/skip-pkg.sh || docker pull ${BASENAME_386} || ./travis/docker-build-and-push.sh ${BASENAME_386} travis/travis-base-386.Dockerfile
- ./travis/skip-pkg.sh || docker pull ${BASENAME_UBUNTU_386} || ./travis/docker-build-and-push.sh ${BASENAME_UBUNTU_386} travis/travis-base-ubuntu-386.Dockerfile
script:
- docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-safe-wrappers.sh
- docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-formatting.sh
- docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${BASENAME} /bin/sh -c 'autoreconf -fi && mkdir -p build && cd build && (../configure || (cat config.log; false)) && make -j CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Werror"'
- docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-spelling.pl
- docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${BASENAME} ./travis/run-tests.sh
- ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/debian-build.sh deb/debian-amd64/DIST
- ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME_UBUNTU} ./travis/debian-build.sh deb/ubuntu-amd64/DIST
- ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME_386} linux32 ./travis/debian-build.sh deb/debian-i386/DIST
- ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME_UBUNTU_386} linux32 ./travis/debian-build.sh deb/ubuntu-i386/DIST
- ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/docs.sh
- ./travis/skip-pkg.sh || travis/prep-bintray.sh
deploy:
- provider: bintray
file: travis/bintray-autobuild-debian.json
user: $BINTRAY_USER
key: $BINTRAY_KEY
skip_cleanup: true
on:
branch: next
condition: $CC = gcc
- provider: bintray
file: travis/bintray-autobuild-ubuntu.json
user: $BINTRAY_USER
key: $BINTRAY_KEY
skip_cleanup: true
on:
branch: next
condition: $CC = gcc
- provider: script
script: travis/deploy-github-pages.sh
skip_cleanup: true
on:
branch: next
condition: $CC = gcc
after_deploy:
- travis/cleanup-bintray.pl i3-autobuild
- travis/cleanup-bintray.pl i3-autobuild-ubuntu

View File

@@ -1,5 +1,14 @@
Revision history for AnyEvent-I3
0.19 2024-04-09
* use Carp for errors (includes stacktraces)
* introduce (preferred) RUN_COMMAND spelling
* migrate tooling to ExtUtils::MakeMaker
* implement the tick event
* introduce the sync IPC command
* introduce the GET_BINDING_STATE IPC command
0.18 2017-08-19
* support the GET_CONFIG command

View File

@@ -8,7 +8,6 @@ use AnyEvent::Handle;
use AnyEvent::Socket;
use AnyEvent;
use Encode;
use Scalar::Util qw(tainted);
use Carp;
=head1 NAME
@@ -17,11 +16,11 @@ AnyEvent::I3 - communicate with the i3 window manager
=cut
our $VERSION = '0.18';
our $VERSION = '0.19';
=head1 VERSION
Version 0.18
Version 0.19
=head1 SYNOPSIS
@@ -100,11 +99,14 @@ use constant TYPE_GET_VERSION => 7;
use constant TYPE_GET_BINDING_MODES => 8;
use constant TYPE_GET_CONFIG => 9;
use constant TYPE_SEND_TICK => 10;
use constant TYPE_SYNC => 11;
use constant TYPE_GET_BINDING_STATE => 12;
our %EXPORT_TAGS = ( 'all' => [
qw(i3 TYPE_RUN_COMMAND TYPE_COMMAND TYPE_GET_WORKSPACES TYPE_SUBSCRIBE TYPE_GET_OUTPUTS
TYPE_GET_TREE TYPE_GET_MARKS TYPE_GET_BAR_CONFIG TYPE_GET_VERSION
TYPE_GET_BINDING_MODES TYPE_GET_CONFIG TYPE_SEND_TICK)
TYPE_GET_BINDING_MODES TYPE_GET_CONFIG TYPE_SEND_TICK TYPE_SYNC
TYPE_GET_BINDING_STATE)
] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
@@ -129,35 +131,10 @@ sub i3 {
AnyEvent::I3->new(@_)
}
# Calls i3, even when running in taint mode.
sub _call_i3 {
my ($args) = @_;
my $path_tainted = tainted($ENV{PATH});
# This effectively circumvents taint mode checking for $ENV{PATH}. We
# do this because users might specify PATH explicitly to call i3 in a
# custom location (think ~/.bin/).
(local $ENV{PATH}) = ($ENV{PATH} =~ /(.*)/);
# In taint mode, we also need to remove all relative directories from
# PATH (like . or ../bin). We only do this in taint mode and warn the
# user, since this might break a real-world use case for some people.
if ($path_tainted) {
my @dirs = split /:/, $ENV{PATH};
my @filtered = grep !/^\./, @dirs;
if (scalar @dirs != scalar @filtered) {
$ENV{PATH} = join ':', @filtered;
warn qq|Removed relative directories from PATH because you | .
qq|are running Perl with taint mode enabled. Remove -T | .
qq|to be able to use relative directories in PATH. | .
qq|New PATH is "$ENV{PATH}"|;
}
}
# Otherwise the qx() operator wont work:
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
chomp(my $result = qx(i3 $args));
# Circumventing taint mode again: the socket can be anywhere on the
# system and thats okay.
if ($result =~ /^([^\0]+)$/) {
return $1;
}
@@ -179,21 +156,21 @@ instance on the current DISPLAY which is almost always what you want.
sub new {
my ($class, $path) = @_;
$path = _call_i3('--get-socketpath') unless $path;
# This is the old default path (v3.*). This fallback line can be removed in
# a year from now. -- Michael, 2012-07-09
$path ||= '~/.i3/ipc.sock';
# We have I3SOCK now
$path ||= $ENV{I3SOCK};
$path ||= _call_i3('--get-socketpath');
# Check if we need to resolve ~
if ($path =~ /~/) {
# We use getpwuid() instead of $ENV{HOME} because the latter is tainted
# and thus produces warnings when running tests with perl -T
my $home = (getpwuid($<))[7];
my $home = $ENV{HOME};
confess "Could not get home directory" unless $home and -d $home;
$path =~ s/~/$home/g;
}
if(!-S $path) {
die "$path is not a socket", $/;
}
bless { path => $path } => $class;
}
@@ -312,6 +289,11 @@ sub subscribe {
# Register callbacks for each message type
for my $key (keys %{$callbacks}) {
if (!exists $events{$key}) {
warn "Could not subscribe to event type '$key'." .
" Supported events are " . join(" ", sort keys %events), $/;
next;
}
my $type = $events{$key};
$self->{callbacks}->{$type} = $callbacks->{$key};
}
@@ -534,6 +516,19 @@ sub send_tick {
$self->message(TYPE_SEND_TICK, $payload);
}
=head2 sync
Sends an i3 sync event. Requires i3 >= 4.16
=cut
sub sync {
my ($self, $payload) = @_;
$self->_ensure_connection;
$self->message(TYPE_SYNC, $payload);
}
=head2 command($content)
Makes i3 execute the given command

View File

@@ -1,4 +1,4 @@
#!perl -T
#!perl
use Test::More tests => 1;

View File

@@ -1,4 +1,4 @@
#!perl -T
#!perl
# vim:ts=4:sw=4:expandtab
use Test::More tests => 3;

View File

@@ -1,4 +1,4 @@
#!perl -T
#!perl
# vim:ts=4:sw=4:expandtab
use Test::More tests => 3;

View File

@@ -1,4 +1,4 @@
#!perl -T
#!perl
use strict;
use warnings;

View File

@@ -1,4 +1,4 @@
#!perl -T
#!perl
use strict;
use warnings;

View File

@@ -1,4 +1,4 @@
#!perl -T
#!perl
use strict;
use warnings;

46
DEPENDS
View File

@@ -4,29 +4,29 @@
"min" means minimum required version
"lkgv" means last known good version
┌──────────────┬────────┬────────┬───────────────────────────────────────────────────────────┐
│ dependency │ min. │ lkgv │ URL │
├──────────────┼────────┼────────┼───────────────────────────────────────────────────────────┤
│ pkg-config │ 0.25 │ 0.29 │ https://pkgconfig.freedesktop.org/ │
│ libxcb │ 1.1.93 │ 1.12 │ https://xcb.freedesktop.org/dist/ │
│ xcb-util │ 0.3.3 │ 0.4.1 │ https://xcb.freedesktop.org/dist/ │
│ xkbcommon │ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/ │
│ xkbcommon-x11│ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/ │
│ util-cursor³⁴│ 0.0.99 │ 0.1.3 │ https://xcb.freedesktop.org/dist/ │
│ util-wm⁴ │ 0.3.8 │ 0.3.8 │ https://xcb.freedesktop.org/dist/ │
│ util-keysyms⁴│ 0.3.8 │ 0.4.0 │ https://xcb.freedesktop.org/dist/ │
│ util-xrm⁴ │ 1.0.0 │ 1.0.0 │ https://github.com/Airblader/xcb-util-xrm │
│ libev │ 4.0 │ 4.19 │ http://libev.schmorp.de/ │
│ yajl │ 2.0.1 │ 2.1.0 │ https://lloyd.github.com/yajl/ │
│ asciidoc │ 8.3.0 │ 8.6.9 │ http://www.methods.co.nz/asciidoc/ │
│ xmlto │ 0.0.23 │ 0.0.23 │ http://www.methods.co.nz/asciidoc/ │
│ Pod::Simple² │ 3.22 │ 3.22 │ http://search.cpan.org/~dwheeler/Pod-Simple-3.23/
│ docbook-xml │ 4.5 │ 4.5 │ http://www.methods.co.nz/asciidoc/ │
│ PCRE │ 8.12 │ 8.38 │ https://www.pcre.org/ │
│ libsn¹ │ 0.10 │ 0.12 │ https://freedesktop.org/wiki/Software/startup-notification │
│ pango │ 1.30.0 | 1.40.1 │ http://www.pango.org/ │
│ cairo │ 1.14.4 │ 1.14.6 │ https://cairographics.org/ │
└──────────────┴────────┴────────┴───────────────────────────────────────────────────────────┘
┌──────────────┬────────┬────────┬─────────────────────────────────────────────────────────────
│ dependency │ min. │ lkgv │ URL
├──────────────┼────────┼────────┼─────────────────────────────────────────────────────────────
│ pkg-config │ 0.25 │ 0.29 │ https://pkgconfig.freedesktop.org/
│ libxcb │ 1.1.93 │ 1.12 │ https://xcb.freedesktop.org/dist/
│ xcb-util │ 0.3.3 │ 0.4.1 │ https://xcb.freedesktop.org/dist/
│ xkbcommon │ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/
│ xkbcommon-x11│ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/
│ util-cursor³⁴│ 0.0.99 │ 0.1.3 │ https://xcb.freedesktop.org/dist/
│ util-wm⁴ │ 0.3.8 │ 0.3.8 │ https://xcb.freedesktop.org/dist/
│ util-keysyms⁴│ 0.3.8 │ 0.4.0 │ https://xcb.freedesktop.org/dist/
│ util-xrm⁴ │ 1.0.0 │ 1.0.0 │ https://github.com/Airblader/xcb-util-xrm/
│ libev │ 4.0 │ 4.19 │ http://libev.schmorp.de/
│ yajl │ 2.0.1 │ 2.1.0 │ https://lloyd.github.com/yajl/
│ asciidoc │ 8.3.0 │ 8.6.9 │ http://www.methods.co.nz/asciidoc/
│ xmlto │ 0.0.23 │ 0.0.23 │ http://www.methods.co.nz/asciidoc/
│ Pod::Simple² │ 3.22 │ 3.22 │ http://search.cpan.org/dist/Pod-Simple/
│ docbook-xml │ 4.5 │ 4.5 │ http://www.methods.co.nz/asciidoc/
│ PCRE │ 8.12 │ 8.38 │ https://www.pcre.org/
│ libsn¹ │ 0.10 │ 0.12 │ https://freedesktop.org/wiki/Software/startup-notification/
│ pango │ 1.30.0 1.40.1 │ http://www.pango.org/
│ cairo │ 1.14.4 │ 1.14.6 │ https://cairographics.org/
└──────────────┴────────┴────────┴─────────────────────────────────────────────────────────────
¹ libsn = libstartup-notification
² Pod::Simple is a Perl module required for converting the testsuite
documentation to HTML. See https://michael.stapelberg.de/cpan/#Pod::Simple

View File

@@ -1 +1 @@
4.15 (2018-03-10)
4.19.1-non-git

41
LICENSE
View File

@@ -1,27 +1,26 @@
Copyright © 2009, Michael Stapelberg and contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Michael Stapelberg nor the
names of contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Michael Stapelberg ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Michael Stapelberg BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,608 +0,0 @@
@CODE_COVERAGE_RULES@
echo-version:
@echo "@I3_VERSION@"
bin_PROGRAMS = \
i3 \
i3bar/i3bar \
i3-config-wizard/i3-config-wizard \
i3-dump-log/i3-dump-log \
i3-input/i3-input \
i3-msg/i3-msg \
i3-nagbar/i3-nagbar
install-exec-hook:
$(LN_S) -f i3 $(DESTDIR)$(bindir)/i3-with-shmlog
uninstall-hook:
rm -f $(DESTDIR)$(bindir)/i3-with-shmlog
i3includedir=$(includedir)/i3
i3include_HEADERS = \
include/i3/ipc.h
dist_bin_SCRIPTS = \
i3-dmenu-desktop \
i3-migrate-config-to-v4 \
i3-save-tree \
i3-sensible-editor \
i3-sensible-pager \
i3-sensible-terminal
i3confdir = $(sysconfdir)/i3
dist_i3conf_DATA = \
etc/config \
etc/config.keycodes
applicationsdir = $(datarootdir)/applications
xsessionsdir = $(datarootdir)/xsessions
dist_applications_DATA = \
share/applications/i3.desktop
dist_xsessions_DATA = \
share/xsessions/i3.desktop \
share/xsessions/i3-with-shmlog.desktop
noinst_LIBRARIES = libi3.a
check_PROGRAMS = \
test.commands_parser \
test.config_parser \
test.inject_randr15
check_SCRIPTS = \
testcases/complete-run.pl
check_DATA = \
anyevent-i3.stamp
clean-check:
rm -rf testsuite-* latest i3-cfg-for-* _Inline
clean-local: clean-check
TESTS = testcases/complete-run.pl
EXTRA_DIST = \
$(dist_docs_toc_DATA:.html=) \
$(dist_docs_notoc_DATA:.html=) \
AnyEvent-I3/Changes \
AnyEvent-I3/MANIFEST \
AnyEvent-I3/MANIFEST.SKIP \
AnyEvent-I3/Makefile.PL \
AnyEvent-I3/README \
AnyEvent-I3/lib/AnyEvent/I3.pm \
AnyEvent-I3/t/00-load.t \
AnyEvent-I3/t/01-workspaces.t \
AnyEvent-I3/t/02-sugar.t \
AnyEvent-I3/t/boilerplate.t \
AnyEvent-I3/t/manifest.t \
AnyEvent-I3/t/pod-coverage.t \
AnyEvent-I3/t/pod.t \
contrib/dump-asy.pl \
contrib/gtk-tree-watch.pl \
contrib/i3-wsbar \
contrib/per-workspace-layout.pl \
contrib/trivial-bar-script.sh \
docs/asciidoc-git.conf \
docs/bigpicture.png \
docs/i3-pod2html \
docs/i3-sync.dia \
docs/i3-sync.png \
docs/i3-sync-working.dia \
docs/i3-sync-working.png \
docs/keyboard-layer1.png \
docs/keyboard-layer2.png \
docs/layout-saving-1.png \
docs/logo-30.png \
docs/modes.png \
docs/refcard.html \
docs/refcard_style.css \
docs/single_terminal.png \
docs/snapping.png \
docs/tree-layout1.png \
docs/tree-layout2.png \
docs/tree-shot1.png \
docs/tree-shot2.png \
docs/tree-shot3.png \
docs/tree-shot4.png \
docs/two_columns.png \
docs/two_terminals.png \
docs/wsbar.dia \
docs/wsbar.png \
i3bar/LICENSE \
libi3/README \
$(asciidoc_MANS:.1=.man) \
$(asciidoc_MANS:.1=.man) \
man/asciidoc.conf.in \
DEPENDS \
I3_VERSION \
LICENSE \
PACKAGE-MAINTAINER \
RELEASE-NOTES-4.15 \
generate-command-parser.pl \
parser-specs/commands.spec \
parser-specs/config.spec \
parser-specs/highlighting.vim \
pseudo-doc.doxygen \
testcases/complete-run.pl.in \
testcases/i3-test.config \
testcases/lib/i3test/Test.pm \
testcases/lib/i3test/Util.pm \
testcases/lib/i3test/XTEST.pm \
testcases/lib/i3test.pm.in \
testcases/lib/SocketActivation.pm \
testcases/lib/StartXServer.pm \
testcases/lib/StatusLine.pm \
testcases/lib/TestWorker.pm \
testcases/Makefile.PL \
testcases/new-test \
testcases/restart-state.golden \
testcases/t \
testcases/valgrind.supp
# dirstamps contains directories which we want to be created in $(top_builddir)
# so that our custom rules can store files in them.
dirstamp = .dirstamp
dirstamps = \
docs/$(dirstamp) \
man/$(dirstamp) \
parser/$(dirstamp)
DISTCLEANFILES = $(dirstamps)
$(dirstamps):
@stamp='$@'; $(MKDIR_P) "$${stamp%/*}"
@: > $@
################################################################################
# docs generation
################################################################################
docs_tocdir = ${docdir}
docs_notocdir = ${docdir}
docs_poddir = ${docdir}
if BUILD_DOCS
dist_docs_toc_DATA = \
docs/hacking-howto.html \
docs/userguide.html \
docs/ipc.html \
docs/multi-monitor.html \
docs/wsbar.html \
docs/testsuite.html \
docs/i3bar-protocol.html \
docs/layout-saving.html
dist_docs_notoc_DATA = \
docs/debugging.html
dist_docs_pod_DATA = \
docs/lib-i3test.html \
docs/lib-i3test-test.html
$(dist_docs_toc_DATA): docs/%.html: docs/% docs/$(dirstamp)
$(AM_V_GEN) @PATH_ASCIIDOC@ -a toc -n -o $@ $<
$(dist_docs_notoc_DATA): docs/%.html: docs/% docs/$(dirstamp)
$(AM_V_GEN) @PATH_ASCIIDOC@ -n -o $@ $<
docs/lib-i3test.html: testcases/lib/i3test.pm docs/$(dirstamp)
$(AM_V_GEN) $(top_srcdir)/docs/i3-pod2html $< $@
docs/lib-i3test-test.html: testcases/lib/i3test/Test.pm docs/$(dirstamp)
$(AM_V_GEN) $(top_srcdir)/docs/i3-pod2html $< $@
else
dist_docs_toc_DATA =
dist_docs_notoc_DATA =
dist_docs_pod_DATA =
endif
################################################################################
# manpage generation
################################################################################
if BUILD_MANS
dist_man1_MANS = \
$(asciidoc_MANS) \
$(pod_MANS)
asciidoc_MANS = \
man/i3.1 \
man/i3bar.1 \
man/i3-msg.1 \
man/i3-input.1 \
man/i3-nagbar.1 \
man/i3-config-wizard.1 \
man/i3-migrate-config-to-v4.1 \
man/i3-sensible-editor.1 \
man/i3-sensible-pager.1 \
man/i3-sensible-terminal.1 \
man/i3-dump-log.1
pod_MANS = \
man/i3-dmenu-desktop.1 \
man/i3-save-tree.1
$(asciidoc_MANS): man/%.1: man/%.xml man/$(dirstamp)
$(AM_V_GEN) out='$@'; @PATH_XMLTO@ man -o "$${out%/*}" $<
@stamp='$@'; $(MKDIR_P) "$${stamp%/*}"
man/%.xml: man/%.man man/asciidoc.conf man/$(dirstamp)
$(AM_V_GEN) @PATH_ASCIIDOC@ -d manpage -b docbook -f $(top_builddir)/man/asciidoc.conf -o $@ $<
$(pod_MANS): man/%.1: % man/$(dirstamp)
$(AM_V_GEN) @PATH_POD2MAN@ --utf8 $< > $@
else
asciidoc_MANS =
endif
AM_CPPFLAGS = \
-DSYSCONFDIR="\"$(sysconfdir)\"" \
-I$(top_builddir)/parser \
-I$(top_srcdir)/include \
@AX_EXTEND_SRCDIR_CPPFLAGS@
i3_CFLAGS = \
$(AM_CFLAGS) \
$(libi3_CFLAGS) \
$(LIBSN_CFLAGS) \
$(XCB_CFLAGS) \
$(XCB_UTIL_CURSOR_CFLAGS) \
$(XCB_UTIL_KEYSYM_CFLAGS) \
$(XCB_UTIL_WM_CFLAGS) \
$(XCB_UTIL_XRM_CFLAGS) \
$(XKBCOMMON_CFLAGS) \
$(YAJL_CFLAGS) \
$(LIBPCRE_CFLAGS) \
$(PTHREAD_CFLAGS) \
$(CODE_COVERAGE_CFLAGS)
i3_CPPFLAGS = \
$(AM_CPPFLAGS) \
$(CODE_COVERAGE_CPPFLAGS)
i3_LDADD = \
$(libi3_LIBS) \
$(LIBSN_LIBS) \
$(XCB_LIBS) \
$(XCB_UTIL_CURSOR_LIBS) \
$(XCB_UTIL_KEYSYMS_LIBS) \
$(XCB_UTIL_WM_LIBS) \
$(XCB_UTIL_XRM_LIBS) \
$(XKBCOMMON_LIBS) \
$(YAJL_LIBS) \
$(LIBPCRE_LIBS) \
$(PANGOCAIRO_LIBS) \
$(PTHREAD_LIBS) \
$(CODE_COVERAGE_LDFLAGS)
libi3_CFLAGS = \
$(AM_CFLAGS) \
$(XCB_CFLAGS) \
$(XCB_UTIL_CFLAGS) \
$(XCB_UTIL_XRM_CFLAGS) \
$(YAJL_CFLAGS) \
$(PANGOCAIRO_CFLAGS)
libi3_LIBS = \
$(top_builddir)/libi3.a \
$(XCB_LIBS) \
$(XCB_UTIL_LIBS) \
$(XCB_UTIL_XRM_LIBS) \
$(YAJL_LIBS) \
$(PANGOCAIRO_LIBS)
libi3_a_CFLAGS = \
$(libi3_CFLAGS)
libi3_a_SOURCES = \
include/libi3.h \
libi3/dpi.c \
libi3/draw_util.c \
libi3/fake_configure_notify.c \
libi3/font.c \
libi3/format_placeholders.c \
libi3/get_colorpixel.c \
libi3/get_config_path.c \
libi3/get_exe_path.c \
libi3/get_mod_mask.c \
libi3/get_process_filename.c \
libi3/get_visualtype.c \
libi3/ipc_connect.c \
libi3/ipc_recv_message.c \
libi3/ipc_send_message.c \
libi3/is_debug_build.c \
libi3/mkdirp.c \
libi3/resolve_tilde.c \
libi3/root_atom_contents.c \
libi3/safewrappers.c \
libi3/string.c \
libi3/strndup.c \
libi3/ucs2_conversion.c
i3_dump_log_i3_dump_log_CFLAGS = \
$(AM_CFLAGS) \
$(PTHREAD_CFLAGS) \
$(libi3_CFLAGS)
i3_dump_log_i3_dump_log_LDADD = \
$(PTHREAD_LIBS) \
$(libi3_LIBS)
i3_dump_log_i3_dump_log_SOURCES = \
i3-dump-log/main.c
i3_input_i3_input_CFLAGS = \
$(AM_CFLAGS) \
$(libi3_CFLAGS)
i3_input_i3_input_LDADD = \
$(libi3_LIBS) \
$(XCB_UTIL_KEYSYMS_LIBS)
i3_input_i3_input_SOURCES = \
i3-input/i3-input.h \
i3-input/keysym2ucs.c \
i3-input/keysym2ucs.h \
i3-input/main.c
i3_msg_i3_msg_CFLAGS = \
$(AM_CFLAGS) \
$(libi3_CFLAGS)
i3_msg_i3_msg_LDADD = \
$(libi3_LIBS)
i3_msg_i3_msg_SOURCES = \
i3-msg/main.c
i3_nagbar_i3_nagbar_CFLAGS = \
$(AM_CFLAGS) \
$(libi3_CFLAGS)
i3_nagbar_i3_nagbar_LDADD = \
$(libi3_LIBS) \
$(XCB_UTIL_CURSOR_LIBS)
i3_nagbar_i3_nagbar_SOURCES = \
i3-nagbar/atoms.xmacro \
i3-nagbar/i3-nagbar.h \
i3-nagbar/main.c
i3bar_i3bar_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(top_srcdir)/i3bar/include
i3bar_i3bar_CFLAGS = \
$(AM_CFLAGS) \
$(libi3_CFLAGS) \
$(XCB_CFLAGS) \
$(XKBCOMMON_CFLAGS) \
$(PANGOCAIRO_CFLAGS) \
$(YAJL_CFLAGS)
i3bar_i3bar_LDADD = \
$(libi3_LIBS) \
$(XCB_LIBS) \
$(XCB_UTIL_CURSOR_LIBS) \
$(XKBCOMMON_LIBS) \
$(PANGOCAIRO_LIBS) \
$(YAJL_LIBS)
i3bar_i3bar_SOURCES = \
i3bar/include/child.h \
i3bar/include/common.h \
i3bar/include/configuration.h \
i3bar/include/ipc.h \
i3bar/include/mode.h \
i3bar/include/outputs.h \
i3bar/include/parse_json_header.h \
i3bar/include/trayclients.h \
i3bar/include/util.h \
i3bar/include/workspaces.h \
i3bar/include/xcb_atoms.def \
i3bar/include/xcb.h \
i3bar/src/child.c \
i3bar/src/config.c \
i3bar/src/ipc.c \
i3bar/src/main.c \
i3bar/src/mode.c \
i3bar/src/outputs.c \
i3bar/src/parse_json_header.c \
i3bar/src/workspaces.c \
i3bar/src/xcb.c
i3_config_wizard_i3_config_wizard_CFLAGS = \
$(AM_CFLAGS) \
$(libi3_CFLAGS) \
$(XKBCOMMON_CFLAGS)
i3_config_wizard_i3_config_wizard_LDADD = \
$(libi3_LIBS) \
$(XCB_UTIL_KEYSYMS_LIBS) \
$(XKBCOMMON_LIBS)
i3_config_wizard_i3_config_wizard_SOURCES = \
i3-config-wizard/atoms.xmacro \
i3-config-wizard/main.c \
i3-config-wizard/xcb.h
test_inject_randr15_CPPFLAGS = \
$(AM_CPPFLAGS)
test_inject_randr15_CFLAGS = \
$(AM_CFLAGS) \
$(i3_CFLAGS)
test_inject_randr15_SOURCES = \
testcases/inject_randr1.5.c
test_inject_randr15_LDADD = \
$(i3_LDADD)
test_commands_parser_CPPFLAGS = \
$(AM_CPPFLAGS) \
-DTEST_PARSER
test_commands_parser_CFLAGS = \
$(AM_CFLAGS) \
$(i3_CFLAGS)
test_commands_parser_SOURCES = \
src/commands_parser.c
test_commands_parser_LDADD = \
$(i3_LDADD)
test_config_parser_CPPFLAGS = \
$(AM_CPPFLAGS) \
-DTEST_PARSER
test_config_parser_CFLAGS = \
$(AM_CFLAGS) \
$(i3_CFLAGS)
test_config_parser_SOURCES = \
src/config_parser.c
test_config_parser_LDADD = \
$(i3_LDADD)
command_parser_SOURCES = \
parser/GENERATED_command_enums.h \
parser/GENERATED_command_tokens.h \
parser/GENERATED_command_call.h
config_parser_SOURCES = \
parser/GENERATED_config_enums.h \
parser/GENERATED_config_tokens.h \
parser/GENERATED_config_call.h
i3_SOURCES = \
$(command_parser_SOURCES) \
$(config_parser_SOURCES) \
include/all.h \
include/assignments.h \
include/atoms_NET_SUPPORTED.xmacro \
include/atoms_rest.xmacro \
include/atoms.xmacro \
include/bindings.h \
include/click.h \
include/cmdparse.h \
include/commands.h \
include/commands_parser.h \
include/config_directives.h \
include/configuration.h \
include/config_parser.h \
include/con.h \
include/data.h \
include/display_version.h \
include/ewmh.h \
include/fake_outputs.h \
include/floating.h \
include/handlers.h \
include/i3.h \
include/ipc.h \
include/key_press.h \
include/load_layout.h \
include/log.h \
include/main.h \
include/manage.h \
include/match.h \
include/move.h \
include/output.h \
include/queue.h \
include/randr.h \
include/regex.h \
include/render.h \
include/resize.h \
include/restore_layout.h \
include/scratchpad.h \
include/sd-daemon.h \
include/shmlog.h \
include/sighandler.h \
include/startup.h \
include/tree.h \
include/util.h \
include/window.h \
include/workspace.h \
include/xcb.h \
include/xcursor.h \
include/x.h \
include/xinerama.h \
include/yajl_utils.h \
src/assignments.c \
src/bindings.c \
src/click.c \
src/commands.c \
src/commands_parser.c \
src/con.c \
src/config.c \
src/config_directives.c \
src/config_parser.c \
src/display_version.c \
src/ewmh.c \
src/fake_outputs.c \
src/floating.c \
src/handlers.c \
src/ipc.c \
src/key_press.c \
src/load_layout.c \
src/log.c \
src/main.c \
src/manage.c \
src/match.c \
src/move.c \
src/output.c \
src/randr.c \
src/regex.c \
src/render.c \
src/resize.c \
src/restore_layout.c \
src/scratchpad.c \
src/sd-daemon.c \
src/sighandler.c \
src/startup.c \
src/tree.c \
src/util.c \
src/version.c \
src/window.c \
src/workspace.c \
src/x.c \
src/xcb.c \
src/xcursor.c \
src/xinerama.c
################################################################################
# parser generation
################################################################################
$(command_parser_SOURCES): %.h: i3-command-parser.stamp
$(config_parser_SOURCES): %.h: i3-config-parser.stamp
src/i3-commands_parser.$(OBJEXT): i3-command-parser.stamp
src/i3-config_parser.$(OBJEXT): i3-config-parser.stamp
i3-command-parser.stamp: parser/$(dirstamp) generate-command-parser.pl parser-specs/commands.spec
$(AM_V_GEN) $(top_srcdir)/generate-command-parser.pl --input=$(top_srcdir)/parser-specs/commands.spec --prefix=command
$(AM_V_at) mv GENERATED_command_* $(top_builddir)/parser
$(AM_V_at) touch $@
i3-config-parser.stamp: parser/$(dirstamp) generate-command-parser.pl parser-specs/config.spec
$(AM_V_GEN) $(top_srcdir)/generate-command-parser.pl --input=$(top_srcdir)/parser-specs/config.spec --prefix=config
$(AM_V_at) mv GENERATED_config_* $(top_builddir)/parser
$(AM_V_at) touch $@
################################################################################
# AnyEvent-I3 build process
################################################################################
anyevent-i3.stamp: AnyEvent-I3/lib/AnyEvent/I3.pm
$(AM_V_BUILD) (cd $(top_srcdir)/AnyEvent-I3 && perl Makefile.PL && make)
$(AM_V_at) touch $@
CLEANFILES = \
i3-command-parser.stamp \
i3-config-parser.stamp \
anyevent-i3.stamp

View File

@@ -21,12 +21,14 @@ i3-sensible-terminal is used in the default configuration.
If your distribution has a mechanism to get the preferred terminal, such as the
x-terminal-emulator symlink in Debian, please use it in i3-sensible-terminal.
On debian, compilation and installing the manpages looks like this:
You can build i3 like you build any other software package which uses
https://mesonbuild.com/; see
https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project
In case youre unfamiliar:
autoreconf -fi
mkdir -p build && cd build
../configure
make -j8 install
$ mkdir -p build && cd build
$ meson setup
$ ninja
Please make sure that i3-migrate-config-to-v4 and i3-config-wizard are
installed with i3. The Perl script is necessary to (automatically) convert v3
@@ -35,10 +37,8 @@ config with the users preferred modifier and should be started on the first
start of i3 (it will automatically exit if it finds a config file).
If you have any questions, ideas, hints, problems or whatever, please do not
hesitate to contact me. I will help you out. Just drop me an E-Mail (find the
address at https://michael.stapelberg.de/Impressum/, scroll down to bottom),
contact me using the same address in jabber or ask on our IRC channel:
(#i3 on irc.freenode.net).
hesitate to contact me. I will help you out. Please see
https://i3wm.org/contact/
Thanks again for your efforts,
Michael

View File

@@ -1,9 +1,12 @@
![Logo](docs/logo-30.png) i3: A tiling window manager
=====================================================
[![Build Status](https://travis-ci.org/i3/i3.svg?branch=next)](https://travis-ci.org/i3/i3)
[![Issue Stats](http://www.issuestats.com/github/i3/i3/badge/issue?style=flat)](http://www.issuestats.com/github/i3/i3)
[![Pull Request Stats](http://www.issuestats.com/github/i3/i3/badge/pr?style=flat)](http://www.issuestats.com/github/i3/i3)
[![Build Status](https://github.com/i3/i3/actions/workflows/main.yml/badge.svg)](https://github.com/i3/i3/actions/workflows/main.yml)
[![Issue Stats](https://img.shields.io/github/issues/i3/i3.svg)](https://github.com/i3/i3/issues)
[![Pull Request Stats](https://img.shields.io/github/issues-pr/i3/i3.svg)](https://github.com/i3/i3/pulls)
[![Packages](https://repology.org/badge/latest-versions/i3.svg)](https://repology.org/metapackage/i3/versions)
[![Packages](https://repology.org/badge/tiny-repos/i3.svg)](https://repology.org/metapackage/i3/versions)
i3 is a tiling window manager for X11.

View File

@@ -1,113 +0,0 @@
┌────────────────────────────┐
│ Release notes for i3 v4.15 │
└────────────────────────────┘
This is i3 v4.15. This version is considered stable. All users of i3 are
strongly encouraged to upgrade.
Aside from a number of fixes and documentation improvements, a number of
commands have been extended to be more complete (e.g. “assign”, “resize”).
┌────────────────────────────┐
│ Changes in i3 v4.15 │
└────────────────────────────┘
• build: AnyEvent::I3 moved to the i3 repository, so that its main consumer,
the i3 testsuite, can use new features immediately (such as the tick event,
in this case).
• docs/hacking-howto: promote “using git / sending patches” and “how to
build?” sections
• docs/i3bar-protocol: document that pango markup only works with pango fonts
• docs/ipc: document focus, nodes, floating_nodes
• docs/ipc: urgent: complete the list of container types
• docs/ipc: document how to detect i3s byte order in memory-safe languages
• docs/ipc: document the GET_CONFIG request
• docs/userguide: fix formatting issue
• docs/userguide: explain why Mod4 is usually preferred as a modifier
• docs/userguide: use more idiomatic english (full-size, so-called)
• docs/userguide: switch from removed goto command to focus
• docs/userguide: mention <criteria> in focus
• docs/userguide: remove outdated 2013 last-modified date
• dump-asy: add prerequisite checks
• dump-asy: fix warnings about empty container names
• i3-dump-log: enable shmlog on demand
• i3-sensible-terminal: add “kitty”, “guake”, “tilda”
• i3-sensible-editor: add “gvim”
• i3bar: add --release flag for bindsym in bar blocks
• i3bar: add relative coordinates in JSON for click events
• ipc: rename COMMAND to RUN_COMMAND for consistency
• ipc: implement tick event for less flaky tests
• ipc: add error reply to “focus <window_mode>”
• ipc: send success response for nop
• default config: add $mod+r to toggle resize mode
• default config: use variables for workspace names to avoid repetition
• introduce “assign <criteria> [→] [workspace] [number] <workspace>”
• introduce “assign <criteria> [→] output left|right|up|down|primary|<output>”
• introduce a “focus_wrapping” option (subsumes “force_focus_wrapping”)
• introduce percentage point resizing for floating containers:
“resize set <width> [px | ppt] <height> [px | ppt]”
• introduce “resize set <width> ppt <height> ppt” for tiling windows
• rename “new_window” and “new_float” to “default_border” and
“default_floating_border” (the old names keep working)
• output names (e.g. “DP2”) can now be used as synonyms for monitor names
(e.g. “Dell UP2414Q”).
• the “swap” command now works with fullscreen windows
• raise floating windows to top when they are focused programmatically
• _NET_ACTIVE_WINDOW: invalidate focus to force SetInputFocus call
• make focus handling consistent when changing focus between outputs
• round non-integer Xft.dpi values
• tiling resize: remove minimum size
┌────────────────────────────┐
│ Bugfixes │
└────────────────────────────┘
• i3bar: fix various memory leaks
• i3bar: fix crash when no status_command is provided
• fix uninitialized variables in init_dpi_end, tree_restore
• fix incorrectly set up signal handling
• fix “swap” debug log message
• fix crash when specifying invalid con_id for “swap”
• fix crash upon restart with window marks
• fix crash when config file does not end in a newline
• fix crash in append_layout
• fix crash in layout toggle command
• fix crash when switching monitors
• fix use-after-free in randr_init error path
• fix move accidentally moving windows across outputs
• fix crash when floating window is tiled while being resized
• fix out-of-bounds memory read
• fix memory leak when config conversion fails
• fix layout toggle split, which didnt work until enabling tabbed/stack mode
once
• move XCB event handling into xcb_prepare_cb
• avert endless loop on unexpected EOF in ipc messages
• perform proper cleanup for signals with Term action
• dont match containers in the scratchpad with criteria
• fix “workspace show” related issues
• fix config file conversion with long variable names
• fix config file conversion memory initialization
• prevent access of freed workspace in _workspace_show
• disable fullscreen when required when programmatically focusing windows
• free last_motion_notify
• dont raise floating windows when focused because of focus_follows_mouse
• correctly set EWMH atoms when closing a workspace
• dont raise floating windows when workspace is shown
• keep focus order when encapsulating workspaces
• validate layout files before loading
┌────────────────────────────┐
│ Thanks! │
└────────────────────────────┘
Thanks for testing, bugfixes, discussions and everything I forgot go out to:
Alex Lu, Ben Creasy, Bennett Piater, Cast, chressie, clonejo, Dan Elkouby,
Daniel Mueller, DebianWall, Diki Ananta, Edward Betts, hwangcc23, Ingo Bürk,
Jan Alexander Steffens, Johannes Lange, Kent Fredric, livanh, Martin
T. H. Sandsmark, Michael Siegel, Orestis Floros, Pallav Agarwal, Pawel
S. Veselov, Pietro Cerutti, Theo Buehler, Thomas Praxl, Tyler Brazier,
Vladimir Panteleev, walker0643, Wes Roberts, xzfc
-- Michael Stapelberg, 2018-03-10

62
RELEASE-NOTES-4.24 Normal file
View File

@@ -0,0 +1,62 @@
┌──────────────────────────────┐
│ Release notes for i3 v4.24 │
└──────────────────────────────┘
This is i3 v4.24. This version is considered stable. All users of i3 are
strongly encouraged to upgrade.
Aside from a number of bug fixes and detail improvements, the tiling drag
feature has been extended to allow swapping containers with the mouse.
See the swap_modifier in the userguide:
https://i3wm.org/docs/userguide.html
┌────────────────────────────┐
│ Changes in i3 v4.24 │
└────────────────────────────┘
• docs/userguide: add note to default_border about title bar in stacked/tabbed
• docs/userguide: fix focus output next example
• docs/hacking-howto: update build instructions
• docs/testsuite: update instructions
• docs/ipc: update section on IPC socket location
• docs/ipc: describe workspace events in more detail
• i3-sensible-terminal: add rio
• i3bar: use short-form text on a per-block basis
• reap zombie children when starting
• do not grab mouse pointer when executing bindings
• tiling drag: swap containers with the mouse
• disable automatic v3-to-v4 migration script
• pass _NET_WM_STATE_MAXIMIZED_{HORZ, VERT} (fixes tab bar in Google Chrome)
• avoid creating redundant containers when switching between layouts
• deprecate smart_borders in favour of hide_edge_borders smart/smart_no_gaps
• float windows of type _NET_WM_WINDOW_TYPE_NOTIFICATION by default
• add “popup_during_fullscreen all”
• mark fullscreen windows as maximized
• support multiple _NET_WM_STATE changes in one ClientMessage
• fix size_t format specifiers on 32-bit systems
┌────────────────────────────┐
│ Bugfixes │
└────────────────────────────┘
• i3bar: fix clicks when horizontal padding is used
• consider workspace_auto_back_and_forth in focus workspace
• workspace next/prev: do not skip identically numbered workspaces
• make order of numbered workspace consistent with non-numbered
• fix crash with focus output and command criteria matching scratchpad window
• fix crash when reloading config with invalid criteria
• fix error log related crash
┌────────────────────────────┐
│ Thanks! │
└────────────────────────────┘
Thanks for testing, bugfixes, discussions and everything I forgot go out to:
a-kenji, Alessandro Vinciguerra, Bimba Laszlo, colona_, Eddie Lebow, Harimbola
Santatra, Junicchi, Malix, Nikolay Nechaev, Orestis Floros, rsgowman,
sethpollen, Seth Pollen, systec-awe, Tasos Sahanidis, Theo Buehler, Wesley
Schwengle, Yonas Yanfa, yuvallangerontheroad
-- Michael Stapelberg, 2024-11-06

View File

@@ -1,181 +0,0 @@
# -*- Autoconf -*-
# Run autoreconf -fi to generate a configure script from this file.
AC_PREREQ([2.69])
AC_INIT([i3], [4.15], [https://github.com/i3/i3/issues])
# For AX_EXTEND_SRCDIR
AX_ENABLE_BUILDDIR
AM_INIT_AUTOMAKE([foreign subdir-objects -Wall no-dist-gzip dist-bzip2])
# Default to silent rules, use V=1 to get verbose compilation output.
AM_SILENT_RULES([yes])
# Make it possible to disable maintainer mode to disable re-generation of build
# system files.
AM_MAINTAINER_MODE([enable])
AC_CONFIG_SRCDIR([libi3/ipc_recv_message.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
dnl Verify macros defined in m4/ such as AX_SANITIZERS are not present in the
dnl output, i.e. are replaced as expected. This line results in a better error
dnl message when using aclocal < 1.13 (which does not understand
dnl AC_CONFIG_MACRO_DIR) without passing the -I m4 parameter.
m4_pattern_forbid([AX_SANITIZERS])
# Verify we are using GNU make because we use '%'-style pattern rules in
# Makefile.am, which are a GNU make extension. Pull requests to replace
# '%'-style pattern rules with a more portable alternative are welcome.
AX_CHECK_GNU_MAKE
AS_VAR_IF([_cv_gnu_make_command], [""], [AC_MSG_ERROR([the i3 Makefile.am requires GNU make])])
AX_EXTEND_SRCDIR
AS_IF([test -d ${srcdir}/.git],
[
VERSION="$(git -C ${srcdir} describe --tags --abbrev=0)"
I3_VERSION="$(git -C ${srcdir} describe --tags --always) ($(git -C ${srcdir} log --pretty=format:%cd --date=short -n1), branch \\\"$(git -C ${srcdir} describe --tags --always --all | sed s:heads/::)\\\")"
# Mirrors what libi3/is_debug_build.c does:
is_release=$(test $(echo "${I3_VERSION}" | cut -d '(' -f 1 | wc -m) -lt 10 && echo yes || echo no)
],
[
VERSION="$(cut -d '-' -f 1 ${srcdir}/I3_VERSION | cut -d ' ' -f 1)"
I3_VERSION="$(sed -e 's/@<:@\"?\\@:>@/\\&/g' ${srcdir}/I3_VERSION)"
is_release="$(grep -q non-git ${srcdir}/I3_VERSION && echo no || echo yes)"
])
AC_SUBST([I3_VERSION], [$I3_VERSION])
MAJOR_VERSION="$(echo ${VERSION} | cut -d '.' -f 1)"
MINOR_VERSION="$(echo ${VERSION} | cut -d '.' -f 2)"
PATCH_VERSION="$(echo ${VERSION} | cut -d '.' -f 3)"
AS_IF([test "x${PATCH_VERSION}" = x], [PATCH_VERSION=0])
AC_DEFINE_UNQUOTED([I3_VERSION], ["${I3_VERSION}"], [i3 version])
AC_DEFINE_UNQUOTED([MAJOR_VERSION], [${MAJOR_VERSION}], [i3 major version])
AC_DEFINE_UNQUOTED([MINOR_VERSION], [${MINOR_VERSION}], [i3 minor version])
AC_DEFINE_UNQUOTED([PATCH_VERSION], [${PATCH_VERSION}], [i3 patch version])
AX_CODE_COVERAGE
dnl is_release must be lowercase because AX_CHECK_ENABLE_DEBUG calls m4_tolower
dnl on its fourth argument.
AX_CHECK_ENABLE_DEBUG([yes], , [UNUSED_NDEBUG], [$is_release])
AC_PROG_CC_C99
# For strnlen() and vasprintf().
AC_USE_SYSTEM_EXTENSIONS
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
dnl The error message should include the specific type which could not be
dnl found, but I do not see a way to achieve that.
AC_CHECK_TYPES([mode_t, off_t, pid_t, size_t, ssize_t], , [AC_MSG_FAILURE([cannot find required type])])
# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
AC_FUNC_STRNLEN
AC_CHECK_FUNCS([atexit dup2 ftruncate getcwd gettimeofday localtime_r memchr memset mkdir rmdir setlocale socket strcasecmp strchr strdup strerror strncasecmp strndup strrchr strspn strstr strtol strtoul], , [AC_MSG_FAILURE([cannot find the $ac_func function, which i3 requires])])
# Checks for libraries.
AC_SEARCH_LIBS([floor], [m], , [AC_MSG_FAILURE([cannot find the required floor() function despite trying to link with -lm])])
# libev does not ship with a pkg-config file :(.
AC_SEARCH_LIBS([ev_run], [ev], , [AC_MSG_FAILURE([cannot find the required ev_run() function despite trying to link with -lev])])
AC_SEARCH_LIBS([shm_open], [rt])
AC_SEARCH_LIBS([iconv_open], [iconv], , [AC_MSG_FAILURE([cannot find the required iconv_open() function despite trying to link with -liconv])])
AX_PTHREAD
dnl Each prefix corresponds to a source tarball which users might have
dnl downloaded in a newer version and would like to overwrite.
PKG_CHECK_MODULES([LIBSN], [libstartup-notification-1.0])
PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr])
PKG_CHECK_MODULES([XCB_UTIL], [xcb-event xcb-util])
PKG_CHECK_MODULES([XCB_UTIL_CURSOR], [xcb-cursor])
PKG_CHECK_MODULES([XCB_UTIL_KEYSYMS], [xcb-keysyms])
PKG_CHECK_MODULES([XCB_UTIL_WM], [xcb-icccm])
PKG_CHECK_MODULES([XCB_UTIL_XRM], [xcb-xrm])
PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon xkbcommon-x11])
PKG_CHECK_MODULES([YAJL], [yajl])
PKG_CHECK_MODULES([LIBPCRE], [libpcre >= 8.10])
PKG_CHECK_MODULES([PANGOCAIRO], [cairo >= 1.14.4 pangocairo])
# Checks for programs.
AC_PROG_AWK
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_PROG_LN_S
AC_PATH_PROG([PATH_ASCIIDOC], [asciidoc])
AC_PATH_PROG([PATH_XMLTO], [xmlto])
AC_PATH_PROG([PATH_POD2MAN], [pod2man])
AM_CONDITIONAL([BUILD_MANS], [test x$PATH_ASCIIDOC != x && test x$PATH_XMLTO != x && test x$PATH_POD2MAN != x])
AM_CONDITIONAL([BUILD_DOCS], [test x$PATH_ASCIIDOC != x])
AM_PROG_AR
AX_FLAGS_WARN_ALL
AX_CHECK_COMPILE_FLAG([-Wunused-value], [AX_APPEND_FLAG([-Wunused-value], [AM_CFLAGS])])
AC_SUBST(AM_CFLAGS)
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h float.h inttypes.h limits.h locale.h netinet/in.h paths.h stddef.h stdint.h stdlib.h string.h sys/param.h sys/socket.h sys/time.h unistd.h], , [AC_MSG_FAILURE([cannot find the $ac_header header, which i3 requires])])
AC_CONFIG_FILES([Makefile testcases/lib/i3test.pm man/asciidoc.conf])
AC_CONFIG_FILES([testcases/complete-run.pl], [chmod +x testcases/complete-run.pl])
# Enable address sanitizer for non-release builds. The performance hit is a
# 50% increase of wallclock time for the testsuite on my machine.
if test x$is_release = xyes; then
default_sanitizers=
else
default_sanitizers=address
fi
AX_SANITIZERS(, [$default_sanitizers], [AC_DEFINE([I3_ASAN_ENABLED], [], [Enable ASAN])])
AC_OUTPUT
if test -z "${BUILD_DOCS_TRUE}"; then
print_BUILD_DOCS=yes
else
print_BUILD_DOCS=no
fi
if test -z "${BUILD_MANS_TRUE}"; then
print_BUILD_MANS=yes
else
print_BUILD_MANS=no
fi
in_git_worktree=`git rev-parse --is-inside-work-tree 2>/dev/null`
if [[ "$in_git_worktree" = "true" ]]; then
git_dir=`git rev-parse --git-dir 2>/dev/null`
srcdir=`dirname "$git_dir"`
exclude_dir=`pwd | sed "s,^$srcdir,,g"`
if ! grep -q "^$exclude_dir" "$git_dir/info/exclude"; then
echo "$exclude_dir" >> "$git_dir/info/exclude"
fi
fi
echo \
"--------------------------------------------------------------------------------
build configured:
AS_HELP_STRING([i3 version:], [`echo ${I3_VERSION} | sed 's,\\\\,,g'`])
AS_HELP_STRING([is release version:], [${is_release}])
AS_HELP_STRING([build manpages:], [${print_BUILD_MANS}])
AS_HELP_STRING([build docs:], [${print_BUILD_DOCS}])
AS_HELP_STRING([enable debug flags:], [${ax_enable_debug}])
AS_HELP_STRING([code coverage:], [${CODE_COVERAGE_ENABLED}])
AS_HELP_STRING([enabled sanitizers:], [${ax_enabled_sanitizers}])
To compile, run:
cd `pwd` && make -j8
--------------------------------------------------------------------------------"

View File

@@ -319,7 +319,7 @@
<dc:title>steckdenis</dc:title>
</cc:Agent>
</dc:creator>
<dc:description>Logo for I3, an improved dynamic tiling window manager: http://i3.zekjur.net/</dc:description>
<dc:description>Logo for i3 - an improved tiling window manager: http://i3.zekjur.net/</dc:description>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
</cc:Work>

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -1,26 +1,35 @@
#!/usr/bin/env perl
# vim:ts=4:sw=4:expandtab
# renders the layout tree using asymptote
#
# ./dump-asy.pl
# will render the entire tree
# ./dump-asy.pl 'name'
# will render the tree starting from the node with the specified name,
# e.g. ./dump-asy.pl 2 will render workspace 2 and below
use strict;
use warnings;
use Data::Dumper;
use Getopt::Long;
use Pod::Usage;
use AnyEvent::I3;
use File::Temp;
use File::Spec;
use File::Basename;
use v5.10;
use IPC::Cmd qw[can_run];
my %options = (
gv => 1,
save => undef,
help => 0,
);
my $result = GetOptions(
"gv!" => \$options{gv},
"save=s" => \$options{save},
"help|?" => \$options{help},
);
pod2usage(-verbose => 2, -exitcode => 0) if $options{help};
# prerequisites check so we can be specific about failures caused
# by not having these tools in the path
can_run('asy') or die 'Please install asymptote';
can_run('gv') or die 'Please install gv';
can_run('gv') or die 'Please install gv' unless !$options{gv};
my $i3 = i3();
@@ -37,7 +46,7 @@ sub dump_node {
my $o = ($n->{orientation} eq 'none' ? "u" : ($n->{orientation} eq 'horizontal' ? "h" : "v"));
my $w = (defined($n->{window}) ? $n->{window} : "N");
my $na = ($n->{name} or "[Empty]");
my $na = ($n->{name} or ($n->{type} eq "floating_con" ? "[Floating con]" : "[Empty]"));
$na =~ s/#/\\#/g;
$na =~ s/\$/\\\$/g;
$na =~ s/&/\\&/g;
@@ -47,14 +56,16 @@ sub dump_node {
if (!defined($n->{window})) {
$type = $n->{layout};
}
my $name = qq|``$na'' ($type)|;
my $marks = $n->{marks} ? ' [' . join('][', @{$n->{marks}}) . ']' : '';
my $name = qq|``$na'' ($type)$marks|;
print $tmp "TreeNode n" . $n->{id} . " = makeNode(";
print $tmp "n" . $parent->{id} . ", " if defined($parent);
print $tmp "\"" . $name . "\");\n";
dump_node($_, $n) for @{$n->{nodes}};
dump_node($_, $n) for @{$n->{nodes}};
dump_node($_, $n) for @{$n->{floating_nodes}};
}
sub find_node_with_name {
@@ -82,5 +93,60 @@ say $tmp "draw(n" . $root->{id} . ", (0, 0));";
close($tmp);
my $rep = "$tmp";
$rep =~ s/asy$/eps/;
my $tmp_dir = dirname($rep);
system("cd $tmp_dir && asy $tmp && gv --scale=-1000 --noresize --widgetless $rep && rm $rep");
if ($options{gv}) {
my $tmp_dir = dirname($rep);
$options{save} = File::Spec->rel2abs($options{save}) if $options{save};
chdir($tmp_dir);
} else {
$rep = basename($rep); # Output in current dir.
}
system("asy $tmp"); # Create the .eps file.
system("gv --scale=-1000 --noresize --widgetless $rep") if $options{gv};
if ($options{save}) {
system("mv $rep ${options{save}}");
} elsif ($options{gv}) {
system("rm $rep");
}
system("rm $tmp");
__END__
=head1 NAME
dump-asy.pl - Render the layout tree using asymptote
=head1 SYNOPSIS
dump-asy.pl [workspace]
=head1 EXAMPLE
Render the entire tree, run:
./dump-asy.pl
Render the tree starting from the node with the specified name, run:
./dump-asy.pl 'name'
Render the entire tree, save in file 'file.eps' and show using gv, run:
./dump-asy.pl --save file.eps
=head1 OPTIONS
=over 8
=item B<--gv>
=item B<--no-gv>
Enable or disable showing the result through gv. If disabled, an .eps file will
be saved in the current working directory. Enabled by default.
=item B<--save>
Save result using the specified file-name. If omitted, no file will be saved
when using '--gv' or a random name will be used when using '--no-gv'.
=back

View File

@@ -329,7 +329,7 @@
<dc:title>steckdenis</dc:title>
</cc:Agent>
</dc:creator>
<dc:description>Logo for I3, an improved dynamic tiling window manager: http://i3.zekjur.net/</dc:description>
<dc:description>Logo for i3 - an improved tiling window manager: http://i3.zekjur.net/</dc:description>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
</cc:Work>

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

116
debian/changelog vendored
View File

@@ -1,8 +1,116 @@
i3-wm (4.14.2-1) unstable; urgency=medium
i3-wm (4.24-1) unstable; urgency=medium
* UNRELEASED
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Mon, 25 Sep 2017 08:55:22 +0200
-- Michael Stapelberg <stapelberg@debian.org> Wed, 06 Nov 2024 18:34:06 +0100
i3-wm (4.23-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Sun, 29 Oct 2023 15:42:11 +0100
i3-wm (4.22-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Mon, 02 Jan 2023 09:46:22 +0100
i3-wm (4.21.2-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Mon, 24 Oct 2022 21:22:36 +0200
i3-wm (4.21.1-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Mon, 24 Oct 2022 21:22:36 +0200
i3-wm (4.21-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Wed, 21 Sep 2022 18:14:14 +0200
i3-wm (4.20.1-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Wed, 03 Nov 2021 09:22:48 +0100
i3-wm (4.20-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Sat, 27 Feb 2021 10:32:17 +0100
i3-wm (4.19.2-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Sat, 27 Feb 2021 10:32:17 +0100
i3-wm (4.19-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Mon, 19 Oct 2020 22:48:30 +0200
i3-wm (4.18.3-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Mon, 19 Oct 2020 22:48:30 +0200
i3-wm (4.18.2-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Sun, 26 Jul 2020 10:24:46 +0200
i3-wm (4.18.1-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Wed, 22 Apr 2020 09:04:42 +0200
i3-wm (4.18-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Mon, 17 Feb 2020 18:25:47 +0100
i3-wm (4.17.1-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Fri, 30 Aug 2019 23:06:40 +0200
i3-wm (4.17-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Sat, 03 Aug 2019 15:14:28 +0200
i3-wm (4.16.1-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Sun, 27 Jan 2019 16:45:11 +0100
i3-wm (4.16-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Sun, 04 Nov 2018 14:47:25 +0100
i3-wm (4.15-1) unstable; urgency=medium
* New upstream release.
-- Michael Stapelberg <stapelberg@debian.org> Sat, 10 Mar 2018 17:27:26 +0100
i3-wm (4.14.1-1) unstable; urgency=medium
@@ -555,7 +663,7 @@ i3-wm (3.d-bf1-1) unstable; urgency=low
* Bugfix: Resize client after updating base_width/base_height
* Bugfix: Force render containers after setting the client active
* Bugfix: Fix two problems in resizing floating windows with right mouse
* Bugfix: Use more precise floating point arithmetics
* Bugfix: Use more precise floating point arithmetic
* Bugfix: Correctly place new windows below fullscreen windows
-- Michael Stapelberg <michael@stapelberg.de> Mon, 21 Dec 2009 22:33:02 +0100

2
debian/compat vendored
View File

@@ -1 +1 @@
9
10

11
debian/control vendored
View File

@@ -2,8 +2,8 @@ Source: i3-wm
Section: x11
Priority: extra
Maintainer: Michael Stapelberg <stapelberg@debian.org>
Build-Depends: debhelper (>= 9),
dh-autoreconf,
Build-Depends: debhelper (>= 10),
meson,
libx11-dev,
libxcb-util0-dev (>= 0.3.8),
libxcb-keysyms1-dev,
@@ -13,6 +13,7 @@ Build-Depends: debhelper (>= 9),
libxcb-cursor-dev,
libxcb-xrm-dev,
libxcb-xkb-dev,
libxcb-shape0-dev,
libxkbcommon-dev (>= 0.4.0),
libxkbcommon-x11-dev (>= 0.4.0),
asciidoc (>= 8.4.4),
@@ -21,7 +22,7 @@ Build-Depends: debhelper (>= 9),
pkg-config,
libev-dev (>= 1:4.04),
libyajl-dev (>= 2.0.4),
libpcre3-dev (>= 1:8.10),
libpcre2-dev,
libstartup-notification0-dev (>= 0.10),
libcairo2-dev (>= 1.14.4),
libpango1.0-dev,
@@ -40,10 +41,10 @@ Description: metapackage (i3 window manager, screen locker, menu, statusbar)
Package: i3-wm
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}, x11-utils
Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
Provides: x-window-manager
Recommends: xfonts-base, fonts-dejavu-core, libanyevent-i3-perl (>= 0.12), libjson-xs-perl, rxvt-unicode | x-terminal-emulator
Description: improved dynamic tiling window manager
Description: improved tiling window manager
Key features of i3 are good documentation, reasonable defaults (changeable in
a simple configuration file) and good multi-monitor support. The user
interface is designed for power users and emphasizes keyboard usage. i3 uses

32
debian/i3-wm.docs vendored
View File

@@ -1,32 +0,0 @@
docs/debugging.html
docs/hacking-howto.html
docs/i3bar-protocol.html
docs/userguide.html
docs/bigpicture.png
docs/single_terminal.png
docs/snapping.png
docs/two_columns.png
docs/two_terminals.png
docs/modes.png
docs/ipc.html
docs/multi-monitor.html
docs/wsbar.html
docs/wsbar.png
docs/keyboard-layer1.png
docs/keyboard-layer2.png
docs/testsuite.html
docs/i3-sync-working.png
docs/i3-sync.png
docs/tree-layout1.png
docs/tree-layout2.png
docs/tree-shot1.png
docs/tree-shot2.png
docs/tree-shot3.png
docs/tree-shot4.png
docs/refcard.html
docs/refcard_style.css
docs/logo-30.png
docs/lib-i3test.html
docs/lib-i3test-test.html
docs/layout-saving.html
docs/layout-saving-1.png

13
debian/i3-wm.manpages vendored
View File

@@ -1,13 +0,0 @@
man/i3.1
man/i3-msg.1
man/i3-input.1
man/i3-nagbar.1
man/i3-config-wizard.1
man/i3-dump-log.1
man/i3-migrate-config-to-v4.1
man/i3-sensible-pager.1
man/i3-sensible-editor.1
man/i3-sensible-terminal.1
man/i3-dmenu-desktop.1
man/i3-save-tree.1
man/i3bar.1

10
debian/rules vendored
View File

@@ -14,12 +14,8 @@ override_dh_auto_test:
# TODO: enable tests
override_dh_auto_configure:
# The default is /usr/share/doc/i3
dh_auto_configure -- --docdir=/usr/share/doc/i3-wm
override_dh_builddeb:
# bintray does not support xz currently.
dh_builddeb -- -Zgzip
# Set -Ddocdir; the default is /usr/share/doc/i3
dh_auto_configure -- -Ddocdir=/usr/share/doc/i3-wm -Dmans=true
%:
dh $@ --parallel --builddirectory=build --with=autoreconf
dh $@ --buildsystem=meson

View File

@@ -29,7 +29,7 @@
add_ignore_event, xcb_intern_atom, xcb_intern_atom_reply, fprintf, printf, free, load_configuration,%
XInternAtom, exit, strlen}}
}{}
\title{i3 - an improved dynamic tiling window manager}
\title{i3 - an improved tiling window manager}
\author{sECuRE beim NoName e.V.\\
~\\
powered by \LaTeX, of course}

19
docs/bigpicture.asy Normal file
View File

@@ -0,0 +1,19 @@
import drawtree;
treeLevelStep = 2cm;
TreeNode n94457831379296 = makeNode("``root'' (splith) []");
TreeNode n94457831380944 = makeNode(n94457831379296, "``\_\_i3'' (output) []");
TreeNode n94457831384048 = makeNode(n94457831380944, "``content'' (splith) []");
TreeNode n94457831387184 = makeNode(n94457831384048, "``\_\_i3\_scratch'' (splith) []");
TreeNode n94457831390576 = makeNode(n94457831379296, "``eDP-1'' (output) []");
TreeNode n94457831393744 = makeNode(n94457831390576, "``topdock'' (dockarea) []");
TreeNode n94457831396992 = makeNode(n94457831390576, "``content'' (splith) []");
TreeNode n94457831628304 = makeNode(n94457831396992, "``1'' (splith) []");
TreeNode n94457831571040 = makeNode(n94457831628304, "``Hacking i3: How To - Mozilla Firefox'' (leaf) []");
TreeNode n94457831246384 = makeNode(n94457831628304, "``vim'' (leaf) []");
TreeNode n94457831461088 = makeNode(n94457831396992, "``Named workspace'' (splith) []");
TreeNode n94457831471424 = makeNode(n94457831461088, "``[Empty]'' (tabbed) []");
TreeNode n94457831570576 = makeNode(n94457831471424, "``contrib/dump-asy.pl --no-gv'' (leaf) [Marks go here]");
TreeNode n94457831645488 = makeNode(n94457831471424, "``ipython'' (leaf) []");
TreeNode n94457831400192 = makeNode(n94457831390576, "``bottomdock'' (dockarea) []");
TreeNode n94457831424848 = makeNode(n94457831400192, "``i3bar for output eDP-1'' (leaf) []");
draw(n94457831379296, (0, 0));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

View File

@@ -147,20 +147,22 @@ After pressing "b" in the crash dialog, you will get a file called
id (PID) and the second one is incremented each time you generate a backtrace,
starting at 0.
== Sending bug reports/debugging on IRC
In Linux, if the backtrace just says +No stack.+, that's because gdb does not
have necessary permissions to attach to a running process. You can fix that by
running from a terminal (you can open a new tty, e.g. with ctrl-alt-F2):
When sending bug reports, please attach the *whole* log file. Even if you think
you found the section which clearly highlights the problem, additional
information might be necessary to completely diagnose the problem.
---------------------------------------------------------------------
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
---------------------------------------------------------------------
When debugging with us in IRC, be prepared to use a so-called nopaste service
such as https://pastebin.com because pasting large amounts of text in IRC
sometimes leads to incomplete lines (servers have line length limitations) or
flood kicks.
Afterwards, try re-generating the stack trace. Note that this setting re-sets
after reboot, see more info at
https://www.kernel.org/doc/Documentation/security/Yama.txt.
== Debugging i3bar
To debug i3bar problems, add +verbose yes+ to all +bar {}+ blocks in your i3
To debug i3bar problems, use the +--verbose+ commandline parameter,
or add +verbose yes+ to all +bar {}+ blocks in your i3
config, reload your config and then restart all i3bar instances like this:
---------------------------------------------------------------------

BIN
docs/gaps1920.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -8,83 +8,70 @@ touching i3s source code. It should contain all important information to help
you understand why things are like they are. If it does not mention something
you find necessary, please do not hesitate to contact me.
++++
<div style="background-color:red; color:white; padding:20px;">
<strong style="color:white;">WARNING!</strong>
<p>
++++
This document is not 100% up to date. Specifically, everything up to and
including <<startup>> has been updated recently. The rest might contain
outdated information.
++++
</p>
</div>
++++
== Building i3
You can build i3 like you build any other software package which uses autotools.
Heres a memory refresher:
You can build i3 like you build any other software package which uses
https://mesonbuild.com/[The Meson Build system]; see
https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project[Quickstart
Guide → Compiling a Meson project]. In case youre unfamiliar:
$ autoreconf -fi
$ mkdir -p build && cd build
$ ../configure
$ make -j8
(The autoreconf -fi step is unnecessary if you are building from a release tarball,
but shouldnt hurt either.)
mkdir -p build
meson setup build
meson compile -C build
=== Build system features
* We use the AX_ENABLE_BUILDDIR macro to enforce builds happening in a separate
directory. This is a prerequisite for the AX_EXTEND_SRCDIR macro and building
in a separate directory is common practice anyway. In case this causes any
trouble when packaging i3 for your distribution, please open an issue.
* +ninja test+ runs the i3 testsuite. See docs/testsuite for details.
* “make check” runs the i3 testsuite. See docs/testsuite for details.
* +meson dist+ builds a release tarball and runs tests on the result.
* “make distcheck” (runs testsuite on “make dist” result, tiny bit quicker
feedback cycle than waiting for the travis build to catch the issue).
* +meson -Ddocs=true -Dmans=true+ will enable the options to build docs and
manpages. These options require additional dependencies that are normally not
required for users who just want to build i3.
* “make uninstall” (occasionally requested by users who compile from source)
* +meson -Db_sanitize=address+ will enable the address sanitizer which is
disabled by default. A summary of memory leaks will be printed on program
exit. This can include false-positives. For other options of the +b_sanitize+
flag see https://mesonbuild.com/Builtin-options.html.
* “make” will build manpages/docs by default if the tools are installed.
Conversely, manpages/docs are not tried to be built for users who dont want
to install all these dependencies to get started hacking on i3.
* non-release builds will enable address sanitizer by default. Use the
--disable-sanitizers configure option to turn off all sanitizers, and see
--help for available sanitizers.
* Support for pre-compiled headers (PCH) has been dropped for now in the
interest of simplicity. If you need support for PCH, please open an issue.
* Coverage reports are now generated using “make check-code-coverage”, which
requires specifying --enable-code-coverage when calling configure.
== Using git / sending patches
For a short introduction into using git, see
https://web.archive.org/web/20121024222556/http://www.spheredev.org/wiki/Git_for_the_lazy
or, for more documentation, see https://git-scm.com/documentation
== Pull requests
Please talk to us before working on new features to see whether they will be
accepted. A good way for this is to open an issue and asking for opinions on it.
Even for accepted features, this can be a good way to refine an idea upfront. However,
we don't want to see certain features in i3, e.g., switching window focus in an
Alt+Tab like way.
Even for accepted features, this can be a good way to refine an idea upfront.
However, we don't want to see certain features in i3, e.g., switching window
focus in an Alt+Tab like way.
When working on bugfixes, please make sure you mention that you are working on
it in the corresponding bug report at https://github.com/i3/i3/issues. In case
there is no bug report yet, please create one.
When working on bugfixes, please make sure you mention that you are working on it
in the corresponding bug report at https://github.com/i3/i3/issues. In case there
is no bug report yet, please create one.
After you are done, please submit your work for review as a pull request at
https://github.com/i3/i3.
Do not send emails to the mailing list or any author directly, and dont submit
them in the bugtracker, since all reviews should be done in public at
https://github.com/i3/i3. In order to make your review go as fast as possible, you
could have a look at previous reviews and see what the common mistakes are.
https://github.com/i3/i3. In order to make your review go as fast as possible,
you could have a look at previous reviews and see what the common mistakes are.
=== Which branch to use?
Work on i3 generally happens in two branches: “master” and “next” (the latter
being the default branch, the one that people get when they check out the git
repository).
Work on i3 generally happens in two branches: “next” (default) and “stable”.
The contents of “master” are always stable. That is, it contains the source code
The contents of “stable” are always stable. That is, it contains the source code
of the latest release, plus any bugfixes that were applied since that release.
New features are only found in the “next” branch. Therefore, if you are working
on a new feature, use the “next” branch. If you are working on a bugfix, use the
“next” branch, too, but make sure your code also works on “master”.
New features are only found in the “next” branch. Always use this branch when
writing new code (both bugfixes and features).
== Window Managers
@@ -106,9 +93,9 @@ In the case of i3, the tasks (and order of them) are the following:
the first client of X) and manage them (reparent them, create window
decorations, etc.)
. When new windows are created, manage them
. Handle the clients `_WM_STATE` property, but only `_WM_STATE_FULLSCREEN` and
`_NET_WM_STATE_DEMANDS_ATTENTION`
. Handle the clients `WM_NAME` property
. Handle the clients +_WM_STATE+ property, but only +_WM_STATE_FULLSCREEN+ and
+_NET_WM_STATE_DEMANDS_ATTENTION+
. Handle the clients +WM_NAME+ property
. Handle the clients size hints to display them proportionally
. Handle the clients urgency hint
. Handle enter notifications (focus follows mouse)
@@ -123,11 +110,11 @@ will be discussed.
=== Tiling window managers
Traditionally, there are two approaches to managing windows: The most common
one nowadays is floating, which means the user can freely move/resize the
windows. The other approach is called tiling, which means that your window
manager distributes windows to use as much space as possible while not
overlapping each other.
Traditionally, there are two approaches to managing windows: The most common one
nowadays is stacking (or floating, using i3's terminology), which means the user
can freely move/resize the windows, potentially overlapping them. The other
approach is called tiling, which means that the window manager distributes
windows to use as much space as possible while not overlapping each other.
The idea behind tiling is that you should not need to waste your time
moving/resizing windows while you usually want to get some work done. After
@@ -161,63 +148,67 @@ example.
== Files
include/atoms.xmacro::
A file containing all X11 atoms which i3 uses. This file will be included
various times (for defining, requesting and receiving the atoms), each time
with a different definition of xmacro().
i3's source code is in the +src+ folder while header files reside in +include+.
Other tools such as i3bar and i3-nagbar have their own folders. i3 and its tools
share an internal library called ``libi3'' which also has its own folder.
The following list gives an overview of the codebase, explaining the
functionality of the most important, core source code files. Other files in the
tree that are not mentioned here implement specific functionalities: for example,
+src/scratchpad.c+ is obviously about the scratchpad functionality.
include/data.h::
Contains data definitions used by nearly all files. You really need to read
this first.
Contains data definitions used by nearly all files.
include/*.h::
Contains forward definitions for all public functions, as well as
doxygen-compatible comments (so if you want to get a bit more of the big
picture, either browse all header files or use doxygen if you prefer that).
src/config_parser.c::
Contains a custom configuration parser. See src/command_parser.c for rationale
on why we use a custom parser.
src/click.c::
Contains all functions which handle mouse button clicks (right mouse button
clicks initiate resizing and thus are relatively complex).
src/command_parser.c::
Contains a hand-written parser to parse commands (commands are what
you bind on keys and what you can send to i3 using the IPC interface, like
'move left' or 'workspace 4').
src/config_directives.c::
src/commands.c::
Contain the definitions for all high-level config and command directives. These
are excellent places to start with a top-to-bottom approach to understand
specific i3 behavior. For example, if you want to investigate a bug that happens
for the +move to mark+ command, you can use gdb to pause in
+cmd_move_con_to_mark+ and then work your way from there, stepping into
lower-level functions.
src/con.c::
Contains all functions which deal with containers directly (creating
containers, searching containers, getting specific properties from containers,
…).
Contains all functions which deal with containers directly (creating containers,
searching containers, getting specific properties from containers, …). Contains
abstractions and auxiliary functions necessary to work with the container
structure which is used in almost all parts of the codebase.
src/config.c::
Contains all functions handling the configuration file (calling the parser
src/config_parser.c) with the correct path, switching key bindings mode).
src/tree.c::
Contains functions which deal with the tree abstraction. However, be aware that
+src/con.c+ also contains functions that heavily interact with the tree
structure. Some functions that are included in +str/tree.c+ are those that handle
opening and closing containers in the tree, finding the container that should be
focused next and flattening the tree. See also +src/move.c+ for other
move-specific functions that interact with the tree, which were moved into their
own file because they are so long.
src/ewmh.c::
Functions to get/set certain EWMH properties easily.
src/floating.c::
Contains functions for floating mode (mostly resizing/dragging).
src/workspace.c::
Contains functions which deal with workspaces. Includes code that creates new
workspaces, shows existing ones and deals with workspace assignments.
src/handlers.c::
Contains all handlers for all kinds of X events (new window title, new hints,
unmapping, key presses, button presses, …).
unmapping, key presses, button presses, …). This is a very important file to
understand how i3 interacts with changes to its environment.
src/ipc.c::
Contains code for the IPC interface.
src/command_parser.c::
src/config_parser.c::
Contain a hand-written parser to parse commands and configuration (commands are what
you bind on keys and what you can send to i3 using the IPC interface, like
+move left+ or +workspace 4+). +src/config.c+ is responsible for calling the
configuration parser.
src/load_layout.c::
Contains code for loading layouts from JSON files.
src/log.c::
Contains the logging functions.
src/main.c::
Initializes the window manager.
src/click.c::
src/resize.c::
Contain functions which handle mouse button clicks (right mouse button
clicks initiate resizing and thus are relatively complex).
src/manage.c::
Looks at existing or new windows and decides whether to manage them. If so, it
@@ -226,93 +217,66 @@ reparents the window and inserts it into our data structures.
src/match.c::
A "match" is a data structure which acts like a mask or expression to match
certain windows or not. For example, when using commands, you can specify a
command like this: [title="*Firefox*"] kill. The title member of the match
command like this: +[title="*Firefox*"] kill+. The title member of the match
data structure will then be filled and i3 will check each window using
match_matches_window() to find the windows affected by this command.
src/move.c::
Contains code to move a container in a specific direction.
src/output.c::
Functions to handle CT_OUTPUT cons.
+match_matches_window()+ to find the windows affected by this command.
src/randr.c::
The RandR API is used to get (and re-query) the configured outputs (monitors,
…).
…). Legacy Xinerama support resides in +src/xinerama.c+.
src/render.c::
Renders the tree data structure by assigning coordinates to every node. These
values will later be pushed to X11 in +src/x.c+.
src/resize.c::
Contains the functions to resize containers.
src/restore_layout.c::
Everything for restored containers that is not pure state parsing (which can be
found in load_layout.c).
src/sighandler.c::
Handles +SIGSEGV+, +SIGABRT+ and +SIGFPE+ by showing a dialog that i3 crashed.
You can chose to let it dump core, to restart it in-place or to restart it
in-place but forget about the layout.
src/tree.c::
Contains functions which open or close containers in the tree, change focus or
cleanup ("flatten") the tree. See also +src/move.c+ for another similar
function, which was moved into its own file because it is so long.
src/util.c::
Contains useful functions which are not really dependent on anything.
You can choose to let it dump core and restart i3 in-place (either trying to
preserve layout or forget about it).
src/window.c::
Handlers to update X11 window properties like +WM_CLASS+, +_NET_WM_NAME+,
+CLIENT_LEADER+, etc.
src/workspace.c::
Contains all functions related to workspaces (displaying, hiding, renaming…)
src/x.c::
Transfers our in-memory tree (see +src/render.c+) to X11.
src/xcb.c::
Contains wrappers to use xcb more easily.
src/xcursor.c::
XCursor functions (for cursor themes).
src/xinerama.c::
Legacy support for Xinerama. See +src/randr.c+ for the preferred API.
include/*.xmacro.*::
A file containing all X11 atoms which i3 uses. This file will be included
various times (for defining, requesting and receiving the atoms), each time
with a different definition of xmacro().
[[data_structures]]
== Data structures
See +include/data.h+ for documented data structures. The most important ones are
explained here.
See include/data.h for documented data structures. The most important ones are
explained right here.
The following picture is generated by the +contrib/dump-asy.pl+ script.
/////////////////////////////////////////////////////////////////////////////////
// TODO: update image
image:bigpicture.png["The Big Picture",width=1000,link="bigpicture.png"]
image:bigpicture.png[The Big Picture]
The hierarchy is:
/////////////////////////////////////////////////////////////////////////////////
So, the hierarchy is:
. *X11 root window*, the root container
. *Output container* (LVDS1 in this example)
. *Content container* (there are also containers for dock windows)
. *Workspaces* (Workspace 1 in this example, with horizontal orientation)
. *Split container* (vertically split)
. *X11 window containers*
. *Root container*
. *Output containers*: +eDP-1+ in this example and the internal +__i3++ output
. *Content and 2 dockarea containers*
. *Workspaces*: Numbered workspace ``1'' and a ``Named workspace''
. *Split containers*: One horizontal in the first workspace and a tabbed one in
the named one.
. *Leaf containers*: Windows like vim and an i3bar dock.
The data type is +Con+, in all cases.
=== X11 root window
=== Root container
The X11 root window is a single window per X11 display (a display is identified
by +:0+ or +:1+ etc.). The root window is what you draw your background image
on. It spans all the available outputs, e.g. +VGA1+ is a specific part of the
root window and +LVDS1+ is a specific part of the root window.
The root container (global variable +croot+) is the up-most ascendant of every i3
container. It can be used to iterate over the whole tree structure. E.g., it is
used to reply to the +GET_WORKSPACES+ request, iterating over it's children to
find all workspaces. This is different from the X11 root window.
The X11 root window (global variable +root+) is a single window per X11 display
(a display is identified by +:0+ or +:1+ etc.). The root window is what you draw
your background image on. It spans all the available outputs, e.g. +VGA1+ is a
specific part of the root window and +LVDS1+ is a specific part of the root
window.
=== Output container
@@ -334,8 +298,8 @@ currently on.
=== Content container
Each output has multiple children. Two of them are dock containers which hold
dock clients. The other one is the content container, which holds the actual
content (workspaces) of this output.
the top and bottom dock clients. The other one is the content container, which
holds the actual content (workspaces) of this output.
=== Workspace
@@ -354,42 +318,37 @@ vertical) and a layout.
Split containers (and X11 window containers, which are a subtype of split
containers) can have different border styles.
=== X11 window container
=== Leaf containers
An X11 window container holds exactly one X11 window. These are the leaf nodes
of the layout tree, they cannot have any children.
A leaf container holds exactly one X11 window. They can't have any children.
== List/queue macros
i3 makes heavy use of the list macros defined in BSD operating systems. To
ensure that the operating system on which i3 is compiled has all the expected
features, i3 comes with `include/queue.h`. On BSD systems, you can use man
`queue(3)`. On Linux, you have to use google (or read the source).
features, i3 comes with +include/queue.h+. On BSD systems, you can use +man
queue(3)+. On Linux, you have to use google (or read the source).
The lists used are +SLIST+ (single linked lists), +CIRCLEQ+ (circular
queues) and +TAILQ+ (tail queues). Usually, only forward traversal is necessary,
so an `SLIST` works fine. If inserting elements at arbitrary positions or at
the end of a list is necessary, a +TAILQ+ is used instead. However, for the
windows inside a container, a +CIRCLEQ+ is necessary to go from the currently
selected window to the window above/below.
The lists used are +SLIST+ (single linked lists), +CIRCLEQ+ (circular queues)
and +TAILQ+ (tail queues). Usually, +TAILQ+ is used which allows inserting
elements at arbitrary positions or at the end of the list. If only forward
traversal is necessary, an +SLIST+ can be used. +CIRCLEQ+ is used just to
manage the X11 state of each window.
== Naming conventions
[[startup]]
== Startup (src/main.c, main())
There is a row of standard variables used in many events. The following names
should be chosen for those:
* ``conn'' is the xcb_connection_t
* ``event'' is the event of the particular type
* ``con'' names a container
* ``current'' is a loop variable when using +TAILQ_FOREACH+ etc.
== Startup (src/mainx.c, main())
Among other things, the main() function does the following:
* Establish the xcb connection
* Load the i3 config
* Check for XKB extension on the separate X connection, load Xcursor
* Check for RandR screens (with a fall-back to Xinerama)
* Set up EWMH hints
* Grab the keycodes for which bindings exist
* Check for XRandR screens
* Manage all existing windows
* Exec configured startup processes
* Start i3bar if configured
* Enter the event loop
== Keybindings
@@ -425,12 +384,12 @@ the correct state.
Then, it looks through all bindings and gets the one which matches the received
event.
The bound command is parsed by the cmdparse lexer/parser, see +parse_cmd+ in
+src/cmdparse.y+.
The bound command is parsed by the i3 parser, see +parse_command+ in
+src/commands_parser.c+.
== Manage windows (src/main.c, manage_window() and reparent_window())
`manage_window()` does some checks to decide whether the window should be
+manage_window()+ does some checks to decide whether the window should be
managed at all:
* Windows have to be mapped, that is, visible on screen
@@ -438,18 +397,18 @@ managed at all:
not be managed by a window manager
Afterwards, i3 gets the initial geometry and reparents the window (see
`reparent_window()`) if it wasnt already managed.
+reparent_window()+) if it wasnt already managed.
Reparenting means that for each window which is reparented, a new window,
slightly larger than the original one, is created. The original window is then
reparented to the bigger one (called "frame").
After reparenting, the window type (`_NET_WM_WINDOW_TYPE`) is checked to see
whether this window is a dock (`_NET_WM_WINDOW_TYPE_DOCK`), like dzen2 for
After reparenting, the window type (+_NET_WM_WINDOW_TYPE+) is checked to see
whether this window is a dock (+_NET_WM_WINDOW_TYPE_DOCK+), like dzen2 for
example. Docks are handled differently, they dont have decorations and are not
assigned to a specific container. Instead, they are positioned at the bottom
or top of the screen (in the appropriate dock area containers). To get the
height which needs to be reserved for the window, the `_NET_WM_STRUT_PARTIAL`
height which needs to be reserved for the window, the +_NET_WM_STRUT_PARTIAL+
property is used.
Furthermore, the list of assignments (to other workspaces, which may be on
@@ -460,10 +419,10 @@ target workspace is not visible, the window will not be mapped.
== What happens when an application is started?
i3 does not care about applications. All it notices is when new windows are
mapped (see `src/handlers.c`, `handle_map_request()`). The window is then
mapped (see +src/handlers.c+, +handle_map_request()+). The window is then
reparented (see section "Manage windows").
After reparenting the window, `render_tree()` is called which renders the
After reparenting the window, +render_tree()+ is called which renders the
internal layout table. The new window has been placed in the currently focused
container and therefore the new window and the old windows (if any) need to be
moved/resized so that the currently active layout (default/stacking/tabbed mode)
@@ -482,7 +441,7 @@ can reconfigure themselves).
Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms
are handled.
The former calls ``toggle_fullscreen()'' for the specific client which just
The former calls +toggle_fullscreen()+ for the specific client which just
configures the client to use the whole screen on which it currently is.
Also, it is set as fullscreen_client for the i3Screen.
@@ -539,7 +498,7 @@ container) to the bottom.
=== Rendering the root container
The i3 root container (`con->type == CT_ROOT`) represents the X11 root window.
The i3 root container (+con->type == CT_ROOT+) represents the X11 root window.
It contains one child container for every output (like LVDS1, VGA1, …), which
is available on your computer.
@@ -558,7 +517,7 @@ only called for the global fullscreen window.
=== Rendering an output
Output containers (`con->layout == L_OUTPUT`) represent a hardware output like
Output containers (+con->layout == L_OUTPUT+) represent a hardware output like
LVDS1, VGA1, etc. An output container has three children (at the moment): One
content container (having workspaces as children) and the top/bottom dock area
containers.
@@ -566,7 +525,7 @@ containers.
The rendering happens in the function +render_l_output()+ in the following
steps:
1. Find the content container (`con->type == CT_CON`)
1. Find the content container (+con->type == CT_CON+)
2. Get the currently visible workspace (+con_get_fullscreen_con(content,
CF_OUTPUT)+).
3. If there is a fullscreened window on that workspace, directly render it and
@@ -574,24 +533,22 @@ steps:
4. Sum up the space used by all the dock windows (they have a variable height
only).
5. Set the workspace rects (x/y/width/height) based on the position of the
output (stored in `con->rect`) and the usable space
(`con->rect.{width,height}` without the space used for dock windows).
output (stored in +con->rect+) and the usable space
(+con->rect.{width,height}+ without the space used for dock windows).
6. Recursively raise and render the outputs child containers (meaning dock
area containers and the content container).
=== Rendering a workspace or split container
From here on, there really is no difference anymore. All containers are of
`con->type == CT_CON` (whether workspace or split container) and some of them
have a `con->window`, meaning they represent an actual window instead of a
+con->type == CT_CON+ (whether workspace or split container) and some of them
have a +con->window+, meaning they represent an actual window instead of a
split container.
==== Default layout
In default layout, containers are placed horizontally or vertically next to
each other (depending on the `con->orientation`). If a child is a leaf node (as
opposed to a split container) and has border style "normal", appropriate space
will be reserved for its window decoration.
each other (depending on the +con->orientation+).
==== Stacked layout
@@ -835,8 +792,8 @@ workspace <direction>::
the beginning. +
NOTE: Note that you can specify multiple literals in the same line. This has
exactly the same effect as if you specified `direction =
'next_on_output' -> call cmd_workspace($direction)` and so forth. +
exactly the same effect as if you specified +direction =
'next_on_output' -> call cmd_workspace($direction)+ and so forth. +
NOTE: Also note that the order of literals is important here: If 'next' were
ordered before 'next_on_output', then 'next_on_output' would never
@@ -1020,11 +977,11 @@ Without much ado, here is the list of cases which need to be considered:
== Gotchas
* Forgetting to call `xcb_flush(conn);` after sending a request. This usually
* Forgetting to call +xcb_flush(conn);+ after sending a request. This usually
leads to code which looks like it works fine but which does not work under
certain conditions.
* Forgetting to call `floating_fix_coordinates(con, old_rect, new_rect)` after
* Forgetting to call +floating_fix_coordinates(con, old_rect, new_rect)+ after
moving workspaces across outputs. Coordinates for floating containers are
not relative to workspace boundaries, so you must correct their coordinates
or those containers will show up in the wrong workspace or not at all.

View File

@@ -4,8 +4,14 @@
use strict;
use warnings;
use Pod::Simple::HTML;
use Getopt::Long;
use v5.10;
my $stylesurl = '';
GetOptions("stylesurl=s" => \$stylesurl)
or die "parsing flags";
$Pod::Simple::HTML::Tagmap{'Verbatim'} = '<pre><tt>';
$Pod::Simple::HTML::Tagmap{'VerbatimFormatted'} = '<pre><tt>';
$Pod::Simple::HTML::Tagmap{'/Verbatim'} = '</tt></pre>';
@@ -22,8 +28,9 @@ open(my $out, '>', $ARGV[1]) or die "Couldnt open $ARGV[1] for writing: $!\n"
my $parser = Pod::Simple::HTML->new();
$parser->index(1);
$parser->html_header_before_title(
<<'EOF'
if ($stylesurl ne '') {
$parser->html_header_before_title(
<<EOF
<!doctype html>
<html lang="en">
<head>
@@ -31,7 +38,7 @@ $parser->html_header_before_title(
<meta charset="utf-8">
<meta name="generator" content="Pod::Simple::HTML">
<meta name="description" content="i3 Perl documentation">
<link rel="stylesheet" href="https://i3wm.org/css/style.css" type="text/css" />
<link rel="stylesheet" href="$stylesurl/style.css" type="text/css" />
<style type="text/css">
.pod pre {
background: #333;
@@ -63,7 +70,8 @@ tt {
</style>
<title>
EOF
);
);
}
$parser->html_header_after_title(
<<'EOF'
</title>
@@ -75,7 +83,7 @@ $parser->html_header_after_title(
<ul id="nav">
<li><a style="border-bottom: 2px solid #fff" href="/docs">Docs</a></li>
<li><a href="/screenshots">Screens</a></li>
<li><a href="https://www.reddit.com/r/i3wm/">FAQ</a></li>
<li><a href="https://www.github.com/i3/i3/discussions">Get Help</a></li>
<li><a href="/contact">Contact</a></li>
<li><a href="https://bugs.i3wm.org/">Bugs</a></li>
</ul>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -103,11 +103,13 @@ https://github.com/i3/i3/blob/next/contrib/trivial-bar-script.sh
version::
The version number (as an integer) of the i3bar protocol you will use.
stop_signal::
Specify to i3bar the signal (as an integer) to send to stop your
processing.
The default value (if none is specified) is SIGSTOP.
Specify the signal (as an integer) that i3bar should send to request that you
pause your output. This is used to conserve battery power when the bar is
hidden by not unnecessarily computing bar updates. The default value is SIGSTOP,
which will unconditionally stop your process. If this is an issue, this feature
can be disabled by setting the value to 0.
cont_signal::
Specify to i3bar the signal (as an integer)to send to continue your
Specify to i3bar the signal (as an integer) to send to continue your
processing.
The default value (if none is specified) is SIGCONT.
click_events::
@@ -118,7 +120,8 @@ click_events::
full_text::
The +full_text+ will be displayed by i3bar on the status line. This is the
only required key.
only required key. If +full_text+ is an empty string, the block will be
skipped.
short_text::
Where appropriate, the +short_text+ (string) entry should also be
provided. It will be used in case the status line needs to be shortened
@@ -140,6 +143,18 @@ background::
Overrides the background color for this particular block.
border::
Overrides the border color for this particular block.
border_top::
Defines the width (in pixels) of the top border of this block. Defaults
to 1.
border_right::
Defines the width (in pixels) of the right border of this block. Defaults
to 1.
border_bottom::
Defines the width (in pixels) of the bottom border of this block. Defaults
to 1.
border_left::
Defines the width (in pixels) of the left border of this block. Defaults
to 1.
min_width::
The minimum width (in pixels) of the block. If the content of the
+full_text+ key take less space than the specified min_width, the block
@@ -176,7 +191,7 @@ separator_block_width::
is 9 pixels), since the separator line is drawn in the middle.
markup::
A string that indicates how the text of the block should be parsed. Set to
+"pango"+ to use https://developer.gnome.org/pango/stable/PangoMarkupFormat.html[Pango markup].
+"pango"+ to use https://developer.gnome.org/pango/1.46/[Pango markup].
Set to +"none"+ to not use any markup (default). Pango markup only works
if you use a pango font.
@@ -214,13 +229,18 @@ An example of a block which uses all possible entries follows:
"color": "#00ff00",
"background": "#1c1c1c",
"border": "#ee0000",
"border_top": 1,
"border_right": 0,
"border_bottom": 3,
"border_left": 1,
"min_width": 300,
"align": "right",
"urgent": false,
"name": "ethernet",
"instance": "eth0",
"separator": true,
"separator_block_width": 9
"separator_block_width": 9,
"markup": "none"
}
------------------------------------------
@@ -240,8 +260,13 @@ button::
relative_x, relative_y::
Coordinates where the click occurred, with respect to the top left corner
of the block
output_x, output_y::
Coordinates relative to the current output where the click occurred
width, height::
Width and height (in px) of the block
modifiers::
An array of the modifiers active when the click occurred. The order in which
modifiers are listed is not guaranteed.
*Example*:
------------------------------------------
@@ -249,10 +274,13 @@ width, height::
"name": "ethernet",
"instance": "eth0",
"button": 1,
"x": 1320,
"modifiers": ["Shift", "Mod1"],
"x": 1925,
"y": 1400,
"relative_x": 12,
"relative_y": 8,
"output_x": 5,
"output_y": 1400,
"width": 50,
"height": 22
}

View File

@@ -0,0 +1,184 @@
i3bar workspace buttons protocol
================================
This document explains the protocol in which i3bar expects input for
configuring workspace buttons. This feature is available since i3 version 4.23.
The program defined by the +workspace_command+ configuration option for i3bar can
modify the workspace buttons displayed by i3bar. The command should constantly
print in its standard output a stream of messages following the protocol
defined in this page.
If you are looking for the status line protocol instead, see https://i3wm.org/docs/i3bar-protocol.html.
== The protocol
Each message should be a newline-delimited JSON array. The array is in the same
format as the +GET_WORKSPACES+ ipc event, see
https://i3wm.org/docs/ipc.html#_workspaces_reply.
As an example, this is the output of the +i3-msg -t get_workspaces+ command:
------------------------------
[
{
"id": 94131549984064,
"num": 1,
"name": "1",
"visible": false,
"focused": false,
"output": "HDMI-A-0",
"urgent": false
},
{
"id": 94131550477584,
"num": 2,
"name": "2",
"visible": true,
"focused": true,
"output": "HDMI-A-0",
"urgent": false
},
{
"id": 94131550452704,
"num": 3,
"name": "3:some workspace",
"visible": false,
"focused": false,
"output": "HDMI-A-0",
"urgent": false
}
]
------------------------------
Please note that this example was pretty printed for human consumption, with
the +"rect"+ field removed. Workspace button commands should output each array
in one line.
Each element in the array represents a workspace. i3bar creates one workspace
button for each element in the array. The order of these buttons is the same as
the order of the elements in the array.
In general, we recommend subscribing to the +workspace+ and +output+
https://i3wm.org/docs/ipc.html#_workspace_event[events],
fetching the current workspace information with +GET_WORKSPACES+, modifying the
JSON array in the response according to your needs and then printing it to the
standard output. However, you are free to build a new message from the ground
up.
=== Workspace objects in detail
The documentation of +GET_WORKSPACES+ should be sufficient to understand the
meaning of each property but here we provide extra notes for each property and
its meaning with respect to i3bar.
All properties but +name+ are optional.
id (integer)::
If it is included it will be used to switch to that workspace when you
click the corresponding button. If it's not provided, the +name+ will be
used. You can use the +id+ field to present workspaces under a modified
name.
num (integer)::
The only use of a workspace's number is if the +strip_workspace_numbers+
setting is enabled.
name (string)::
The only required property. If an +id+ is provided you can freely change
the +name+ as you wish, effectively renaming the buttons of i3bar.
visible (boolean)::
Defaults to +false+ if not included. +focused+ takes precedence over it,
however +visible+ is important for more than one monitor.
focused (boolean)::
Defaults to +false+ if not included. Generally, exactly one of the
workspaces should be +focused+. If not, no button will have the
+focused_workspace+ color.
urgent (boolean)::
Defaults to +false+ if not included.
rect (map)::
Not used by i3bar but will be ignored.
output (string)::
Defaults to the primary output if not included.
== Examples
These example scripts require the https://stedolan.github.io/jq/[jq] utility to
be installed but otherwise just use the standard +i3-msg+ utility included with
i3. However, you can write your own scripts in your preferred language, with
the help of one of the
https://i3wm.org/docs/ipc.html#_see_also_existing_libraries[pre-existing i3
libraries]
=== Base configuration
------------------------------
bar {
workspace_command /path/to/your/script.sh
}
------------------------------
=== Re-create the default behaviour of i3bar
Not very useful by itself but this will be the basic building block of all the
following scripts. This one does not require +jq+.
------------------------------
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
# Initially print the current workspaces before we receive any events. This
# avoids having an empty bar when starting up.
i3-msg -t get_workspaces;
# Then, while we receive events, update the workspace information.
while read EVENT; do i3-msg -t get_workspaces; done;
}
------------------------------
=== Hide workspace named +foo+ unless if it is focused.
------------------------------
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
i3-msg -t get_workspaces;
while read EVENT; do i3-msg -t get_workspaces; done;
} | jq --unbuffered -c '[ .[] | select(.name != "foo" or .focused) ]'
------------------------------
Important! Make sure you use the +--unbuffered+ flag with +jq+, otherwise you
might not get the changes in real-time but whenever they are flushed, which
might mean that you are getting an empty bar until enough events are written.
=== Show empty workspaces +foo+ and +bar+ on LVDS1 even if they do not exist at the moment.
------------------------------
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
i3-msg -t get_workspaces;
while read EVENT; do i3-msg -t get_workspaces; done;
} | jq --unbuffered -c '
def fake_ws(name): {
name: name,
output: "LVDS1",
};
. + [ fake_ws("foo"), fake_ws("bar") ] | unique_by(.name)
'
------------------------------
=== Sort workspaces in reverse alphanumeric order
------------------------------
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
i3-msg -t get_workspaces;
while read EVENT; do i3-msg -t get_workspaces; done;
} | jq --unbuffered -c 'sort_by(.name) | reverse'
------------------------------
=== Append "foo" to the name of each workspace
------------------------------
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
i3-msg -t get_workspaces;
while read EVENT; do i3-msg -t get_workspaces; done;
} | jq --unbuffered -c '[ .[] | .name |= . + " foo" ]'
------------------------------

382
docs/ipc
View File

@@ -1,7 +1,7 @@
IPC interface (interprocess communication)
==========================================
Michael Stapelberg <michael@i3wm.org>
September 2017
June 2020
This document describes how to interface with i3 from a separate process. This
is useful for example to remote-control i3 (to write test cases for example) or
@@ -10,14 +10,22 @@ workspace bar.
The method of choice for IPC in our case is a unix socket because it has very
little overhead on both sides and is usually available without headaches in
most languages. In the default configuration file, the ipc-socket gets created
in +/tmp/i3-%u.XXXXXX/ipc-socket.%p+ where +%u+ is your UNIX username, +%p+ is
the PID of i3 and XXXXXX is a string of random characters from the portable
filename character set (see mkdtemp(3)). You can get the socketpath from i3 by
calling +i3 --get-socketpath+.
most languages.
By default i3 will set the path of the IPC socket based on:
All i3 utilities, like +i3-msg+ and +i3-input+ will read the +I3_SOCKET_PATH+
X11 property, stored on the X11 root window.
1. The +ipc-socket+ configuration directive if it is used
2. The +I3SOCK+ environmental variable if it is set
3. +$XDG_RUNTIME_DIR/i3/ipc-socket.%p+ if the directory is available where +%p+
is the PID of i3 and XXXXXX is a string of random characters
4. +/tmp/i3-%u.XXXXXX/ipc-socket.%p+ where +%u+ is your UNIX username
You can get the socketpath from i3 by executing +i3 --get-socketpath+, which
will print the path to the standard output (plus a newline) or by reading the
+I3SOCK+ environmental variable.
All i3 utilities, like +i3-msg+ and +i3-input+ will determine the path of the
IPC socket frome the +I3SOCK+ environmental variable if it is set or the
+I3_SOCKET_PATH+ X11 property, stored on the X11 root window.
[WARNING]
.Use an existing library!
@@ -39,12 +47,12 @@ my $sock = IO::Socket::UNIX->new(Peer => $path);
== Sending messages to i3
To send a message to i3, you have to format in the binary message format which
i3 expects. This format specifies a magic string in the beginning to ensure
the integrity of messages (to prevent follow-up errors). Following the magic
string comes the length of the payload of the message as 32-bit integer, and
the type of the message as 32-bit integer (the integers are not converted, so
they are in native byte order).
To send a message to i3, you have to format it in the binary message format
which i3 expects. This format specifies a magic string in the beginning to
ensure the integrity of messages (to prevent follow-up errors). Following the
magic string comes the length of the payload of the message as a 32-bit
integer, and the type of the message as a 32-bit integer (the integers are not
converted, so they are in native byte order).
The magic string currently is "i3-ipc" and will only be changed when a change
in the IPC API is done which breaks compatibility (we hope that we dont need
@@ -65,6 +73,8 @@ to do that).
| 8 | +GET_BINDING_MODES+ | <<_binding_modes_reply,BINDING_MODES>> | Gets the names of all currently configured binding modes.
| 9 | +GET_CONFIG+ | <<_config_reply,CONFIG>> | Returns the last loaded i3 config.
| 10 | +SEND_TICK+ | <<_tick_reply,TICK>> | Sends a tick event with the specified payload.
| 11 | +SYNC+ | <<_sync_reply,SYNC>> | Sends an i3 sync event with the specified random value to the specified window.
| 12 | +GET_BINDING_STATE+ | <<_binding_state_reply,BINDING_STATE>> | Request the current binding state, i.e. the currently active binding mode name.
|======================================================
So, a typical message could look like this:
@@ -79,7 +89,8 @@ Or, as a hexdump:
------------------------------------------------------------------------------
To generate and send such a message, you could use the following code in Perl:
------------------------------------------------------------
-------------------------------------------------------------------------------
sub format_ipc_command {
my ($msg) = @_;
my $len;
@@ -89,22 +100,34 @@ sub format_ipc_command {
}
$sock->write(format_ipc_command("exit"));
------------------------------------------------------------------------------
-------------------------------------------------------------------------------
== Receiving replies from i3
Replies from i3 usually consist of a simple string (the length of the string
is the message_length, so you can consider them length-prefixed) which in turn
contain the JSON serialization of a data structure. For example, the
GET_WORKSPACES message returns an array of workspaces (each workspace is a map
with certain attributes).
Each message sent to i3 will cause exactly one reply to be sent in return. The
order of the sent replies will always correspond to the order of the sent
requests. The only exception to this is <<events>>, which (once subscribed to)
may be sent at any time (though never in the middle of another event or reply).
=== Reply format
It is generally safe to send several messages to i3 without first waiting for a
reply for each one (pipelining) -- though, note that depending on the language /
network library you use, writing to the socket without also reading from it may
cause a deadlock due to the socket buffers getting full.
The reply format is identical to the normal message format. There also is
the magic string, then the message length, then the message type and the
payload.
The payload of replies from i3 usually consists of a simple string (the length
of the string is the message_length, so you can consider them length-prefixed),
which in turn contain the JSON serialization of a data structure. For example,
the GET_WORKSPACES message returns an array of workspaces (each workspace is a
map with certain attributes).
Replies currently have a 1:1 correspondence to messages, with the message type
of the reply corresponding to the message type of the message which caused the
reply to be sent.
The following reply types are implemented:
COMMAND (0)::
@@ -124,36 +147,86 @@ BAR_CONFIG (6)::
VERSION (7)::
Reply to the GET_VERSION message.
BINDING_MODES (8)::
Reply to the GET_BINDING_MODES message.
Reply to the GET_BINDING_MODES message.
GET_CONFIG (9)::
Reply to the GET_CONFIG message.
TICK (10)::
Reply to the SEND_TICK message.
SYNC (11)::
Reply to the SYNC message.
GET_BINDING_STATE (12)::
Reply to the GET_BINDING_STATE message.
== Messages and replies
[[_command_reply]]
=== COMMAND reply
=== RUN_COMMAND / COMMAND
Run the payload as an https://i3wm.org/docs/userguide.html#list_of_commands[i3
command] (like the commands you can bind to keys).
*Message:*
The message payload is the string containing the command to execute. There is
no JSON encoding or trailing newline.
*Reply:*
The reply consists of a list of serialized maps for each command that was
parsed. Each has the property +success (bool)+ and may also include a
human-readable error message in the property +error (string)+.
NOTE: When sending the `restart` command, you will get a singular reply once the
restart completed. All IPC connection states (e.g. subscriptions) will reset and
all but one socket will be closed. Libraries must be able to cope with this by
aligning their internal states. It is also recommended that libraries close
the last remaining socket(one which replied to `restart` command) to achieve
the full reset.
NOTE: It is easiest to always send the `restart` command alone: due to i3s
state reset, the reply messages of preceding commands are lost, and following
commands will not be executed.
NOTE: When processing the `exit` command, i3 will immediately exit without
sending a reply. Expect the socket to be shut down.
*Example:*
-------------------
[{ "success": true }]
-------------------
When the specified command cannot be parsed, `success` will be false and
`parse_error` will be true:
*Example:*
-------------------
[{ "success": false, "parse_error": true }]
-------------------
[[_workspaces_reply]]
=== WORKSPACES reply
=== GET_WORKSPACES / WORKSPACES
Get the list of current workspaces.
*Message:*
No payload.
*Reply:*
The reply consists of a serialized list of workspaces. Each workspace has the
following properties:
id (integer)::
The internal ID (actually a C pointer value) of this container. Do not
make any assumptions about it. You can use it to (re-)identify and
address containers when talking to i3.
num (integer)::
The logical number of the workspace. Corresponds to the command
to switch to this workspace. For named workspaces, this will be -1.
name (string)::
The name of this workspace (by default num+1), as changed by the
user. Encoded in UTF-8.
The name of this workspace if changed by the user, otherwise defaults
to the string representation of the +num+ field). Encoded in UTF-8.
visible (boolean)::
Whether this workspace is currently visible on an output (multiple
workspaces can be visible at the same time).
@@ -203,7 +276,16 @@ output (string)::
-------------------
[[_subscribe_reply]]
=== SUBSCRIBE reply
=== SUBSCRIBE
Subscribe this IPC connection to the event types specified in the message
payload. See <<events>>.
*Message:*
A JSON-encoded array of event types to subscribe to.
*Reply:*
The reply consists of a single serialized map. The only property is
+success (bool)+, indicating whether the subscription was successful (the
@@ -215,7 +297,15 @@ default) or whether a JSON parse error occurred.
-------------------
[[_outputs_reply]]
=== OUTPUTS reply
=== GET_OUTPUTS / OUTPUTS
Get the list of current outputs.
*Message:*
No payload.
*Reply:*
The reply consists of a serialized list of outputs. Each output has the
following properties:
@@ -226,7 +316,7 @@ active (boolean)::
Whether this output is currently active (has a valid mode).
primary (boolean)::
Whether this output is currently the primary output.
current_workspace (string)::
current_workspace (string or null)::
The name of the current workspace that is visible on this output. +null+ if
the output is not active.
rect (map)::
@@ -262,7 +352,15 @@ rect (map)::
-------------------
[[_tree_reply]]
=== TREE reply
=== GET_TREE / TREE
Get the i3 layout tree.
*Message:*
No payload.
*Reply:*
The reply consists of a serialized tree. Each node in the tree (representing
one container) has at least the properties listed below. While the nodes might
@@ -298,7 +396,7 @@ orientation (string)::
"vertical".
THIS FIELD IS OBSOLETE. It is still present, but your code should not
use it. Instead, rely on the layout field.
percent (float)::
percent (float or null)::
The percentage which this container takes in its parent. A value of
+null+ means that the percent property does not make sense for this
container, for example for the root container.
@@ -319,19 +417,37 @@ deco_rect (map)::
The coordinates of the *window decoration* inside its container. These
coordinates are relative to the container and do not include the actual
client window.
actual_deco_rect (map)::
See +deco_rect+. i3 v4.22 changed the way title bars are rendered. Before
i3 v4.22, the deco_rect was always relative to the parent coordinates.
Starting with i3 v4.22, this remains true for tabbed/stacked containers
(actual_deco_rect is identical to deco_rect), but for normal-border leaf
containers within vertical/horizontal split containers, actual_deco_rect
is relative to the container itself. For more background, see
https://github.com/i3/i3/issues/1966
geometry (map)::
The original geometry the window specified when i3 mapped it. Used when
switching a window to floating mode, for example.
window (integer)::
window (integer or null)::
The X11 window ID of the *actual client window* inside this container.
This field is set to null for split containers or otherwise empty
This field is set to +null+ for split containers or otherwise empty
containers. This ID corresponds to what xwininfo(1) and other
X11-related tools display (usually in hex).
window_properties (map)::
This optional field contains all available X11 window properties from the
following list: *title*, *instance*, *class*, *window_role*, *machine*
and *transient_for*.
window_type (string)::
The window type (_NET_WM_WINDOW_TYPE). Possible values are `undefined`,
unknown, normal, dialog, utility, toolbar, splash, menu, dropdown_menu,
popup_menu, tooltip and notification.
urgent (bool)::
Whether this container (window, split container, floating container or
workspace) has the urgency hint set, directly or indirectly. All parent
containers up until the workspace container will be marked urgent if they
have at least one urgent child.
marks (array of string)::
List of marks assigned to container
focused (bool)::
Whether this container is currently focused.
focus (array of integer)::
@@ -339,11 +455,28 @@ focus (array of integer)::
order. Traversing the tree by following the first entry in this array
will result in eventually reaching the one node with +focused+ set to
true.
sticky (bool)::
Whether this window is "sticky". If it is also floating, this window will
be present on all workspaces on the same output.
fullscreen_mode (integer)::
Whether this container is in fullscreen state or not.
Possible values are
+0+ (no fullscreen),
+1+ (fullscreened on output) or
+2+ (fullscreened globally).
Note that all workspaces are considered fullscreened on their respective output.
floating (string)::
Floating state of container.
Can be either "auto_on", "auto_off", "user_on" or "user_off"
nodes (array of node)::
The tiling (i.e. non-floating) child containers of this node.
floating_nodes (array of node)::
The floating child containers of this node. Only non-empty on nodes with
type +workspace+.
scratchpad_state (string)::
Whether the window is not in the scratchpad ("none"), freshly moved to
the scratchpad but not yet resized ("fresh") or moved to the scratchpad
and resized ("changed").
Please note that in the following example, I have left out some keys/values
which are not relevant for the type of the node. Otherwise, the example would
@@ -422,6 +555,12 @@ JSON dump:
"width": 1280,
"height": 782
},
"window_properties": {
"class": "Evince",
"instance": "evince",
"title": "Properties",
"transient_for": 52428808
},
"floating_nodes": [],
"nodes": [
@@ -475,10 +614,18 @@ JSON dump:
}
]
}
------------------------
-----------------------
[[_marks_reply]]
=== MARKS reply
=== GET_MARKS / MARKS
Gets the names of all currently set marks.
*Message:*
No payload.
*Reply:*
The reply consists of a single array of strings for each container that has a
mark. A mark can only be set on one container, so the array is unique.
@@ -487,7 +634,15 @@ The order of that array is undefined.
If no window has a mark the response will be the empty array [].
[[_bar_config_reply]]
=== BAR_CONFIG reply
=== GET_BAR_CONFIG / BAR_CONFIG
Gets the specified bar configuration or the names of all bar configurations if payload is empty.
*Message:*
No payload, or the ID of the bar whose configuration to retrieve.
*Reply:*
This can be used by third-party workspace bars (especially i3bar, but others
are free to implement compatible alternatives) to get the +bar+ block
@@ -587,7 +742,15 @@ binding_mode_text/binding_mode_bg/binding_mode_border::
--------------
[[_version_reply]]
=== VERSION reply
=== GET_VERSION / VERSION
Gets the i3 version.
*Message:*
No payload.
*Reply:*
The reply consists of a single JSON dictionary with the following keys:
@@ -620,7 +783,15 @@ loaded_config_file_name (string)::
-------------------
[[_binding_modes_reply]]
=== BINDING_MODES reply
=== GET_BINDING_MODES / BINDING_MODES
Gets the names of all currently configured binding modes.
*Message:*
No payload.
*Reply:*
The reply consists of an array of all currently configured binding modes.
@@ -630,18 +801,66 @@ The reply consists of an array of all currently configured binding modes.
---------------------
[[_config_reply]]
=== CONFIG reply
=== GET_CONFIG / CONFIG
The config reply is a map which currently only contains the "config" member,
which is a string containing the config file as loaded by i3 most recently.
Returns the last loaded i3 config.
*Message:*
No payload.
*Reply:*
The config reply is a map which contains the following fields:
config (string)::
The top-level config file contents that i3 has loaded most recently.
This field is kept for backwards compatibility. See +included_configs+
instead.
included_configs (array of maps)::
i3 adds one entry to this array for each config file it loads, in
order. The first entrys +raw_contents+ are identical to the +config+
field.
Each +included_configs+ entry contains the following fields
path (string)::
Absolute path name to the config file that i3 loaded.
raw_contents (string)::
The raw contents of the file as i3 read them.
variable_replaced_contents (string)::
The contents of the file after i3 replaced all variables. This is useful
for debugging variable replacement.
*Example:*
-------------------
{ "config": "font pango:monospace 8\nbindsym Mod4+q exit\n" }
{
"config": "include font.cfg\n",
"included_configs": [
{
"path": "/home/michael/configfiles/i3/config",
"raw_contents": "include font.cfg\n",
"variable_replaced_contents": "include font.cfg\n"
},
{
"path": "/home/michael/configfiles/i3/font.cfg",
"raw_contents": "set $font pango:monospace 8\nfont $font",
"variable_replaced_contents": "set pango:monospace 8 pango:monospace 8\nfont pango:monospace 8\n"
}
],
}
-------------------
[[_tick_reply]]
=== TICK reply
=== SEND_TICK / TICK
Sends a tick event with the specified payload.
*Message:*
The payload of the tick event to send to IPC event listeners.
*Reply:*
The reply is a map containing the "success" member. After the reply was
received, the tick event has been written to all IPC connections which subscribe
@@ -654,15 +873,56 @@ events generated prior to the +SEND_TICK+ message (happened-before relation).
{ "success": true }
-------------------
[[_sync_reply]]
=== SYNC
Sends an i3 sync event with the specified random value to the specified window.
*Message:*
A JSON-encoded map with the properties "rnd" and "window" (both integer).
*Reply:*
The reply is a map containing the "success" member. After the reply was
received, the https://i3wm.org/docs/testsuite.html#i3_sync[i3 sync message] was
responded to.
*Example:*
-------------------
{ "success": true }
-------------------
[[_binding_state_reply]]
=== GET_BINDING_STATE
Request the current binding state, i.e. the currently active binding mode name.
*Message:*
No payload.
*Reply:*
The binding_state reply is a map which currently only contains the "name"
member, which is the name of the currently active binding mode as a string.
*Example:*
-------------------
{ "name": "default" }
-------------------
== Events
[[events]]
To get informed when certain things happen in i3, clients can subscribe to
events. Events consist of a name (like "workspace") and an event reply type
(like I3_IPC_EVENT_WORKSPACE). The events sent by i3 are in the same format
as replies to specific commands. However, the highest bit of the message type
is set to 1 to indicate that this is an event reply instead of a normal reply.
(like I3_IPC_EVENT_WORKSPACE). Events sent by i3 follow a format similar to
replies but with the highest bit of the message type set to 1 to indicate an
event reply instead of a normal reply. Note that event types and reply types
do not follow the same enumeration scheme (e.g. event type 0 corresponds to the
workspace event however reply type 0 corresponds to the COMMAND reply).
Caveat: As soon as you subscribe to an event, it is not guaranteed any longer
that the requests to i3 are processed in order. This means, the following
@@ -672,6 +932,14 @@ program does not want to cope which such kinds of race conditions (an
event based library may not have a problem here), I suggest you create a
separate connection to receive events.
If an event message needs to be sent and the socket is not writeable (write
returns EAGAIN, happens when the socket doesn't have enough buffer space for
writing new data) then i3 uses a queue system to store outgoing messages for
each client. This is combined with a timer: if the message queue for a client is
not empty and no data where successfully written in the past 10 seconds, the
connection is killed. Practically, this means that your client should try to
always read events from the socket to avoid having its connection closed.
=== Subscribing to events
By sending a message of type SUBSCRIBE with a JSON-encoded array as payload
@@ -736,10 +1004,19 @@ if ($is_event) {
=== workspace event
This event consists of a single serialized map containing a property
+change (string)+ which indicates the type of the change ("focus", "init",
"empty", "urgent", "reload", "rename", "restored", "move"). A
+current (object)+ property will be present with the affected workspace
whenever the type of event affects a workspace (otherwise, it will be +null).
+change (string)+ which indicates the type of the change.
* +empty+ the workspace has become empty
* +focus+ the workspace has received input focus
* +init+ the workspace has been created
* +move+ the workspace has been moved to a different output
* +reload+ i3 config has been reloaded
* +rename+ the workspace's name has changed
* +restored+ the workspace's layout has changed to a previously saved layout
* +urgent+ the workspace has become urgent or lost its urgent status
A +current (object)+ property will be present with the affected workspace
whenever the type of event affects a workspace (otherwise, it will be +null+).
When the change is "focus", an +old (object)+ property will be present with the
previous workspace. When the first switch occurs (when i3 focuses the
@@ -838,6 +1115,8 @@ binding that ran a command because of user input. The +change (string)+ field
indicates what sort of binding event was triggered (right now it will always be
+"run"+ but may be expanded in the future).
The +mode (string)+ field contains the name of the mode the binding was run in.
The +binding (object)+ field contains details about the binding that was run:
command (string)::
@@ -919,6 +1198,7 @@ C::
* i3 includes a headerfile +i3/ipc.h+ which provides you all constants.
* https://github.com/acrisci/i3ipc-glib
C++::
* https://github.com/Iskustvo/i3-ipcpp[i3-ipc++]
* https://github.com/drmgc/i3ipcpp
Go::
* https://github.com/mdirkse/i3ipc-go

View File

@@ -185,9 +185,9 @@ Therefore, if you just start Emacs via dmenu, it will not get swallowed by that
container. Only if you start Emacs with the proper instance name (+emacs24
--name notmuch+), it will get swallowed.
You can match on "class", "instance", "window_role" and "title". All values are
case-sensitive regular expressions (PCRE). Use +xprop(1)+ and click into a
window to see its properties:
You can match on "class", "instance", "window_role", "title" and "machine". All
values are case-sensitive regular expressions (PCRE). Use +xprop(1)+ and click
into a window to see its properties:
--------------------------------------------------------------------------------
$ xprop
@@ -219,13 +219,15 @@ the window which matches any of the criteria. As an example:
A layout file as generated by +i3-save-tree(1)+ is not strictly valid JSON:
1. Layout files contain multiple “JSON documents” on the top level, whereas the
JSON standard only allows precisely one “document” (array or hash).
1. Layout files contain multiple “JSON texts” at the top level. The JSON
standard doesn't prohibit this, but in practice most JSON parsers only
allow precisely one “text” per document/file, and will mark multiple texts
as invalid JSON.
2. Layout files contain comments which are not standardized, but understood by
many parsers.
2. Layout files contain comments which are not allowed by the JSON standard,
but are understood by many parsers.
Both deviations from the JSON standard are to make manual editing by humans
Both of these deviations from the norm are to make manual editing by humans
easier. In case you are writing a more elaborate tool for manipulating these
layouts, you can either use a JSON parser that supports these deviations (for
example libyajl), transform the layout file to a JSON-conforming file, or
@@ -259,27 +261,3 @@ container:
]
}
--------------------------------------------------------------------------------
=== Placeholders using window title matches don't swallow the window
If you use the +title+ attribute to match a window and find that it doesn't
work or only works sometimes, the reason might be that the application sets the
title only after making the window visible. This will be especially true for
programs running inside terminal emulators, e.g., +urxvt -e irssi+ when
matching on +title: "irssi"+.
One way to deal with this is to not rely on the title, but instead use, e.g.,
the +instance+ attribute and running the program to set this window instance to
that value:
--------------------------------------------------------------------------------
# Run irssi via
# urxvt -name "irssi-container" -e irssi
"swallows": [
{
"class": "URxvt",
"instance": "irssi-container"
}
]
--------------------------------------------------------------------------------

View File

@@ -15,7 +15,7 @@
h1 { font-size: 1.1em; }
header a { font-size: 0.7em; }
header p { margin: 5px 0; font-size: 0.8em; text-align: left; }
kbd { font-family: LinuxBiolinumKeyboard, Linux Biolinum Keyboard O, Linux Biolinum Keyboard, DejaVu Sans Mono, monospace; font-size: 0.9em; }
kbd { font-family: LinuxBiolinumKeyboard, Linux Biolinum Keyboard O, Linux Biolinum Keyboard, DejaVu Sans Mono, monospace; font-size: 1.2em; }
code { font-family: DejaVu Sans Mono, monospace; font-size: 0.8em; }
section { break-inside: avoid-column; -moz-break-inside: -moz-avoid-column; -webkit-break-inside: avoid-column; }
h2 { margin: 7px 0 2px; padding: 2px 4px; font-size: 1.1em; font-family: LinuxBiolinum, Linux Biolinum O, Linux Biolinum, sans; background-color: #b3b3b3; }

View File

@@ -4,11 +4,10 @@ Michael Stapelberg <michael@i3wm.org>
September 2012
This document explains how the i3 testsuite works, how to use it and extend it.
It is targeted at developers who not necessarily have been doing testing before
or have not been testing in Perl before. In general, the testsuite is not of
It is targeted at developers who haven't necessarily done testing before,
or have not used Perl for testing before. In general, the testsuite is not of
interest for end users.
== Introduction
The i3 testsuite is a collection of files which contain testcases for various
@@ -37,8 +36,8 @@ that, but it will also be useful for every future change.
Apart from this document, you should also have a look at:
1. The "Modern Perl" book, which can be found at
http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
1. The "Modern Perl" book:
https://i3wm.org/downloads/modern_perl_a4.pdf
2. The latest Perl documentation of the "i3test" (general testcase setup) and
"i3test::Test" (additional test instructions) modules:
https://build.i3wm.org/docs/lib-i3test.html respectively
@@ -77,30 +76,20 @@ used to install the testsuite. Many users prefer to use the more modern
The tests additionally require +Xephyr(1)+ to run a nested X server. Install
+xserver-xephyr+ on Debian or +xorg-server-xephyr+ on Arch Linux.
.Installing testsuite dependencies using cpanminus (preferred)
.Installing testsuite dependencies using cpanminus
--------------------------------------------------------------------------------
$ cd ~/i3/testcases
$ sudo apt-get install cpanminus
$ sudo cpanm .
# Install testsuite system-level dependencies. Xvfb is optional but recommended.
$ sudo apt-get install xcb-proto cpanminus xvfb xserver-xephyr
# Install dependencies in ~/perl5 local library
$ cpanm --local-lib=~/perl5 local::lib App::cpanminus Module::Install
# Activate the local library
$ eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
$ cd ~/i3/testcases/
$ cpanm .
$ cd ~/i3/AnyEvent-I3
$ sudo cpanm Module::Install
$ sudo cpanm .
$ cpanm .
--------------------------------------------------------------------------------
If you dont want to use cpanminus for some reason, the same works with cpan:
.Installing testsuite dependencies using cpan
--------------------------------------------------------------------------------
$ cd ~/i3/testcases
$ sudo cpan .
$ cd ~/i3/AnyEvent-I3
$ sudo cpan Module::Install
$ sudo cpan .
--------------------------------------------------------------------------------
In case you dont have root permissions, you can also install into your home
directory, see https://michael.stapelberg.de/cpan/
=== Mechanisms
==== Script: complete-run
@@ -120,50 +109,57 @@ tests are run under Xvfb.
---------------------------------------
$ cd ~/i3
$ autoreconf -fi
$ mkdir -p build
$ mkdir -p build && cd build
$ meson setup build
$ cd build
$ ../configure
$ make -j8
$ meson compile
# output omitted because it is very long
$ cd testcases
$ ./complete-run.pl
# output omitted because it is very long
All tests successful.
Files=78, Tests=734, 27 wallclock secs ( 0.38 usr 0.48 sys + 17.65 cusr 3.21 csys = 21.72 CPU)
Result: PASS
$ ./complete-run.pl t/04-floating.t
[:3] i3 startup: took 0.07s, status = 1
[:3] Running t/04-floating.t with logfile testsuite-2011-09-24-16-06-04-4.0.2-226-g1eb011a/i3-log-for-04-floating.t
[:3] t/04-floating.t finished
[:3] killing i3
output for t/04-floating.t:
ok 1 - use X11::XCB::Window;
ok 2 - The object isa X11::XCB::Window
ok 3 - Window is mapped
ok 4 - i3 raised the width to 75
ok 5 - i3 raised the height to 50
ok 6 - i3 did not map it to (0x0)
ok 7 - The object isa X11::XCB::Window
ok 8 - i3 let the width at 80
ok 9 - i3 let the height at 90
ok 10 - i3 mapped it to x=1
ok 11 - i3 mapped it to y=18
ok 12 - The object isa X11::XCB::Window
ok 13 - i3 let the width at 80
ok 14 - i3 let the height at 90
1..14
$ ./complete-run.pl t/005-floating.t
Running tests under Xvfb display :99
Starting 1 Xephyr instances, starting at :100...
Rough time estimate for this run: 9.65 seconds
Writing logfile to 'testsuite-2024-05-01-21-33-45-4.23-28-g5834b7e8/complete-run.log'...
[:100] i3/testcases/t/005-floating.t: finished
completed 0 of 1 tests
All tests successful.
Files=1, Tests=14, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.19 cusr 0.03 csys = 0.23 CPU)
Files=1, Tests=13, 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU)
Result: PASS
$ less latest/i3-log-for-04-floating.t
The slowest tests are:
i3/testcases/t/005-floating.t with 0.07 seconds
Test output:
[:100] i3/testcases/t/005-floating.t: starting
[:100] i3/testcases/t/005-floating.t: finished
output for i3/testcases/t/005-floating.t:
ok 1 - An object of class 'X11::XCB::Window' isa 'X11::XCB::Window'
ok 2 - Window is mapped
ok 3 - i3 raised the width to 75
ok 4 - i3 raised the height to 50
ok 5 - i3 did not map it to (0x0)
ok 6 - An object of class 'X11::XCB::Window' isa 'X11::XCB::Window'
ok 7 - i3 let the width at 80
ok 8 - i3 let the height at 90
ok 9 - i3 mapped it to x=20
ok 10 - i3 mapped it to y=20
ok 11 - An object of class 'X11::XCB::Window' isa 'X11::XCB::Window'
ok 12 - i3 let the width at 80
ok 13 - i3 let the height at 90
1..13
$ less latest/i3-log-for-005-floating.t
----------------------------------------
If your attempt to run the tests with a bare call to ./complete-run.pl fails, try this:
@@ -175,39 +171,34 @@ $ ./complete-run.pl --parallel=1 --keep-xserver-output
This will show the output of Xephyr, which is the X server implementation we
use for testing.
===== make command: +make check+
Make check runs the i3 testsuite.
You can still use ./testcases/complete-run.pl to get the interactive progress output.
===== ninja command: +ninja test+
+ninja test+ runs the i3 testsuite.
You can still use ./complete-run.pl to get the interactive progress output.
.Example invocation of +make check+
.Example invocation of +ninja test+
---------------------------------------
$ cd ~/i3
$ autoreconf -fi
$ mkdir -p build
$ mkdir -p build && cd build
$ meson setup build
$ cd build
$ ../configure
$ ninja test
[1/102] Generating config.h with a custom command
[1/2] Running all tests.
1/1 complete-run OK 34.39s
$ make -j8
# output omitted because it is very long
Ok: 1
Expected Fail: 0
Fail: 0
Unexpected Pass: 0
Skipped: 0
Timeout: 0
$ make check
# output omitted because it is very long
PASS: testcases/complete-run.pl
============================================================================
Testsuite summary for i3 4.13
============================================================================
# TOTAL: 1
# PASS: 1
# SKIP: 0
# XFAIL: 0
# FAIL: 0
# XPASS: 0
# ERROR: 0
============================================================================
Full log written to i3/build/meson-logs/testlog.txt
$ less test-suite.log
$ less latest/complete-run.log
----------------------------------------
==== Coverage testing
@@ -485,7 +476,7 @@ an i3 crash resulting in the testcase being unable to communicate with i3 via
IPC anymore.
[[i3_sync]]
== Appendix A: The i3 sync protocol
== Appendix A: The I3_SYNC protocol
Consider the following situation: You open two windows in your testcase, then
you use +focus left+ and want to verify that the X11 focus has been updated
@@ -503,9 +494,9 @@ is($x->input_focus, $left->id, 'left window focused');
However, the test fails. Sometimes. Apparently, there is a race condition in
your test. If you think about it, this is because you are using two different
pieces of software: You tell i3 to update focus, i3 confirms that, and then you
ask X11 to give you the current focus. There is a certain time i3 needs to
update the X11 state. If the testcase gets CPU time before X11 processed i3's
requests, the test will fail.
ask X11 to give you the current focus. There is a certain time that the X11
server needs to process the requests from i3. If the testcase's request for the
input focus is processed before i3's requests, the test will fail.
image::i3-sync.png["Diagram of the race condition", title="Diagram of the race condition"]
@@ -535,10 +526,10 @@ less robust.
The real solution for this problem is a mechanism which I call "the i3 sync
protocol". The idea is to send a request (which does not modify state) via X11
to i3 which will then be answered. Due to the request's position in the event
queue (*after* all previous events), you can be sure that by the time you
receive the reply, all other events have been dealt with by i3 (and, more
importantly, X11).
to i3 which will then be answered, again via X11. Because this answer is
generated via an X11 request, it will be sent to the X11 server *after* all
previous requests. Thus, you can be sure that by the time you receive the reply,
all other events have been dealt with by i3 (and, more importantly, X11).
image::i3-sync-working.png["Diagram of the i3 sync solution", title="Diagram of the i3 sync solution"]
@@ -573,7 +564,35 @@ i3 will then reply with the same ClientMessage, sent to the window specified in
request. You should use a random value in +data[1]+ and check that you received
the same one when getting the reply.
== Appendix B: Socket activation
== Appendix B: The sync IPC command
The above I3_SYNC protocol allows to synchronise with i3. However, it is not
enough for tests that also involve i3bar: There might still be messages from
i3bar in-flight even after synchronising with i3. Thus, there also exists a sync
IPC command, that is however not meant to be used directly. Instead, i3bar uses
it for implementing the I3_SYNC protocol.
The intended usage works like this:
1. You send an I3_SYNC message to i3bar's window. See <<i3_sync>>.
2. i3bar sends a SYNC IPC command to i3 with payload
+{"window":your-window-here,"rnd":your-random-value}+.
3. i3 reacts to this IPC command as if it received an I3_SYNC request via X11.
This protocol is used, for example, in t/525-i3bar-mouse-bindings.t: A mouse
button press on i3bar is triggered. i3bar reacts to this by sending IPC commands
to i3.
The necessary synchronisation is achieved by sending an I3_SYNC event to i3bar:
Because i3bar reacts with a sync IPC command to i3, all previous IPC commands from
i3bar will be handled first. Because i3 reacts via X11, all previous X11
requests from i3 will be handled by the X11 server first.
The actual test also has to sync with i3 first due to how X11 handling works.
For more details, refer to the documentation for +XAllowEvents+ with mode
+ReplayPointer+.
== Appendix C: Socket activation
Socket activation is a mechanism which was made popular by systemd, an init
replacement. It basically describes creating a listening socket before starting

File diff suppressed because it is too large Load Diff

View File

@@ -17,12 +17,27 @@ font pango:monospace 8
# text rendering and scalability on retina/hidpi displays (thanks to pango).
#font pango:DejaVu Sans Mono 8
# Before i3 v4.8, we used to recommend this one as the default:
# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
# The font above is very space-efficient, that is, it looks good, sharp and
# clear in small sizes. However, its unicode glyph coverage is limited, the old
# X core fonts rendering does not support right-to-left and this being a bitmap
# font, it doesn't scale on retina/hidpi displays.
# Start XDG autostart .desktop files using dex. See also
# https://wiki.archlinux.org/index.php/XDG_Autostart
exec --no-startup-id dex --autostart --environment i3
# The combination of xss-lock, nm-applet and pactl is a popular choice, so
# they are included here as an example. Modify as you see fit.
# xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
# screen before suspend. Use loginctl lock-session to lock your screen.
exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
# NetworkManager is the most popular way to manage wireless networks on Linux,
# and nm-applet is a desktop environment-independent system tray GUI for it.
exec --no-startup-id nm-applet
# Use pactl to adjust volume in PulseAudio.
set $refresh_i3status killall -SIGUSR1 i3status
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
# use these keys for focus, movement, and resize directions when reaching for
# the arrows is not convenient
@@ -34,6 +49,10 @@ set $right semicolon
# use Mouse+Mod1 to drag floating windows to their wanted position
floating_modifier Mod1
# move tiling windows via drag & drop by left-clicking into the title bar,
# or left-clicking anywhere into the window while holding the floating modifier.
tiling_drag modifier titlebar
# start a terminal
bindsym Mod1+Return exec i3-sensible-terminal
@@ -41,10 +60,11 @@ bindsym Mod1+Return exec i3-sensible-terminal
bindsym Mod1+Shift+q kill
# start dmenu (a program launcher)
bindsym Mod1+d exec dmenu_run
# There also is the (new) i3-dmenu-desktop which only displays applications
# shipping a .desktop file. It is a wrapper around dmenu, so you need that
# installed.
bindsym Mod1+d exec --no-startup-id dmenu_run
# A more modern dmenu replacement is rofi:
# bindsym Mod1+d exec "rofi -modi drun,run -show drun"
# There also is i3-dmenu-desktop which only displays applications shipping a
# .desktop file. It is a wrapper around dmenu, so you need that installed.
# bindsym Mod1+d exec --no-startup-id i3-dmenu-desktop
# change focus
@@ -117,37 +137,36 @@ set $ws8 "8"
set $ws9 "9"
set $ws10 "10"
# switch to workspace
bindsym Mod1+1 workspace $ws1
bindsym Mod1+2 workspace $ws2
bindsym Mod1+3 workspace $ws3
bindsym Mod1+4 workspace $ws4
bindsym Mod1+5 workspace $ws5
bindsym Mod1+6 workspace $ws6
bindsym Mod1+7 workspace $ws7
bindsym Mod1+8 workspace $ws8
bindsym Mod1+9 workspace $ws9
bindsym Mod1+0 workspace $ws10
bindsym Mod1+1 workspace number $ws1
bindsym Mod1+2 workspace number $ws2
bindsym Mod1+3 workspace number $ws3
bindsym Mod1+4 workspace number $ws4
bindsym Mod1+5 workspace number $ws5
bindsym Mod1+6 workspace number $ws6
bindsym Mod1+7 workspace number $ws7
bindsym Mod1+8 workspace number $ws8
bindsym Mod1+9 workspace number $ws9
bindsym Mod1+0 workspace number $ws10
# move focused container to workspace
bindsym Mod1+Shift+1 move container to workspace $ws1
bindsym Mod1+Shift+2 move container to workspace $ws2
bindsym Mod1+Shift+3 move container to workspace $ws3
bindsym Mod1+Shift+4 move container to workspace $ws4
bindsym Mod1+Shift+5 move container to workspace $ws5
bindsym Mod1+Shift+6 move container to workspace $ws6
bindsym Mod1+Shift+7 move container to workspace $ws7
bindsym Mod1+Shift+8 move container to workspace $ws8
bindsym Mod1+Shift+9 move container to workspace $ws9
bindsym Mod1+Shift+0 move container to workspace $ws10
bindsym Mod1+Shift+1 move container to workspace number $ws1
bindsym Mod1+Shift+2 move container to workspace number $ws2
bindsym Mod1+Shift+3 move container to workspace number $ws3
bindsym Mod1+Shift+4 move container to workspace number $ws4
bindsym Mod1+Shift+5 move container to workspace number $ws5
bindsym Mod1+Shift+6 move container to workspace number $ws6
bindsym Mod1+Shift+7 move container to workspace number $ws7
bindsym Mod1+Shift+8 move container to workspace number $ws8
bindsym Mod1+Shift+9 move container to workspace number $ws9
bindsym Mod1+Shift+0 move container to workspace number $ws10
# reload the configuration file
bindsym Mod1+Shift+c reload
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindsym Mod1+Shift+r restart
# exit i3 (logs you out of your X session)
bindsym Mod1+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
bindsym Mod1+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
# resize window (you can also use the mouse for that)
mode "resize" {
@@ -187,7 +206,8 @@ bar {
# keysym-based config which used their favorite modifier (alt or windows)
#
# i3-config-wizard will not launch if there already is a config file
# in ~/.i3/config.
# in ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) or
# ~/.i3/config.
#
# Please remove the following exec line:
#######################################################################

View File

@@ -18,16 +18,35 @@ font pango:monospace 8
# text rendering and scalability on retina/hidpi displays (thanks to pango).
#font pango:DejaVu Sans Mono 8
# Before i3 v4.8, we used to recommend this one as the default:
# font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
# The font above is very space-efficient, that is, it looks good, sharp and
# clear in small sizes. However, its unicode glyph coverage is limited, the old
# X core fonts rendering does not support right-to-left and this being a bitmap
# font, it doesnt scale on retina/hidpi displays.
# Start XDG autostart .desktop files using dex. See also
# https://wiki.archlinux.org/index.php/XDG_Autostart
exec --no-startup-id dex --autostart --environment i3
# The combination of xss-lock, nm-applet and pactl is a popular choice, so
# they are included here as an example. Modify as you see fit.
# xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
# screen before suspend. Use loginctl lock-session to lock your screen.
exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
# NetworkManager is the most popular way to manage wireless networks on Linux,
# and nm-applet is a desktop environment-independent system tray GUI for it.
exec --no-startup-id nm-applet
# Use pactl to adjust volume in PulseAudio.
set $refresh_i3status killall -SIGUSR1 i3status
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
# Use Mouse+$mod to drag floating windows to their wanted position
floating_modifier $mod
# move tiling windows via drag & drop by left-clicking into the title bar,
# or left-clicking anywhere into the window while holding the floating modifier.
tiling_drag modifier titlebar
# start a terminal
bindcode $mod+36 exec i3-sensible-terminal
@@ -35,11 +54,12 @@ bindcode $mod+36 exec i3-sensible-terminal
bindcode $mod+Shift+24 kill
# start dmenu (a program launcher)
bindcode $mod+40 exec dmenu_run
# There also is the (new) i3-dmenu-desktop which only displays applications
# shipping a .desktop file. It is a wrapper around dmenu, so you need that
# installed.
# bindsym $mod+d exec --no-startup-id i3-dmenu-desktop
bindcode $mod+40 exec --no-startup-id dmenu_run
# A more modern dmenu replacement is rofi:
# bindcode $mod+40 exec "rofi -modi drun,run -show drun"
# There also is i3-dmenu-desktop which only displays applications shipping a
# .desktop file. It is a wrapper around dmenu, so you need that installed.
# bindcode $mod+40 exec --no-startup-id i3-dmenu-desktop
# change focus
bindcode $mod+44 focus left
@@ -105,35 +125,35 @@ set $ws9 "9"
set $ws10 "10"
# switch to workspace
bindcode $mod+10 workspace $ws1
bindcode $mod+11 workspace $ws2
bindcode $mod+12 workspace $ws3
bindcode $mod+13 workspace $ws4
bindcode $mod+14 workspace $ws5
bindcode $mod+15 workspace $ws6
bindcode $mod+16 workspace $ws7
bindcode $mod+17 workspace $ws8
bindcode $mod+18 workspace $ws9
bindcode $mod+19 workspace $ws10
bindcode $mod+10 workspace number $ws1
bindcode $mod+11 workspace number $ws2
bindcode $mod+12 workspace number $ws3
bindcode $mod+13 workspace number $ws4
bindcode $mod+14 workspace number $ws5
bindcode $mod+15 workspace number $ws6
bindcode $mod+16 workspace number $ws7
bindcode $mod+17 workspace number $ws8
bindcode $mod+18 workspace number $ws9
bindcode $mod+19 workspace number $ws10
# move focused container to workspace
bindcode $mod+Shift+10 move container to workspace $ws1
bindcode $mod+Shift+11 move container to workspace $ws2
bindcode $mod+Shift+12 move container to workspace $ws3
bindcode $mod+Shift+13 move container to workspace $ws4
bindcode $mod+Shift+14 move container to workspace $ws5
bindcode $mod+Shift+15 move container to workspace $ws6
bindcode $mod+Shift+16 move container to workspace $ws7
bindcode $mod+Shift+17 move container to workspace $ws8
bindcode $mod+Shift+18 move container to workspace $ws9
bindcode $mod+Shift+19 move container to workspace $ws10
bindcode $mod+Shift+10 move container to workspace number $ws1
bindcode $mod+Shift+11 move container to workspace number $ws2
bindcode $mod+Shift+12 move container to workspace number $ws3
bindcode $mod+Shift+13 move container to workspace number $ws4
bindcode $mod+Shift+14 move container to workspace number $ws5
bindcode $mod+Shift+15 move container to workspace number $ws6
bindcode $mod+Shift+16 move container to workspace number $ws7
bindcode $mod+Shift+17 move container to workspace number $ws8
bindcode $mod+Shift+18 move container to workspace number $ws9
bindcode $mod+Shift+19 move container to workspace number $ws10
# reload the configuration file
bindcode $mod+Shift+54 reload
# restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
bindcode $mod+Shift+27 restart
# exit i3 (logs you out of your X session)
bindcode $mod+Shift+26 exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -b 'Yes, exit i3' 'i3-msg exit'"
bindcode $mod+Shift+26 exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
# resize window (you can also use the mouse for that)
mode "resize" {

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env perl
# vim:ts=4:sw=4:expandtab
#
# i3 - an improved dynamic tiling window manager
# i3 - an improved tiling window manager
# © 2009 Michael Stapelberg and contributors (see also: LICENSE)
#
# generate-command-parser.pl: script to generate parts of the command parser
@@ -77,7 +77,7 @@ for my $line (@lines) {
($line =~ /
^\s* # skip leading whitespace
([a-z_]+ \s* = \s*|) # optional identifier
(.*?) -> \s* # token
(.*?) -> \s* # token
(.*) # optional action
/x);
@@ -117,6 +117,7 @@ my @keys = sort { (length($b) <=> length($a)) or ($a cmp $b) } keys %states;
open(my $enumfh, '>', "GENERATED_${prefix}_enums.h");
my %statenum;
say $enumfh '#pragma once';
say $enumfh 'typedef enum {';
my $cnt = 0;
for my $state (@keys, '__CALL') {
@@ -131,7 +132,8 @@ close($enumfh);
# Third step: Generate the call function.
open(my $callfh, '>', "GENERATED_${prefix}_call.h");
my $resultname = uc(substr($prefix, 0, 1)) . substr($prefix, 1) . 'ResultIR';
say $callfh "static void GENERATED_call(const int call_identifier, struct $resultname *result) {";
say $callfh '#pragma once';
say $callfh "static void GENERATED_call(Match *current_match, struct stack *stack, const int call_identifier, struct $resultname *result) {";
say $callfh ' switch (call_identifier) {';
my $call_id = 0;
for my $state (@keys) {
@@ -148,8 +150,8 @@ for my $state (@keys) {
# calls to get_string(). Also replaces state names (like FOR_WINDOW)
# with their ID (useful for cfg_criteria_init(FOR_WINDOW) e.g.).
$cmd =~ s/$_/$statenum{$_}/g for @keys;
$cmd =~ s/\$([a-z_]+)/get_string("$1")/g;
$cmd =~ s/\&([a-z_]+)/get_long("$1")/g;
$cmd =~ s/\$([a-z_]+)/get_string(stack, "$1")/g;
$cmd =~ s/\&([a-z_]+)/get_long(stack, "$1")/g;
# For debugging/testing, we print the call using printf() and thus need
# to generate a format string. The format uses %d for <number>s,
# literal numbers or state IDs and %s for NULL, <string>s and literal
@@ -173,9 +175,9 @@ for my $state (@keys) {
say $callfh '#ifndef TEST_PARSER';
my $real_cmd = $cmd;
if ($real_cmd =~ /\(\)/) {
$real_cmd =~ s/\(/(&current_match, result/;
$real_cmd =~ s/\(/(current_match, result/;
} else {
$real_cmd =~ s/\(/(&current_match, result, /;
$real_cmd =~ s/\(/(current_match, result, /;
}
say $callfh " $real_cmd;";
say $callfh '#else';
@@ -206,6 +208,7 @@ close($callfh);
# Fourth step: Generate the token datastructures.
open(my $tokfh, '>', "GENERATED_${prefix}_tokens.h");
say $tokfh '#pragma once';
for my $state (@keys) {
my $tokens = $states{$state};
@@ -218,13 +221,22 @@ for my $state (@keys) {
# quote of the literal. We can do strdup(literal + 1); then :).
$token_name =~ s/'$//;
}
# Escape double quotes:
$token_name =~ s,",\\",g;
my $next_state = $token->{next_state};
if ($next_state =~ /^call /) {
($call_identifier) = ($next_state =~ /^call ([0-9]+)$/);
$next_state = '__CALL';
}
my $identifier = $token->{identifier};
say $tokfh qq| { "$token_name", "$identifier", $next_state, { $call_identifier } },|;
my $identifier;
# Set $identifier to NULL if there is no identifier
if ($token->{identifier} eq ""){
$identifier = "NULL"
}
else{
$identifier = qq|"$token->{identifier}"|;
}
say $tokfh qq| { "$token_name", $identifier, $next_state, { $call_identifier } },|;
}
say $tokfh '};';
}

View File

@@ -1,6 +0,0 @@
xmacro(_NET_WM_NAME)
xmacro(_NET_WM_WINDOW_TYPE)
xmacro(_NET_WM_WINDOW_TYPE_DIALOG)
xmacro(ATOM)
xmacro(CARDINAL)
xmacro(UTF8_STRING)

View File

@@ -0,0 +1,8 @@
// clang-format off
#define CONFIG_WIZARD_ATOMS_XMACRO \
xmacro(_NET_WM_NAME) \
xmacro(_NET_WM_WINDOW_TYPE) \
xmacro(_NET_WM_WINDOW_TYPE_DIALOG) \
xmacro(ATOM) \
xmacro(CARDINAL) \
xmacro(UTF8_STRING)

View File

@@ -1,7 +1,7 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* i3-config-wizard: Program to convert configs using keycodes to configs using
@@ -10,6 +10,8 @@
*/
#include <config.h>
#include "libi3.h"
#if defined(__FreeBSD__)
#include <sys/param.h>
#endif
@@ -23,34 +25,33 @@
#define _WITH_GETLINE
#endif
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <err.h>
#include <stdint.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <glob.h>
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_event.h>
#include <xcb/xcb_keysyms.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-x11.h>
#include <xkbcommon/xkbcommon.h>
#define SN_API_NOT_YET_FROZEN 1
#include <libsn/sn-launchee.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include "i3-config-wizard-atoms.xmacro.h"
/* We need SYSCONFDIR for the path to the keycode config template, so raise an
* error if its not defined for whatever reason */
@@ -65,7 +66,7 @@
} while (0)
#include "xcb.h"
#include "libi3.h"
xcb_visualtype_t *visual_type = NULL;
#define TEXT_PADDING logical_px(4)
#define WIN_POS_X logical_px(490)
@@ -101,7 +102,7 @@ static struct xkb_keymap *xkb_keymap;
static uint8_t xkb_base_event;
static uint8_t xkb_base_error;
static void finish();
static void finish(void);
#include "GENERATED_config_enums.h"
@@ -156,8 +157,9 @@ static struct stack_entry stack[10];
static void push_string(const char *identifier, const char *str) {
for (int c = 0; c < 10; c++) {
if (stack[c].identifier != NULL &&
strcmp(stack[c].identifier, identifier) != 0)
strcmp(stack[c].identifier, identifier) != 0) {
continue;
}
if (stack[c].identifier == NULL) {
/* Found a free slot, lets store it here. */
stack[c].identifier = identifier;
@@ -183,8 +185,9 @@ static void push_string(const char *identifier, const char *str) {
static void push_long(const char *identifier, long num) {
for (int c = 0; c < 10; c++) {
if (stack[c].identifier != NULL)
if (stack[c].identifier != NULL) {
continue;
}
/* Found a free slot, lets store it here. */
stack[c].identifier = identifier;
stack[c].val.num = num;
@@ -203,18 +206,21 @@ static void push_long(const char *identifier, long num) {
static const char *get_string(const char *identifier) {
for (int c = 0; c < 10; c++) {
if (stack[c].identifier == NULL)
if (stack[c].identifier == NULL) {
break;
if (strcmp(identifier, stack[c].identifier) == 0)
}
if (strcmp(identifier, stack[c].identifier) == 0) {
return stack[c].val.str;
}
}
return NULL;
}
static void clear_stack(void) {
for (int c = 0; c < 10; c++) {
if (stack[c].type == STACK_STR && stack[c].val.str != NULL)
if (stack[c].type == STACK_STR) {
free(stack[c].val.str);
}
stack[c].identifier = NULL;
stack[c].val.str = NULL;
stack[c].val.num = 0;
@@ -232,11 +238,13 @@ static bool keysym_used_on_other_key(KeySym sym, xcb_keycode_t except_keycode) {
max_keycode = xcb_get_setup(conn)->max_keycode;
for (i = min_keycode; i && i <= max_keycode; i++) {
if (i == except_keycode)
if (i == except_keycode) {
continue;
}
for (int level = 0; level < 4; level++) {
if (xcb_key_symbols_get_keysym(keysyms, i, level) != sym)
if (xcb_key_symbols_get_keysym(keysyms, i, level) != sym) {
continue;
}
return true;
}
}
@@ -268,22 +276,27 @@ static char *next_state(const cmdp_token *token) {
* qwerty (yes, that happens quite often). */
const xkb_keysym_t *syms;
int num = xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, 0, 0, &syms);
if (num == 0)
if (num == 0) {
errx(1, "xkb_keymap_key_get_syms_by_level returned no symbols for keycode %d", keycode);
if (!keysym_used_on_other_key(syms[0], keycode))
}
if (!keysym_used_on_other_key(syms[0], keycode)) {
level = 0;
}
}
const xkb_keysym_t *syms;
int num = xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, 0, level, &syms);
if (num == 0)
if (num == 0) {
errx(1, "xkb_keymap_key_get_syms_by_level returned no symbols for keycode %d", keycode);
if (num > 1)
}
if (num > 1) {
printf("xkb_keymap_key_get_syms_by_level (keycode = %d) returned %d symbolsinstead of 1, using only the first one.\n", keycode, num);
}
char str[4096];
if (xkb_keysym_get_name(syms[0], str, sizeof(str)) == -1)
if (xkb_keysym_get_name(syms[0], str, sizeof(str)) == -1) {
errx(EXIT_FAILURE, "xkb_keysym_get_name(%u) failed", syms[0]);
}
const char *release = get_string("release");
char *res;
char *modrep = (modifiers == NULL ? sstrdup("") : sstrdup(modifiers));
@@ -293,6 +306,7 @@ static char *next_state(const cmdp_token *token) {
}
sasprintf(&res, "bindsym %s%s%s %s%s\n", (modifiers == NULL ? "" : modrep), (modifiers == NULL ? "" : "+"), str, (release == NULL ? "" : release), get_string("command"));
clear_stack();
free(modrep);
return res;
}
@@ -301,8 +315,9 @@ static char *next_state(const cmdp_token *token) {
/* See if we are jumping back to a state in which we were in previously
* (statelist contains INITIAL) and just move statelist_idx accordingly. */
for (int i = 0; i < statelist_idx; i++) {
if (statelist[i] != _next_state)
if (statelist[i] != _next_state) {
continue;
}
statelist_idx = i + 1;
return NULL;
}
@@ -327,10 +342,9 @@ static char *rewrite_binding(const char *input) {
while ((size_t)(walk - input) <= len) {
/* Skip whitespace before every token, newlines are relevant since they
* separate configuration directives. */
while ((*walk == ' ' || *walk == '\t') && *walk != '\0')
while ((*walk == ' ' || *walk == '\t') && *walk != '\0') {
walk++;
//printf("remaining input: %s\n", walk);
}
cmdp_token_ptr *ptr = &(tokens[state]);
for (c = 0; c < ptr->n; c++) {
@@ -339,11 +353,13 @@ static char *rewrite_binding(const char *input) {
/* A literal. */
if (token->name[0] == '\'') {
if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) {
if (token->identifier != NULL)
if (token->identifier != NULL) {
push_string(token->identifier, token->name + 1);
}
walk += strlen(token->name) - 1;
if ((result = next_state(token)) != NULL)
if ((result = next_state(token)) != NULL) {
return result;
}
break;
}
continue;
@@ -355,20 +371,24 @@ static char *rewrite_binding(const char *input) {
errno = 0;
long int num = strtol(walk, &end, 10);
if ((errno == ERANGE && (num == LONG_MIN || num == LONG_MAX)) ||
(errno != 0 && num == 0))
(errno != 0 && num == 0)) {
continue;
}
/* No valid numbers found */
if (end == walk)
if (end == walk) {
continue;
}
if (token->identifier != NULL)
if (token->identifier != NULL) {
push_long(token->identifier, num);
}
/* Set walk to the first non-number character */
walk = end;
if ((result = next_state(token)) != NULL)
if ((result = next_state(token)) != NULL) {
return result;
}
break;
}
@@ -379,12 +399,14 @@ static char *rewrite_binding(const char *input) {
if (*walk == '"') {
beginning++;
walk++;
while (*walk != '\0' && (*walk != '"' || *(walk - 1) == '\\'))
while (*walk != '\0' && (*walk != '"' || *(walk - 1) == '\\')) {
walk++;
}
} else {
if (token->name[0] == 's') {
while (*walk != '\0' && *walk != '\r' && *walk != '\n')
while (*walk != '\0' && *walk != '\r' && *walk != '\n') {
walk++;
}
} else {
/* For a word, the delimiters are white space (' ' or
* '\t'), closing square bracket (]), comma (,) and
@@ -392,8 +414,9 @@ static char *rewrite_binding(const char *input) {
while (*walk != ' ' && *walk != '\t' &&
*walk != ']' && *walk != ',' &&
*walk != ';' && *walk != '\r' &&
*walk != '\n' && *walk != '\0')
*walk != '\n' && *walk != '\0') {
walk++;
}
}
}
if (walk != beginning) {
@@ -406,33 +429,36 @@ static char *rewrite_binding(const char *input) {
/* We only handle escaped double quotes to not break
* backwards compatibility with people using \w in
* regular expressions etc. */
if (beginning[inpos] == '\\' && beginning[inpos + 1] == '"')
if (beginning[inpos] == '\\' && beginning[inpos + 1] == '"') {
inpos++;
}
str[outpos] = beginning[inpos];
}
if (token->identifier)
if (token->identifier) {
push_string(token->identifier, str);
}
free(str);
/* If we are at the end of a quoted string, skip the ending
* double quote. */
if (*walk == '"')
if (*walk == '"') {
walk++;
if ((result = next_state(token)) != NULL)
}
if ((result = next_state(token)) != NULL) {
return result;
}
break;
}
}
if (strcmp(token->name, "end") == 0) {
//printf("checking for end: *%s*\n", walk);
if (*walk == '\0' || *walk == '\n' || *walk == '\r') {
if ((result = next_state(token)) != NULL)
if ((result = next_state(token)) != NULL) {
return result;
/* To make sure we start with an appropriate matching
* datastructure for commands which do *not* specify any
}
/* To make sure we start with an appropriate matching data
* structure for commands which do *not* specify any
* criteria, we re-initialize the criteria system after
* every command. */
// TODO: make this testable
walk++;
break;
}
@@ -478,7 +504,7 @@ static void txt(int col, int row, char *text, color_t fg, color_t bg) {
* Handles expose events, that is, draws the window contents.
*
*/
static int handle_expose() {
static int handle_expose(void) {
const color_t black = draw_util_hex_to_color("#000000");
const color_t white = draw_util_hex_to_color("#FFFFFF");
const color_t green = draw_util_hex_to_color("#00FF00");
@@ -515,17 +541,19 @@ static int handle_expose() {
txt(13, 10, "to abort", white, black);
/* the not-selected modifier */
if (modifier == MOD_Mod4)
if (modifier == MOD_Mod4) {
txt(5, 5, "<Alt>", white, black);
else
} else {
txt(5, 4, "<Win>", white, black);
}
/* the selected modifier */
set_font(&bold_font);
if (modifier == MOD_Mod4)
if (modifier == MOD_Mod4) {
txt(2, 4, "-> <Win>", white, black);
else
} else {
txt(2, 5, "-> <Alt>", white, black);
}
set_font(&font);
txt(4, 9, "<Enter>", green, black);
@@ -564,8 +592,9 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
strlen("i3: generate config"),
"i3: generate config");
xcb_flush(conn);
} else
} else {
finish();
}
}
/* Swap between modifiers when up or down is pressed. */
@@ -575,8 +604,9 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
}
/* cancel any time */
if (sym == XK_Escape)
if (sym == XK_Escape) {
exit(0);
}
/* Check if this is Mod1 or Mod4. The modmap contains Shift, Lock, Control,
* Mod1, Mod2, Mod3, Mod4, Mod5 (in that order) */
@@ -585,8 +615,9 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
int mask = 3;
for (int i = 0; i < modmap_reply->keycodes_per_modifier; i++) {
xcb_keycode_t code = modmap[(mask * modmap_reply->keycodes_per_modifier) + i];
if (code == XCB_NONE)
if (code == XCB_NONE) {
continue;
}
printf("Modifier keycode for Mod1: 0x%02x\n", code);
if (code == event->detail) {
modifier = MOD_Mod1;
@@ -598,8 +629,9 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
mask = 6;
for (int i = 0; i < modmap_reply->keycodes_per_modifier; i++) {
xcb_keycode_t code = modmap[(mask * modmap_reply->keycodes_per_modifier) + i];
if (code == XCB_NONE)
if (code == XCB_NONE) {
continue;
}
printf("Modifier keycode for Mod4: 0x%02x\n", code);
if (code == event->detail) {
modifier = MOD_Mod4;
@@ -616,11 +648,13 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
*
*/
static void handle_button_press(xcb_button_press_event_t *event) {
if (current_step != STEP_GENERATE)
if (current_step != STEP_GENERATE) {
return;
}
if (event->event_x < col_x(5) || event->event_x > col_x(10))
if (event->event_x < col_x(5) || event->event_x > col_x(10)) {
return;
}
if (event->event_y >= row_y(4) && event->event_y <= (row_y(4) + font.height)) {
modifier = MOD_Mod4;
@@ -631,33 +665,35 @@ static void handle_button_press(xcb_button_press_event_t *event) {
modifier = MOD_Mod1;
handle_expose();
}
return;
}
/*
* Creates the config file and tells i3 to reload.
*
*/
static void finish() {
static void finish(void) {
printf("creating \"%s\"...\n", config_path);
struct xkb_context *xkb_context;
if ((xkb_context = xkb_context_new(0)) == NULL)
if ((xkb_context = xkb_context_new(0)) == NULL) {
errx(1, "could not create xkbcommon context");
}
int32_t device_id = xkb_x11_get_core_keyboard_device_id(conn);
if ((xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0)) == NULL)
if ((xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0)) == NULL) {
errx(1, "xkb_x11_keymap_new_from_device failed");
}
FILE *kc_config = fopen(SYSCONFDIR "/i3/config.keycodes", "r");
if (kc_config == NULL)
if (kc_config == NULL) {
err(1, "Could not open input file \"%s\"", SYSCONFDIR "/i3/config.keycodes");
}
FILE *ks_config = fopen(config_path, "w");
if (ks_config == NULL)
if (ks_config == NULL) {
err(1, "Could not open output config file \"%s\"", config_path);
}
free(config_path);
char *line = NULL;
@@ -688,8 +724,9 @@ static void finish() {
#endif
/* skip the warning block at the beginning of the input file */
if (head_of_file &&
strncmp("# WARNING", line, strlen("# WARNING")) == 0)
strncmp("# WARNING", line, strlen("# WARNING")) == 0) {
continue;
}
head_of_file = false;
@@ -703,10 +740,11 @@ static void finish() {
/* Set the modifier the user chose */
if (strncmp(walk, "set $mod ", strlen("set $mod ")) == 0) {
if (modifier == MOD_Mod1)
if (modifier == MOD_Mod1) {
fputs("set $mod Mod1\n", ks_config);
else
} else {
fputs("set $mod Mod4\n", ks_config);
}
continue;
}
@@ -745,10 +783,12 @@ int main(int argc, char *argv[]) {
char *pattern = "pango:monospace 8";
char *patternbold = "pango:monospace bold 8";
int o, option_index = 0;
bool headless_run = false;
static struct option long_options[] = {
{"socket", required_argument, 0, 's'},
{"version", no_argument, 0, 'v'},
{"modifier", required_argument, 0, 'm'},
{"limit", required_argument, 0, 'l'},
{"prompt", required_argument, 0, 'P'},
{"prefix", required_argument, 0, 'p'},
@@ -756,7 +796,7 @@ int main(int argc, char *argv[]) {
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}};
char *options_string = "s:vh";
char *options_string = "sm:vh";
while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
switch (o) {
@@ -767,9 +807,19 @@ int main(int argc, char *argv[]) {
case 'v':
printf("i3-config-wizard " I3_VERSION "\n");
return 0;
case 'm':
headless_run = true;
if (strcmp(optarg, "alt") == 0) {
modifier = MOD_Mod1;
} else if (strcmp(optarg, "win") == 0) {
modifier = MOD_Mod4;
} else {
err(EXIT_FAILURE, "Invalid modifier key %s", optarg);
}
break;
case 'h':
printf("i3-config-wizard " I3_VERSION "\n");
printf("i3-config-wizard [-s <socket>] [-v]\n");
printf("i3-config-wizard [-s <socket>] [-m win|alt] [-v] [-h]\n");
return 0;
}
}
@@ -782,8 +832,9 @@ int main(int argc, char *argv[]) {
}
/* Always write to $XDG_CONFIG_HOME/i3/config by default. */
if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL)
if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) {
xdg_config_home = "~/.config";
}
xdg_config_home = resolve_tilde(xdg_config_home);
sasprintf(&config_path, "%s/i3/config", xdg_config_home);
@@ -792,9 +843,11 @@ int main(int argc, char *argv[]) {
char *config_dir;
struct stat stbuf;
sasprintf(&config_dir, "%s/i3", xdg_config_home);
if (stat(config_dir, &stbuf) != 0)
if (mkdirp(config_dir, DEFAULT_DIR_MODE) != 0)
if (stat(config_dir, &stbuf) != 0) {
if (mkdirp(config_dir, DEFAULT_DIR_MODE) != 0) {
err(EXIT_FAILURE, "mkdirp(%s) failed", config_dir);
}
}
free(config_dir);
free(xdg_config_home);
@@ -808,8 +861,9 @@ int main(int argc, char *argv[]) {
int screen;
if ((conn = xcb_connect(NULL, &screen)) == NULL ||
xcb_connection_has_error(conn))
errx(1, "Cannot open display\n");
xcb_connection_has_error(conn)) {
errx(1, "Cannot open display");
}
if (xkb_x11_setup_xkb_extension(conn,
XKB_X11_MIN_MAJOR_XKB_VERSION,
@@ -818,25 +872,37 @@ int main(int argc, char *argv[]) {
NULL,
NULL,
&xkb_base_event,
&xkb_base_error) != 1)
&xkb_base_error) != 1) {
errx(EXIT_FAILURE, "Could not setup XKB extension.");
}
keysyms = xcb_key_symbols_alloc(conn);
xcb_get_modifier_mapping_cookie_t modmap_cookie;
modmap_cookie = xcb_get_modifier_mapping(conn);
symbols = xcb_key_symbols_alloc(conn);
if (headless_run) {
finish();
return 0;
}
/* Place requests for the atoms we need as soon as possible */
#define xmacro(atom) \
xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
#include "atoms.xmacro"
CONFIG_WIZARD_ATOMS_XMACRO
#undef xmacro
/* Init startup notification. */
SnDisplay *sndisplay = sn_xcb_display_new(conn, NULL, NULL);
SnLauncheeContext *sncontext = sn_launchee_context_new_from_environment(sndisplay, screen);
sn_display_unref(sndisplay);
root_screen = xcb_aux_get_screen(conn, screen);
root = root_screen->root;
if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL)))
errx(EXIT_FAILURE, "Could not get modifier mapping\n");
if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL))) {
errx(EXIT_FAILURE, "Could not get modifier mapping");
}
xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply);
@@ -864,6 +930,9 @@ int main(int argc, char *argv[]) {
0, /* back pixel: black */
XCB_EVENT_MASK_EXPOSURE |
XCB_EVENT_MASK_BUTTON_PRESS});
if (sncontext) {
sn_launchee_context_setup_window(sncontext, win);
}
/* Map the window (make it visible) */
xcb_map_window(conn, win);
@@ -873,12 +942,12 @@ int main(int argc, char *argv[]) {
do { \
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \
if (!reply) \
errx(EXIT_FAILURE, "Could not get atom " #name "\n"); \
errx(EXIT_FAILURE, "Could not get atom " #name); \
\
A_##name = reply->atom; \
free(reply); \
} while (0);
#include "atoms.xmacro"
CONFIG_WIZARD_ATOMS_XMACRO
#undef xmacro
/* Set dock mode */
@@ -925,6 +994,12 @@ int main(int argc, char *argv[]) {
exit(-1);
}
/* Startup complete. */
if (sncontext) {
sn_launchee_context_complete(sncontext);
sn_launchee_context_unref(sncontext);
}
xcb_flush(conn);
xcb_generic_event_t *event;
@@ -937,13 +1012,12 @@ int main(int argc, char *argv[]) {
/* Strip off the highest bit (set if the event is generated) */
int type = (event->response_type & 0x7F);
/* TODO: handle mappingnotify */
switch (type) {
case XCB_KEY_PRESS:
handle_key_press(NULL, conn, (xcb_key_press_event_t *)event);
break;
/* TODO: handle mappingnotify */
case XCB_BUTTON_PRESS:
handle_button_press((xcb_button_press_event_t *)event);
break;

View File

@@ -3,6 +3,8 @@
/* from X11/keysymdef.h */
#define XCB_NUM_LOCK 0xff7f
#include "i3-config-wizard-atoms.xmacro.h"
#define xmacro(atom) xcb_atom_t A_##atom;
#include "atoms.xmacro"
CONFIG_WIZARD_ATOMS_XMACRO
#undef xmacro

View File

@@ -13,6 +13,7 @@ use POSIX qw(locale_h);
use File::Find;
use File::Basename qw(basename);
use File::Temp qw(tempfile);
use List::Util 'first';
use Getopt::Long;
use Pod::Usage;
use v5.10;
@@ -45,9 +46,11 @@ sub slurp {
my @entry_types;
my $dmenu_cmd = 'dmenu -i';
my $show_duplicates;
my $result = GetOptions(
'dmenu=s' => \$dmenu_cmd,
'entry-type=s' => \@entry_types,
'show-duplicates' => \$show_duplicates,
'version' => sub {
say "dmenu-desktop 1.5 © 2012 Michael Stapelberg";
exit 0;
@@ -123,6 +126,8 @@ for my $dir (split(':', $xdg_data_dirs)) {
# Cleanup the paths, maybe some application does not cope with double slashes
# (the field code %k is replaced with the .desktop file location).
@searchdirs = map { s,//,/,g; $_ } @searchdirs;
# Also remove any trailing slashes.
@searchdirs = map { s,/*$,,g; $_ } @searchdirs;
# To avoid errors by File::Finds find(), only pass existing directories.
@searchdirs = grep { -d $_ } @searchdirs;
@@ -133,8 +138,15 @@ find(
return unless substr($_, -1 * length('.desktop')) eq '.desktop';
my $relative = $File::Find::name;
# + 1 for the trailing /, which is missing in ::topdir.
substr($relative, 0, length($File::Find::topdir) + 1) = '';
# Find and then replace the directory in @searchdirs in which the
# current file is located. We used to do this with
# $File::Find::topdir but it is not supported when using the
# 'follow' or 'follow_fast' options.
# See #3973, #4031.
my $topdir = first { substr($relative, 0, length($_)) eq $_ } @searchdirs;
# + 1 for the trailing /, which is missing in $topdir.
substr($relative, 0, length($topdir) + 1) = '';
# Dont overwrite files with the same relative path, we search in
# descending order of importance.
@@ -143,6 +155,9 @@ find(
$desktops{$relative} = $File::Find::name;
},
no_chdir => 1,
follow_fast => 1,
# Ignore any duplicate files and directories and proceed normally:
follow_skip => 2,
},
@searchdirs
);
@@ -279,7 +294,7 @@ for my $app (keys %apps) {
}
$choices{$name} = $app;
next;
next unless $show_duplicates;
}
if ((scalar grep { $_ eq 'command' } @entry_types) > 0) {
@@ -314,7 +329,7 @@ for my $app (keys %apps) {
if (!(scalar grep { $_ eq lc(basename($command)) } @keys) > 0) {
$choices{basename($command)} = $app;
}
next;
next unless $show_duplicates;
}
if ((scalar grep { $_ eq 'filename' } @entry_types) > 0) {
@@ -353,9 +368,14 @@ binmode $dmenu_in, ':utf8';
binmode $dmenu_out, ':utf8';
# Feed dmenu the possible choices.
# Since the process might have already exited, we ignore SIGPIPE.
$SIG{PIPE} = 'IGNORE';
say $dmenu_in $_ for sort keys %choices;
close($dmenu_in);
$SIG{PIPE} = 'DEFAULT';
waitpid($pid, 0);
my $status = ($? >> 8);
@@ -400,7 +420,7 @@ my $exec = $app->{Exec};
my $location = $app->{_Location};
# Quote as described by “The Exec key”:
# https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
# https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s07.html
sub quote {
my ($str) = @_;
$str =~ s/("|`|\$|\\)/\\$1/g;
@@ -412,6 +432,17 @@ $choice = quote($choice);
$location = quote($location);
$name = quote($name);
# https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s07.html:
#
# Note that the general escape rule for values of type string states that the
# backslash character can be escaped as ("\\") as well and that this escape rule
# is applied before the quoting rule. As such, to unambiguously represent a
# literal backslash character in a quoted argument in a desktop entry file
# requires the use of four successive backslash characters ("\\\\"). Likewise, a
# literal dollar sign in a quoted argument in a desktop entry file is
# unambiguously represented with ("\\$").
$exec =~ s/\\\\/\\/g;
# Remove deprecated field codes, as the spec dictates.
$exec =~ s/%[dDnNvm]//g;
@@ -468,8 +499,10 @@ EOT
# starts with a double quote ("), everything is parsed as-is until the next
# double quote which is NOT preceded by a backslash (\).
#
# Therefore, we escape all double quotes (") by replacing them with \"
$exec =~ s/"/\\"/g;
# Therefore, we escape all double quotes (") by replacing them with \".
# To not change the meaning of any double quote, backslashes need to be
# escaped as well.
$exec =~ s/(["\\])/\\$1/g;
if (exists($app->{StartupNotify}) && !$app->{StartupNotify}) {
$nosn = '--no-startup-id';
@@ -487,7 +520,7 @@ system('i3-msg', $cmd) == 0 or die "Could not launch i3-msg: $?";
=head1 SYNOPSIS
i3-dmenu-desktop [--dmenu='dmenu -i'] [--entry-type=name]
i3-dmenu-desktop [--dmenu='dmenu -i'] [--entry-type=name] [--show-duplicates]
=head1 DESCRIPTION
@@ -538,11 +571,15 @@ version of dmenu.
Display the (localized) "Name" (type = name), the command (type = command) or
the (*.desktop) filename (type = filename) in dmenu. This option can be
specified multiple times.
specified multiple times. Duplicates will be removed, see '--show-duplicates'.
Examples are "GNU Image Manipulation Program" (type = name), "gimp" (type =
command), and "libreoffice-writer" (type = filename).
=item B<--show-duplicates>
Show duplicates if '--entry-type' is specified multiple times.
=back
=head1 VERSION

View File

@@ -1,7 +1,7 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* i3-dump-log/main.c: Dumps the i3 SHM log to stdout.
@@ -9,31 +9,26 @@
*/
#include <config.h>
#include <stdio.h>
#include "libi3.h"
#include "shmlog.h"
#include <err.h>
#include <fcntl.h>
#include <getopt.h>
#include <i3/ipc.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include <stdint.h>
#include <getopt.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <signal.h>
#include "libi3.h"
#include "shmlog.h"
#include <i3/ipc.h>
#if !defined(__OpenBSD__)
static uint32_t offset_next_write;
#endif
static uint32_t wrap_count;
static i3_shmlog_header *header;
@@ -41,17 +36,12 @@ static char *logbuffer,
*walk;
static int ipcfd = -1;
static volatile bool interrupted = false;
static void sighandler(int signal) {
interrupted = true;
}
static void disable_shmlog(void) {
const char *disablecmd = "debuglog off; shmlog off";
if (ipc_send_message(ipcfd, strlen(disablecmd),
I3_IPC_MESSAGE_TYPE_COMMAND, (uint8_t *)disablecmd) != 0)
I3_IPC_MESSAGE_TYPE_COMMAND, (uint8_t *)disablecmd) != 0) {
err(EXIT_FAILURE, "IPC send");
}
/* Ensure the command was sent by waiting for the reply: */
uint32_t reply_length = 0;
@@ -64,8 +54,9 @@ static void disable_shmlog(void) {
}
static int check_for_wrap(void) {
if (wrap_count == header->wrap_count)
if (wrap_count == header->wrap_count) {
return 0;
}
/* The log wrapped. Print the remaining content and reset walk to the top
* of the log. */
@@ -155,12 +146,13 @@ int main(int argc, char *argv[]) {
exit(1);
}
if (root_atom_contents("I3_CONFIG_PATH", conn, screen) != NULL) {
fprintf(stderr, "i3-dump-log: ERROR: i3 is running, but SHM logging is not enabled. Enabling SHM log until cancelled\n\n");
fprintf(stderr, "i3-dump-log: i3 is running, but SHM logging is not enabled. Enabling SHM log now while i3-dump-log is running\n\n");
ipcfd = ipc_connect(NULL);
const char *enablecmd = "debuglog on; shmlog 5242880";
if (ipc_send_message(ipcfd, strlen(enablecmd),
I3_IPC_MESSAGE_TYPE_COMMAND, (uint8_t *)enablecmd) != 0)
I3_IPC_MESSAGE_TYPE_COMMAND, (uint8_t *)enablecmd) != 0) {
err(EXIT_FAILURE, "IPC send");
}
/* By the time we receive a reply, I3_SHMLOG_PATH is set: */
uint32_t reply_length = 0;
uint8_t *reply = NULL;
@@ -186,29 +178,33 @@ int main(int argc, char *argv[]) {
}
}
if (*shmname == '\0')
if (*shmname == '\0') {
errx(EXIT_FAILURE, "Cannot dump log: SHM logging is disabled in i3.");
}
struct stat statbuf;
/* NB: While we must never write, we need O_RDWR for the pthread condvar. */
int logbuffer_shm = shm_open(shmname, O_RDWR, 0);
if (logbuffer_shm == -1)
if (logbuffer_shm == -1) {
err(EXIT_FAILURE, "Could not shm_open SHM segment for the i3 log (%s)", shmname);
}
if (fstat(logbuffer_shm, &statbuf) != 0)
if (fstat(logbuffer_shm, &statbuf) != 0) {
err(EXIT_FAILURE, "stat(%s)", shmname);
}
/* NB: While we must never write, we need PROT_WRITE for the pthread condvar. */
logbuffer = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, logbuffer_shm, 0);
if (logbuffer == MAP_FAILED)
logbuffer = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, logbuffer_shm, 0);
if (logbuffer == MAP_FAILED) {
err(EXIT_FAILURE, "Could not mmap SHM segment for the i3 log");
}
header = (i3_shmlog_header *)logbuffer;
if (verbose)
if (verbose) {
printf("next_write = %d, last_wrap = %d, logbuffer_size = %d, shmname = %s\n",
header->offset_next_write, header->offset_last_wrap, header->size, shmname);
}
free(shmname);
walk = logbuffer + header->offset_next_write;
@@ -219,8 +215,9 @@ int main(int argc, char *argv[]) {
/* In case there was a write to the buffer already, skip the first
* old line, it very likely is mangled. Not a problem, though, the log
* is chatty enough to have plenty lines left. */
while (*walk != '\n')
while (*walk != '\n') {
walk++;
}
walk++;
}
@@ -238,25 +235,38 @@ int main(int argc, char *argv[]) {
return 0;
}
/* Handle SIGINT gracefully to invoke atexit handlers, if any. */
struct sigaction action;
action.sa_handler = sighandler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGINT, &action, NULL);
char *log_stream_socket_path = root_atom_contents("I3_LOG_STREAM_SOCKET_PATH", NULL, 0);
if (log_stream_socket_path == NULL) {
errx(EXIT_FAILURE, "could not determine i3 log stream socket path: possible i3-dump-log and i3 version mismatch");
}
/* Since pthread_cond_wait() expects a mutex, we need to provide one.
* To not lock i3 (thats bad, mhkay?) we just define one outside of
* the shared memory. */
pthread_mutex_t dummy_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&dummy_mutex);
while (!interrupted) {
pthread_cond_wait(&(header->condvar), &dummy_mutex);
/* If this was not a spurious wakeup, print the new lines. */
if (header->offset_next_write != offset_next_write) {
offset_next_write = header->offset_next_write;
print_till_end();
int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sockfd == -1) {
err(EXIT_FAILURE, "Could not create socket");
}
(void)fcntl(sockfd, F_SETFD, FD_CLOEXEC);
struct sockaddr_un addr;
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_LOCAL;
strncpy(addr.sun_path, log_stream_socket_path, sizeof(addr.sun_path) - 1);
if (connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
err(EXIT_FAILURE, "Could not connect to i3 on socket %s", log_stream_socket_path);
}
/* Same size as the buffer used in log.c vlog(): */
char buf[4096];
for (;;) {
const int n = read(sockfd, buf, sizeof(buf));
if (n == -1) {
err(EXIT_FAILURE, "read(log-stream-socket):");
}
if (n == 0) {
exit(0); /* i3 closed the socket */
}
buf[n] = '\0';
swrite(STDOUT_FILENO, buf, n);
}
#endif

View File

@@ -1,6 +1,6 @@
# This list can be used to convert X11 Keysyms to Unicode 2.1 character.
# The list is not checked for correctness by Unicode officials. Use it
# at your own risk and the creator is not responsable for any damage that
# at your own risk and the creator is not responsible for any damage that
# occurred due to using this list.
#
# The list is created by looking at the Keysym names and the Unicode data

View File

@@ -31,9 +31,10 @@
* This software is in the public domain. Share and enjoy!
*/
#include <xcb/xcb.h>
#include "keysym2ucs.h"
#include <xcb/xcb.h>
struct codepair {
unsigned short keysym;
unsigned short ucs;
@@ -821,21 +822,23 @@ long keysym2ucs(xcb_keysym_t keysym) {
/* first check for Latin-1 characters (1:1 mapping) */
if ((keysym >= 0x0020 && keysym <= 0x007e) ||
(keysym >= 0x00a0 && keysym <= 0x00ff))
(keysym >= 0x00a0 && keysym <= 0x00ff)) {
return keysym;
}
/* also check for directly encoded 24-bit UCS characters */
if ((keysym & 0xff000000) == 0x01000000)
if ((keysym & 0xff000000) == 0x01000000) {
return keysym & 0x00ffffff;
}
/* binary search in table */
while (max >= min) {
mid = (min + max) / 2;
if (keysymtab[mid].keysym < keysym)
if (keysymtab[mid].keysym < keysym) {
min = mid + 1;
else if (keysymtab[mid].keysym > keysym)
} else if (keysymtab[mid].keysym > keysym) {
max = mid - 1;
else {
} else {
/* found it */
return keysymtab[mid].ucs;
}

View File

@@ -1,42 +1,45 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* i3-input/main.c: Utility which lets the user input commands and sends them
* to i3.
*
*/
#include "libi3.h"
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include <stdint.h>
#include <getopt.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_event.h>
#include <xcb/xcb_keysyms.h>
#include <X11/keysym.h>
#include "keysym2ucs.h"
xcb_visualtype_t *visual_type = NULL;
#include "i3-input.h"
#include "keysym2ucs.h"
#include "libi3.h"
#include <X11/keysym.h>
#define MAX_WIDTH logical_px(500)
#define BORDER logical_px(2)
#define PADDING logical_px(2)
/* Exit codes for i3-input:
* 0 if i3-input exited successfully and the command was run
* 1 if the user canceled input
* 2 if i3-input fails for any other reason */
const int EXIT_OK = 0;
const int EXIT_CANCEL = 1;
const int EXIT_ERROR = 2;
/* IPC format string. %s will be replaced with what the user entered, then
* the command will be sent to i3 */
static char *format;
@@ -156,33 +159,36 @@ static int handle_key_release(void *ignored, xcb_connection_t *conn, xcb_key_rel
return 1;
}
static void finish_input() {
static void finish_input(void) {
char *command = (char *)concat_strings(glyphs_utf8, input_position);
/* count the occurrences of %s in the string */
int c;
int len = strlen(format);
int cnt = 0;
for (c = 0; c < (len - 1); c++)
if (format[c] == '%' && format[c + 1] == 's')
const size_t len = strlen(format);
size_t cnt = 0;
for (size_t c = 0; c < (len - 1); c++) {
if (format[c] == '%' && format[c + 1] == 's') {
cnt++;
printf("occurrences = %d\n", cnt);
}
}
printf("occurrences = %zu\n", cnt);
/* allocate space for the output */
int inputlen = strlen(command);
char *full = scalloc(strlen(format) - (2 * cnt) /* format without all %s */
+ (inputlen * cnt) /* replaced %s */
+ 1, /* trailing NUL */
1);
const size_t input_len = strlen(command);
const size_t full_len = MAX(input_len, /* avoid compiler warning */
strlen(format) - (2 * cnt) /* format without all %s */
+ (input_len * cnt) /* replaced %s */
+ 1 /* trailing NUL */
);
char *full = scalloc(full_len, 1);
char *dest = full;
for (c = 0; c < len; c++) {
/* if this is not % or it is % but without a following 's',
* just copy the character */
if (format[c] != '%' || (c == (len - 1)) || format[c + 1] != 's')
for (size_t c = 0; c < len; c++) {
/* if this is not % or it is % but without a following 's', just copy
* the character */
if (format[c] != '%' || (c == (len - 1)) || format[c + 1] != 's') {
*(dest++) = format[c];
else {
strncat(dest, command, inputlen);
dest += inputlen;
} else {
strncat(dest, command, input_len);
dest += input_len;
/* skip the following 's' of '%s' */
c++;
}
@@ -191,11 +197,11 @@ static void finish_input() {
/* prefix the command if a prefix was specified on commandline */
printf("command = %s\n", full);
ipc_send_message(sockfd, strlen(full), 0, (uint8_t *)full);
int ret = ipc_send_message(sockfd, strlen(full), 0, (uint8_t *)full);
free(full);
exit(0);
exit(ret == 0 ? EXIT_OK : EXIT_ERROR);
}
/*
@@ -220,8 +226,9 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
/* If modeswitch is currently active, we need to look in group 2 or 3,
* respectively. */
if (modeswitch_active)
if (modeswitch_active) {
col += 2;
}
xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, col);
if (sym == XK_Mode_switch) {
@@ -230,12 +237,14 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
return 1;
}
if (sym == XK_Return)
if (sym == XK_Return) {
finish_input();
}
if (sym == XK_BackSpace) {
if (input_position == 0)
if (input_position == 0) {
return 1;
}
input_position--;
free(glyphs_utf8[input_position]);
@@ -244,7 +253,7 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
return 1;
}
if (sym == XK_Escape) {
exit(0);
exit(EXIT_CANCEL);
}
/* TODO: handle all of these? */
@@ -256,8 +265,9 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));
if (xcb_is_modifier_key(sym) || xcb_is_cursor_key(sym))
if (xcb_is_modifier_key(sym) || xcb_is_cursor_key(sym)) {
return 1;
}
printf("sym = %c (%d)\n", sym, sym);
@@ -281,8 +291,9 @@ static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press
glyphs_utf8[input_position] = out;
input_position++;
if (input_position == limit)
if (input_position == limit) {
finish_input();
}
handle_expose(NULL, conn, NULL);
return 1;
@@ -302,7 +313,7 @@ static xcb_rectangle_t get_window_position(void) {
xcb_intern_atom_reply_t *nswc_reply = xcb_intern_atom_reply(conn, nswc_cookie, NULL);
if (nswc_reply == NULL) {
ELOG("Could not intern atom _NET_SUPPORTING_WM_CHECK\n");
exit(-1);
exit(EXIT_ERROR);
}
A__NET_SUPPORTING_WM_CHECK = nswc_reply->atom;
free(nswc_reply);
@@ -372,9 +383,8 @@ free_resources:
}
int main(int argc, char *argv[]) {
format = sstrdup("%s");
char *socket_path = NULL;
char *pattern = sstrdup("pango:monospace 8");
char *pattern = NULL;
int o, option_index = 0;
static struct option long_options[] = {
@@ -397,8 +407,8 @@ int main(int argc, char *argv[]) {
socket_path = sstrdup(optarg);
break;
case 'v':
printf("i3-input " I3_VERSION);
return 0;
printf("i3-input " I3_VERSION "\n");
return EXIT_OK;
case 'p':
/* This option is deprecated, but will still work in i3 v4.1, 4.2 and 4.3 */
fprintf(stderr, "i3-input: WARNING: the -p option is DEPRECATED in favor of the -F (format) option\n");
@@ -426,16 +436,20 @@ int main(int argc, char *argv[]) {
printf("\n");
printf("Example:\n");
printf(" i3-input -F 'workspace \"%%s\"' -P 'Switch to workspace: '\n");
return 0;
return EXIT_OK;
}
}
if (!format) {
format = "%s";
}
printf("using format \"%s\"\n", format);
int screen;
conn = xcb_connect(NULL, &screen);
if (!conn || xcb_connection_has_error(conn))
die("Cannot open display\n");
if (!conn || xcb_connection_has_error(conn)) {
die("Cannot open display");
}
sockfd = ipc_connect(socket_path);
@@ -445,11 +459,12 @@ int main(int argc, char *argv[]) {
symbols = xcb_key_symbols_alloc(conn);
init_dpi();
font = load_font(pattern, true);
font = load_font(pattern ? pattern : "pango:monospace 8", true);
set_font(&font);
if (prompt != NULL)
if (prompt != NULL) {
prompt_offset = predict_text_width(prompt);
}
const xcb_rectangle_t win_pos = get_window_position();
@@ -494,7 +509,7 @@ int main(int argc, char *argv[]) {
if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
fprintf(stderr, "Could not grab keyboard, status = %d\n", reply->status);
exit(-1);
exit(EXIT_ERROR);
}
xcb_flush(conn);
@@ -530,5 +545,5 @@ int main(int argc, char *argv[]) {
}
draw_util_surface_free(conn, &surface);
return 0;
return EXIT_OK;
}

View File

@@ -1,7 +1,7 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* i3-msg/main.c: Utility which sends messages to a running i3-instance using
@@ -16,27 +16,17 @@
*/
#include "libi3.h"
#include <stdio.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include <stdint.h>
#include <getopt.h>
#include <limits.h>
#include <i3/ipc.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <yajl/yajl_parse.h>
#include <yajl/yajl_version.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <i3/ipc.h>
/*
* Having verboselog() and errorlog() is necessary when using libi3.
@@ -67,25 +57,28 @@ typedef struct reply_t {
char *errorposition;
} reply_t;
static int exit_code = 0;
static reply_t last_reply;
static int reply_boolean_cb(void *params, int val) {
if (strcmp(last_key, "success") == 0)
if (strcmp(last_key, "success") == 0) {
last_reply.success = val;
}
return 1;
}
static int reply_string_cb(void *params, const unsigned char *val, size_t len) {
char *str = scalloc(len + 1, 1);
strncpy(str, (const char *)val, len);
if (strcmp(last_key, "error") == 0)
char *str = sstrndup((const char *)val, len);
if (strcmp(last_key, "error") == 0) {
last_reply.error = str;
else if (strcmp(last_key, "input") == 0)
} else if (strcmp(last_key, "input") == 0) {
last_reply.input = str;
else if (strcmp(last_key, "errorposition") == 0)
} else if (strcmp(last_key, "errorposition") == 0) {
last_reply.errorposition = str;
else
} else {
free(str);
}
return 1;
}
@@ -95,17 +88,19 @@ static int reply_start_map_cb(void *params) {
static int reply_end_map_cb(void *params) {
if (!last_reply.success) {
fprintf(stderr, "ERROR: Your command: %s\n", last_reply.input);
fprintf(stderr, "ERROR: %s\n", last_reply.errorposition);
if (last_reply.input) {
fprintf(stderr, "ERROR: Your command: %s\n", last_reply.input);
fprintf(stderr, "ERROR: %s\n", last_reply.errorposition);
}
fprintf(stderr, "ERROR: %s\n", last_reply.error);
exit_code = 2;
}
return 1;
}
static int reply_map_key_cb(void *params, const unsigned char *keyVal, size_t keyLen) {
free(last_key);
last_key = scalloc(keyLen + 1, 1);
strncpy(last_key, (const char *)keyVal, keyLen);
last_key = sstrndup((const char *)keyVal, keyLen);
return 1;
}
@@ -124,8 +119,7 @@ static yajl_callbacks reply_callbacks = {
static char *config_last_key = NULL;
static int config_string_cb(void *params, const unsigned char *val, size_t len) {
char *str = scalloc(len + 1, 1);
strncpy(str, (const char *)val, len);
char *str = sstrndup((const char *)val, len);
if (strcmp(config_last_key, "config") == 0) {
fprintf(stdout, "%s", str);
}
@@ -142,8 +136,7 @@ static int config_end_map_cb(void *params) {
}
static int config_map_key_cb(void *params, const unsigned char *keyVal, size_t keyLen) {
config_last_key = scalloc(keyLen + 1, 1);
strncpy(config_last_key, (const char *)keyVal, keyLen);
config_last_key = sstrndup((const char *)keyVal, keyLen);
return 1;
}
@@ -155,25 +148,25 @@ static yajl_callbacks config_callbacks = {
};
int main(int argc, char *argv[]) {
#if defined(__OpenBSD__)
if (pledge("stdio rpath unix", NULL) == -1)
err(EXIT_FAILURE, "pledge");
#endif
char *socket_path = NULL;
int o, option_index = 0;
uint32_t message_type = I3_IPC_MESSAGE_TYPE_RUN_COMMAND;
char *payload = NULL;
bool quiet = false;
bool monitor = false;
bool raw_reply = false;
static struct option long_options[] = {
{"socket", required_argument, 0, 's'},
{"type", required_argument, 0, 't'},
{"version", no_argument, 0, 'v'},
{"quiet", no_argument, 0, 'q'},
{"monitor", no_argument, 0, 'm'},
{"help", no_argument, 0, 'h'},
{"raw", no_argument, 0, 'r'},
{0, 0, 0, 0}};
char *options_string = "s:t:vhq";
char *options_string = "s:t:vhqmr";
while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
if (o == 's') {
@@ -196,31 +189,44 @@ int main(int argc, char *argv[]) {
message_type = I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG;
} else if (strcasecmp(optarg, "get_binding_modes") == 0) {
message_type = I3_IPC_MESSAGE_TYPE_GET_BINDING_MODES;
} else if (strcasecmp(optarg, "get_binding_state") == 0) {
message_type = I3_IPC_MESSAGE_TYPE_GET_BINDING_STATE;
} else if (strcasecmp(optarg, "get_version") == 0) {
message_type = I3_IPC_MESSAGE_TYPE_GET_VERSION;
} else if (strcasecmp(optarg, "get_config") == 0) {
message_type = I3_IPC_MESSAGE_TYPE_GET_CONFIG;
} else if (strcasecmp(optarg, "send_tick") == 0) {
message_type = I3_IPC_MESSAGE_TYPE_SEND_TICK;
} else if (strcasecmp(optarg, "subscribe") == 0) {
message_type = I3_IPC_MESSAGE_TYPE_SUBSCRIBE;
} else {
printf("Unknown message type\n");
printf("Known types: run_command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_binding_modes, get_version, get_config, send_tick\n");
printf("Known types: run_command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_binding_modes, get_binding_state, get_version, get_config, send_tick, subscribe\n");
exit(EXIT_FAILURE);
}
} else if (o == 'q') {
quiet = true;
} else if (o == 'm') {
monitor = true;
} else if (o == 'v') {
printf("i3-msg " I3_VERSION "\n");
return 0;
} else if (o == 'h') {
printf("i3-msg " I3_VERSION "\n");
printf("i3-msg [-s <socket>] [-t <type>] <message>\n");
printf("i3-msg [-s <socket>] [-t <type>] [-m] <message>\n");
return 0;
} else if (o == '?') {
exit(EXIT_FAILURE);
} else if (o == 'r') {
raw_reply = true;
}
}
if (monitor && message_type != I3_IPC_MESSAGE_TYPE_SUBSCRIBE) {
fprintf(stderr, "The monitor option -m is used with -t SUBSCRIBE exclusively.\n");
exit(EXIT_FAILURE);
}
/* Use all arguments, separated by whitespace, as payload.
* This way, you dont have to do i3-msg 'mark foo', you can use
* i3-msg mark foo */
@@ -236,66 +242,93 @@ int main(int argc, char *argv[]) {
optind++;
}
if (!payload)
if (!payload) {
payload = sstrdup("");
}
int sockfd = ipc_connect(socket_path);
if (ipc_send_message(sockfd, strlen(payload), message_type, (uint8_t *)payload) == -1)
if (ipc_send_message(sockfd, strlen(payload), message_type, (uint8_t *)payload) == -1) {
err(EXIT_FAILURE, "IPC: write()");
}
free(payload);
if (quiet)
return 0;
uint32_t reply_length;
uint32_t reply_type;
uint8_t *reply;
int ret;
if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
if (ret == -1)
if (ret == -1) {
err(EXIT_FAILURE, "IPC: read()");
}
exit(1);
}
if (reply_type != message_type)
if (reply_type != message_type) {
errx(EXIT_FAILURE, "IPC: Received reply of type %d but expected %d", reply_type, message_type);
}
/* For the reply of commands, have a look if that command was successful.
* If not, nicely format the error message. */
if (reply_type == I3_IPC_REPLY_TYPE_COMMAND) {
yajl_handle handle = yajl_alloc(&reply_callbacks, NULL, NULL);
yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length);
yajl_free(handle);
if (!raw_reply) {
yajl_handle handle = yajl_alloc(&reply_callbacks, NULL, NULL);
yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length);
yajl_free(handle);
switch (state) {
case yajl_status_ok:
break;
case yajl_status_client_canceled:
case yajl_status_error:
errx(EXIT_FAILURE, "IPC: Could not parse JSON reply.");
switch (state) {
case yajl_status_ok:
break;
case yajl_status_client_canceled:
case yajl_status_error:
errx(EXIT_FAILURE, "IPC: Could not parse JSON reply.");
}
}
/* NB: We still fall-through and print the reply, because even if one
* command failed, that doesnt mean that all commands failed. */
if (!quiet || raw_reply) {
printf("%.*s\n", reply_length, reply);
}
} else if (reply_type == I3_IPC_REPLY_TYPE_CONFIG) {
yajl_handle handle = yajl_alloc(&config_callbacks, NULL, NULL);
yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length);
yajl_free(handle);
if (raw_reply) {
printf("%.*s\n", reply_length, reply);
} else {
yajl_handle handle = yajl_alloc(&config_callbacks, NULL, NULL);
yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length);
yajl_free(handle);
switch (state) {
case yajl_status_ok:
break;
case yajl_status_client_canceled:
case yajl_status_error:
errx(EXIT_FAILURE, "IPC: Could not parse JSON reply.");
switch (state) {
case yajl_status_ok:
break;
case yajl_status_client_canceled:
case yajl_status_error:
errx(EXIT_FAILURE, "IPC: Could not parse JSON reply.");
}
}
} else if (reply_type == I3_IPC_REPLY_TYPE_SUBSCRIBE) {
do {
free(reply);
if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
if (ret == -1) {
err(EXIT_FAILURE, "IPC: read()");
}
exit(1);
}
goto exit;
if (!(reply_type & I3_IPC_EVENT_MASK)) {
errx(EXIT_FAILURE, "IPC: Received reply of type %d but expected an event", reply_type);
}
if (!quiet) {
fprintf(stdout, "%.*s\n", reply_length, reply);
fflush(stdout);
}
} while (monitor);
} else {
if (!quiet) {
printf("%.*s\n", reply_length, reply);
}
}
printf("%.*s\n", reply_length, reply);
exit:
free(reply);
close(sockfd);
return 0;
return exit_code;
}

View File

@@ -1,6 +0,0 @@
xmacro(_NET_WM_WINDOW_TYPE)
xmacro(_NET_WM_WINDOW_TYPE_DOCK)
xmacro(_NET_WM_STRUT_PARTIAL)
xmacro(I3_SOCKET_PATH)
xmacro(ATOM)
xmacro(CARDINAL)

View File

@@ -0,0 +1,8 @@
// clang-format off
#define NAGBAR_ATOMS_XMACRO \
xmacro(_NET_WM_WINDOW_TYPE) \
xmacro(_NET_WM_WINDOW_TYPE_DOCK) \
xmacro(_NET_WM_STRUT_PARTIAL) \
xmacro(I3_SOCKET_PATH) \
xmacro(ATOM) \
xmacro(CARDINAL)

View File

@@ -1,18 +0,0 @@
#pragma once
#include <config.h>
#include <err.h>
#define die(...) errx(EXIT_FAILURE, __VA_ARGS__);
#define FREE(pointer) \
do { \
free(pointer); \
pointer = NULL; \
} while (0)
#define xmacro(atom) xcb_atom_t A_##atom;
#include "atoms.xmacro"
#undef xmacro
extern xcb_window_t root;

View File

@@ -1,42 +1,41 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* i3-nagbar is a utility which displays a nag message, for example in the case
* when the user has an error in their configuration file.
*
*/
#include <config.h>
#include "libi3.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include <stdint.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <fcntl.h>
#include <paths.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <xcb/randr.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_event.h>
#include <xcb/randr.h>
#include <xcb/xcb_cursor.h>
#include "i3-nagbar.h"
xcb_visualtype_t *visual_type = NULL;
/** This is the equivalent of XC_left_ptr. Im not sure why xcb doesnt have a
* constant for that. */
#define XCB_CURSOR_LEFT_PTR 68
#define SN_API_NOT_YET_FROZEN 1
#include <libsn/sn-launchee.h>
#include "i3-nagbar-atoms.xmacro.h"
#define MSG_PADDING logical_px(8)
#define BTN_PADDING logical_px(3)
@@ -45,6 +44,12 @@
#define CLOSE_BTN_GAP logical_px(15)
#define BAR_BORDER logical_px(2)
#define xmacro(atom) xcb_atom_t A_##atom;
NAGBAR_ATOMS_XMACRO
#undef xmacro
#define die(...) errx(EXIT_FAILURE, __VA_ARGS__);
static char *argv0 = NULL;
typedef struct {
@@ -52,6 +57,7 @@ typedef struct {
char *action;
int16_t x;
uint16_t width;
bool terminal;
} button_t;
static xcb_window_t win;
@@ -83,7 +89,7 @@ void verboselog(char *fmt, ...) {
va_list args;
va_start(args, fmt);
vfprintf(stdout, fmt, args);
vfprintf(stderr, fmt, args);
va_end(args);
}
@@ -99,14 +105,10 @@ void debuglog(char *fmt, ...) {
}
/*
* Starts the given application by passing it through a shell. We use double fork
* to avoid zombie processes. As the started applications parent exits (immediately),
* the application is reparented to init (process-id 1), which correctly handles
* childs, so we dont have to do it :-).
*
* The shell is determined by looking for the SHELL environment variable. If it
* does not exist, /bin/sh is used.
*
* Starts the given application by passing it through a shell. We use double
* fork to avoid zombie processes. As the started applications parent exits
* (immediately), the application is reparented to init (process-id 1), which
* correctly handles children, so we dont have to do it :-).
*/
static void start_application(const char *command) {
printf("executing: %s\n", command);
@@ -115,7 +117,7 @@ static void start_application(const char *command) {
setsid();
if (fork() == 0) {
/* This is the child */
execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (void *)NULL);
execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, NULL);
/* not reached */
}
exit(0);
@@ -124,9 +126,11 @@ static void start_application(const char *command) {
}
static button_t *get_button_at(int16_t x, int16_t y) {
for (int c = 0; c < buttoncnt; c++)
if (x >= (buttons[c].x) && x <= (buttons[c].x + buttons[c].width))
for (int c = 0; c < buttoncnt; c++) {
if (x >= (buttons[c].x) && x <= (buttons[c].x + buttons[c].width)) {
return &buttons[c];
}
}
return NULL;
}
@@ -146,11 +150,13 @@ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_eve
printf("button released on x = %d, y = %d\n",
event->event_x, event->event_y);
/* If the user hits the close button, we exit(0) */
if (event->event_x >= btn_close.x && event->event_x < btn_close.x + btn_close.width)
if (event->event_x >= btn_close.x && event->event_x < btn_close.x + btn_close.width) {
exit(0);
}
button_t *button = get_button_at(event->event_x, event->event_y);
if (!button)
if (!button) {
return;
}
/* We need to create a custom script containing our actual command
* since not every terminal emulator which is contained in
@@ -172,7 +178,7 @@ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_eve
warn("Could not fdopen() temporary script to store the nagbar command");
return;
}
fprintf(script, "#!/bin/sh\nrm %s\n%s", script_path, button->action);
fprintf(script, "#!%s\nrm %s\n%s", _PATH_BSHELL, script_path, button->action);
/* Also closes fd */
fclose(script);
@@ -184,7 +190,11 @@ static void handle_button_release(xcb_connection_t *conn, xcb_button_release_eve
}
char *terminal_cmd;
sasprintf(&terminal_cmd, "i3-sensible-terminal -e %s", link_path);
if (button->terminal) {
sasprintf(&terminal_cmd, "i3-sensible-terminal -e %s", link_path);
} else {
terminal_cmd = sstrdup(link_path);
}
printf("argv0 = %s\n", argv0);
printf("terminal_cmd = %s\n", terminal_cmd);
@@ -260,13 +270,9 @@ static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
}
/**
* Return the position and size the i3-nagbar window should use.
* This will be the primary output or a fallback if it cannot be determined.
* Tries to position the rectangle on the primary output.
*/
static xcb_rectangle_t get_window_position(void) {
/* Default values if we cannot determine the primary output or its CRTC info. */
xcb_rectangle_t result = (xcb_rectangle_t){50, 50, 500, font.height + 2 * MSG_PADDING + BAR_BORDER};
static void set_window_position_primary(xcb_rectangle_t *result) {
xcb_randr_get_screen_resources_current_cookie_t rcookie = xcb_randr_get_screen_resources_current(conn, root);
xcb_randr_get_output_primary_cookie_t pcookie = xcb_randr_get_output_primary(conn, root);
@@ -274,11 +280,12 @@ static xcb_rectangle_t get_window_position(void) {
xcb_randr_get_screen_resources_current_reply_t *res = NULL;
if ((primary = xcb_randr_get_output_primary_reply(conn, pcookie, NULL)) == NULL) {
DLOG("Could not determine the primary output.\n");
LOG("Could not determine the primary output.\n");
goto free_resources;
}
if ((res = xcb_randr_get_screen_resources_current_reply(conn, rcookie, NULL)) == NULL) {
LOG("Could not query screen resources.\n");
goto free_resources;
}
@@ -286,31 +293,82 @@ static xcb_rectangle_t get_window_position(void) {
xcb_randr_get_output_info_reply(conn,
xcb_randr_get_output_info(conn, primary->output, res->config_timestamp),
NULL);
if (output == NULL || output->crtc == XCB_NONE)
if (output == NULL || output->crtc == XCB_NONE) {
LOG("Could not query primary screen.\n");
goto free_resources;
}
xcb_randr_get_crtc_info_reply_t *crtc =
xcb_randr_get_crtc_info_reply(conn,
xcb_randr_get_crtc_info(conn, output->crtc, res->config_timestamp),
NULL);
if (crtc == NULL)
goto free_resources;
DLOG("Found primary output on position x = %i / y = %i / w = %i / h = %i.\n",
crtc->x, crtc->y, crtc->width, crtc->height);
if (crtc->width == 0 || crtc->height == 0) {
DLOG("Primary output is not active, ignoring it.\n");
if (crtc == NULL) {
LOG("Could not get CRTC.\n");
goto free_resources;
}
result.x = crtc->x;
result.y = crtc->y;
LOG("Found primary output on position x = %i / y = %i / w = %i / h = %i.\n",
crtc->x, crtc->y, crtc->width, crtc->height);
if (crtc->width == 0 || crtc->height == 0) {
LOG("Primary output is not active, ignoring it.\n");
goto free_resources;
}
result->x = crtc->x;
result->y = crtc->y;
goto free_resources;
free_resources:
FREE(res);
FREE(primary);
return result;
free(res);
free(primary);
}
/**
* Tries to position the rectangle on the output with input focus.
* If unsuccessful, try to position on primary output.
*/
static void set_window_position_focus(xcb_rectangle_t *result) {
bool success = false;
xcb_get_input_focus_reply_t *input_focus = NULL;
xcb_get_geometry_reply_t *geometry = NULL;
xcb_translate_coordinates_reply_t *coordinates = NULL;
/* To avoid the input window disappearing while determining its position */
xcb_grab_server(conn);
input_focus = xcb_get_input_focus_reply(conn, xcb_get_input_focus(conn), NULL);
if (input_focus == NULL || input_focus->focus == XCB_NONE) {
LOG("Failed to receive the current input focus or no window has the input focus right now.\n");
goto free_resources;
}
geometry = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, input_focus->focus), NULL);
if (geometry == NULL) {
LOG("Failed to received window geometry.\n");
goto free_resources;
}
coordinates = xcb_translate_coordinates_reply(
conn, xcb_translate_coordinates(conn, input_focus->focus, root, geometry->x, geometry->y), NULL);
if (coordinates == NULL) {
LOG("Failed to translate coordinates.\n");
goto free_resources;
}
LOG("Found current focus at x = %i / y = %i.\n", coordinates->dst_x, coordinates->dst_y);
result->x = coordinates->dst_x;
result->y = coordinates->dst_y;
success = true;
free_resources:
xcb_ungrab_server(conn);
free(input_focus);
free(coordinates);
free(geometry);
if (!success) {
LOG("Could not position on focused output, trying to position on primary output.\n");
set_window_position_primary(result);
}
}
int main(int argc, char *argv[]) {
@@ -343,12 +401,13 @@ int main(int argc, char *argv[]) {
unlink(argv[0]);
cmd = sstrdup(argv[0]);
*(cmd + argv0_len - strlen(".nagbar_cmd")) = '\0';
execl("/bin/sh", "/bin/sh", cmd, NULL);
err(EXIT_FAILURE, "execv(/bin/sh, /bin/sh, %s)", cmd);
execl(_PATH_BSHELL, _PATH_BSHELL, cmd, NULL);
err(EXIT_FAILURE, "execl(%s, %s, %s)", _PATH_BSHELL, _PATH_BSHELL, cmd);
}
argv0 = argv[0];
bool position_on_primary = false;
char *pattern = sstrdup("pango:monospace 8");
int o, option_index = 0;
enum { TYPE_ERROR = 0,
@@ -358,22 +417,25 @@ int main(int argc, char *argv[]) {
{"version", no_argument, 0, 'v'},
{"font", required_argument, 0, 'f'},
{"button", required_argument, 0, 'b'},
{"button-no-terminal", required_argument, 0, 'B'},
{"help", no_argument, 0, 'h'},
{"message", required_argument, 0, 'm'},
{"type", required_argument, 0, 't'},
{"primary", no_argument, 0, 'p'},
{0, 0, 0, 0}};
char *options_string = "b:f:m:t:vh";
char *options_string = "b:B:f:m:t:vhp";
prompt = i3string_from_utf8("Please do not run this program.");
while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
switch (o) {
case 'v':
free(pattern);
printf("i3-nagbar " I3_VERSION "\n");
return 0;
case 'f':
FREE(pattern);
free(pattern);
pattern = sstrdup(optarg);
break;
case 'm':
@@ -384,20 +446,27 @@ int main(int argc, char *argv[]) {
bar_type = (strcasecmp(optarg, "warning") == 0 ? TYPE_WARNING : TYPE_ERROR);
break;
case 'h':
free(pattern);
printf("i3-nagbar " I3_VERSION "\n");
printf("i3-nagbar [-m <message>] [-b <button> <action>] [-t warning|error] [-f <font>] [-v]\n");
printf("i3-nagbar [-m <message>] [-b <button> <action>] [-B <button> <action>] [-t warning|error] [-f <font>] [-v] [-p]\n");
return 0;
case 'p':
position_on_primary = true;
break;
case 'b':
case 'B':
buttons = srealloc(buttons, sizeof(button_t) * (buttoncnt + 1));
buttons[buttoncnt].label = i3string_from_utf8(optarg);
buttons[buttoncnt].action = argv[optind];
buttons[buttoncnt].terminal = (o == 'b');
printf("button with label *%s* and action *%s*\n",
i3string_as_utf8(buttons[buttoncnt].label),
buttons[buttoncnt].action);
buttoncnt++;
printf("now %d buttons\n", buttoncnt);
if (optind < argc)
if (optind < argc) {
optind++;
}
break;
}
}
@@ -406,15 +475,21 @@ int main(int argc, char *argv[]) {
int screens;
if ((conn = xcb_connect(NULL, &screens)) == NULL ||
xcb_connection_has_error(conn))
die("Cannot open display\n");
xcb_connection_has_error(conn)) {
die("Cannot open display");
}
/* Place requests for the atoms we need as soon as possible */
#define xmacro(atom) \
xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
#include "atoms.xmacro"
NAGBAR_ATOMS_XMACRO
#undef xmacro
/* Init startup notification. */
SnDisplay *sndisplay = sn_xcb_display_new(conn, NULL, NULL);
SnLauncheeContext *sncontext = sn_launchee_context_new_from_environment(sndisplay, screens);
sn_display_unref(sndisplay);
root_screen = xcb_aux_get_screen(conn, screens);
root = root_screen->root;
@@ -438,32 +513,21 @@ int main(int argc, char *argv[]) {
font = load_font(pattern, true);
set_font(&font);
#if defined(__OpenBSD__)
if (pledge("stdio rpath wpath cpath getpw proc exec", NULL) == -1)
err(EXIT_FAILURE, "pledge");
#endif
xcb_rectangle_t win_pos = get_window_position();
xcb_cursor_t cursor;
xcb_cursor_context_t *cursor_ctx;
if (xcb_cursor_context_new(conn, root_screen, &cursor_ctx) == 0) {
cursor = xcb_cursor_load_cursor(cursor_ctx, "left_ptr");
xcb_cursor_context_free(cursor_ctx);
/* Default values if we cannot determine the preferred window position. */
xcb_rectangle_t win_pos = (xcb_rectangle_t){50, 50, 500, font.height + 2 * MSG_PADDING + BAR_BORDER};
if (position_on_primary) {
set_window_position_primary(&win_pos);
} else {
cursor = xcb_generate_id(conn);
i3Font cursor_font = load_font("cursor", false);
xcb_create_glyph_cursor(
conn,
cursor,
cursor_font.specific.xcb.id,
cursor_font.specific.xcb.id,
XCB_CURSOR_LEFT_PTR,
XCB_CURSOR_LEFT_PTR + 1,
0, 0, 0,
65535, 65535, 65535);
set_window_position_focus(&win_pos);
}
xcb_cursor_context_t *cursor_ctx;
if (xcb_cursor_context_new(conn, root_screen, &cursor_ctx) < 0) {
errx(EXIT_FAILURE, "Cannot allocate xcursor context");
}
xcb_cursor_t cursor = xcb_cursor_load_cursor(cursor_ctx, "left_ptr");
xcb_cursor_context_free(cursor_ctx);
/* Open an input window */
win = xcb_generate_id(conn);
@@ -484,6 +548,9 @@ int main(int argc, char *argv[]) {
XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_BUTTON_RELEASE,
cursor});
if (sncontext) {
sn_launchee_context_setup_window(sncontext, win);
}
/* Map the window (make it visible) */
xcb_map_window(conn, win);
@@ -493,12 +560,12 @@ int main(int argc, char *argv[]) {
do { \
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \
if (!reply) \
die("Could not get atom " #name "\n"); \
die("Could not get atom " #name); \
\
A_##name = reply->atom; \
free(reply); \
} while (0);
#include "atoms.xmacro"
NAGBAR_ATOMS_XMACRO
#undef xmacro
/* Set dock mode */
@@ -544,6 +611,12 @@ int main(int argc, char *argv[]) {
/* Initialize the drawable bar */
draw_util_surface_init(conn, &bar, win, get_visualtype(root_screen), win_pos.width, win_pos.height);
/* Startup complete. */
if (sncontext) {
sn_launchee_context_complete(sncontext);
sn_launchee_context_unref(sncontext);
}
/* Grab the keyboard to get all input */
xcb_flush(conn);
@@ -585,7 +658,7 @@ int main(int argc, char *argv[]) {
free(event);
}
FREE(pattern);
free(pattern);
draw_util_surface_free(conn, &bar);
return 0;

View File

@@ -123,9 +123,7 @@ sub strip_containers {
delete $tree->{current_border_width} if $tree->{current_border_width} == -1;
for my $key (keys %$tree) {
next if exists($allowed_keys{$key});
delete $tree->{$key};
delete $tree->{$key} unless exists($allowed_keys{$key});
}
for my $key (qw(nodes floating_nodes)) {
@@ -169,7 +167,8 @@ sub dump_containers {
if (leaf_node($tree)) {
my $swallows = {};
for my $property (keys %{$tree->{window_properties}}) {
$swallows->{$property} = '^' . quotemeta($tree->{window_properties}->{$property}) . '$';
$swallows->{$property} = '^' . quotemeta($tree->{window_properties}->{$property}) . '$'
if $property ne 'transient_for';
}
$tree->{swallows} = [ $swallows ];
}

View File

@@ -8,6 +8,11 @@
# Distributions/packagers can enhance this script with a
# distribution-specific mechanism to find the preferred pager.
# The less -E and -F options exit immediately for short files, strip if present.
case "$LESS" in
*[EF]*) LESS=`echo "$LESS" | tr -d EF`
esac
# Hopefully one of these is installed (no flamewars about preference please!):
# We don't use 'more' because it will exit if the file is too short.
# Worst case scenario we'll open the file in your editor.

View File

@@ -8,7 +8,13 @@
# We welcome patches that add distribution-specific mechanisms to find the
# preferred terminal emulator. On Debian, there is the x-terminal-emulator
# symlink for example.
for terminal in "$TERMINAL" x-terminal-emulator urxvt rxvt termit terminator Eterm aterm uxterm xterm gnome-terminal roxterm xfce4-terminal termite lxterminal mate-terminal terminology st qterminal lilyterm tilix terminix konsole kitty guake tilda; do
#
# Invariants:
# 1. $TERMINAL must come first
# 2. Distribution-specific mechanisms come next, e.g. x-terminal-emulator
# 3. The terminal emulator with best accessibility comes first.
# 4. No order is guaranteed/desired for the remaining terminal emulators.
for terminal in "$TERMINAL" x-terminal-emulator mate-terminal gnome-terminal terminator xfce4-terminal urxvt rxvt termit Eterm aterm uxterm xterm roxterm termite lxterminal terminology st qterminal lilyterm tilix terminix konsole kitty guake tilda alacritty hyper wezterm rio; do
if command -v "$terminal" > /dev/null 2>&1; then
exec "$terminal" "$@"
fi

View File

@@ -11,7 +11,7 @@
#include <config.h>
#include <stdbool.h>
#include <ev.h>
#define STDIN_CHUNK_SIZE 1024
@@ -31,7 +31,7 @@ typedef struct {
*/
int stop_signal;
/**
* The signal requested by the client to inform it of theun hidden state of i3bar
* The signal requested by the client to inform it of the unhidden state of i3bar
*/
int cont_signal;
@@ -40,40 +40,88 @@ typedef struct {
*/
bool click_events;
bool click_events_init;
/**
* stdin- and SIGCHLD-watchers
*/
ev_io *stdin_io;
ev_child *child_sig;
int stdin_fd;
/**
* Line read from child that did not include a newline character.
*/
char *pending_line;
} i3bar_child;
/*
* Remove all blocks from the given statusline.
* If free_resources is set, the fields of each status block will be free'd.
*/
void clear_statusline(struct statusline_head *head, bool free_resources);
/*
* Start a child process with the specified command and reroute stdin.
* We actually start a $SHELL to execute the command so we don't have to care
* about arguments and such
* We actually start a shell to execute the command so we don't have to care
* about arguments and such.
*
* If `command' is NULL, such as in the case when no `status_command' is given
* in the bar config, no child will be started.
*
*/
void start_child(char *command);
/*
* Same as start_child but starts the configured client that manages workspace
* buttons.
*
*/
void start_ws_child(char *command);
/*
* Returns true if the status child process is alive.
*
*/
bool status_child_is_alive(void);
/*
* Returns true if the workspace child process is alive.
*
*/
bool ws_child_is_alive(void);
/*
* kill()s the child process (if any). Called when exit()ing.
*
*/
void kill_child_at_exit(void);
void kill_children_at_exit(void);
/*
* kill()s the child process (if any) and closes and
* free()s the stdin- and SIGCHLD-watchers
* kill()s the child process (if any) and closes and free()s the stdin- and
* SIGCHLD-watchers
*
*/
void kill_child(void);
/*
* kill()s the workspace child process (if any) and closes and free()s the
* stdin- and SIGCHLD-watchers.
* Similar to kill_child.
*
*/
void kill_ws_child(void);
/*
* Sends a SIGSTOP to the child process (if existent)
*
*/
void stop_child(void);
void stop_children(void);
/*
* Sends a SIGCONT to the child process (if existent)
*
*/
void cont_child(void);
void cont_children(void);
/*
* Whether or not the child want click events
@@ -85,4 +133,15 @@ bool child_want_click_events(void);
* Generates a click event, if enabled.
*
*/
void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int width, int height);
void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int out_x, int out_y, int width, int height, int mods);
/*
* When workspace_command is enabled this function is used to re-parse the
* latest received JSON from the client.
*/
void repeat_last_ws_json(void);
/*
* Replaces the workspace buttons with an error message.
*/
void set_workspace_button_error(const char *message);

View File

@@ -9,7 +9,6 @@
#include <config.h>
#include <stdbool.h>
#include <xcb/xcb.h>
#include <xcb/xproto.h>
#include "libi3.h"
@@ -17,7 +16,7 @@
typedef struct rect_t rect;
struct ev_loop *main_loop;
extern struct ev_loop *main_loop;
struct rect_t {
int x;
@@ -47,6 +46,9 @@ struct status_block {
i3String *full_text;
i3String *short_text;
bool use_short;
uint32_t render_length;
char *color;
char *background;
char *border;
@@ -61,9 +63,13 @@ struct status_block {
bool urgent;
bool no_separator;
uint32_t border_top;
uint32_t border_right;
uint32_t border_bottom;
uint32_t border_left;
bool pango_markup;
/* The amount of pixels necessary to render a separater after the block. */
/* The amount of pixels necessary to render a separator after the block. */
uint32_t sep_block_width;
/* Continuously-updated information on how to render this status block. */
@@ -74,12 +80,10 @@ struct status_block {
char *name;
char *instance;
TAILQ_ENTRY(status_block)
blocks;
TAILQ_ENTRY(status_block) blocks;
};
TAILQ_HEAD(statusline_head, status_block)
statusline_head;
extern TAILQ_HEAD(statusline_head, status_block) statusline_head;
#include "child.h"
#include "ipc.h"
@@ -90,5 +94,4 @@ statusline_head;
#include "trayclients.h"
#include "xcb.h"
#include "configuration.h"
#include "libi3.h"
#include "parse_json_header.h"

View File

@@ -29,37 +29,43 @@ typedef struct binding_t {
char *command;
bool release;
TAILQ_ENTRY(binding_t)
bindings;
TAILQ_ENTRY(binding_t) bindings;
} binding_t;
typedef struct tray_output_t {
char *output;
TAILQ_ENTRY(tray_output_t)
tray_outputs;
TAILQ_ENTRY(tray_output_t) tray_outputs;
} tray_output_t;
/* Matches i3/include/data.h */
struct Rect {
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
};
typedef struct config_t {
int modifier;
TAILQ_HEAD(bindings_head, binding_t)
bindings;
uint32_t modifier;
TAILQ_HEAD(bindings_head, binding_t) bindings;
position_t position;
int verbose;
bool verbose;
uint32_t bar_height;
struct Rect padding;
bool transparency;
struct xcb_color_strings_t colors;
bool disable_binding_mode_indicator;
bool disable_ws;
int ws_min_width;
bool strip_ws_numbers;
bool strip_ws_name;
char *bar_id;
char *command;
char *workspace_command;
char *fontname;
i3String *separator_symbol;
TAILQ_HEAD(tray_outputs_head, tray_output_t)
tray_outputs;
TAILQ_HEAD(tray_outputs_head, tray_output_t) tray_outputs;
int tray_padding;
int num_outputs;
char **outputs;
@@ -71,13 +77,20 @@ typedef struct config_t {
S_SHOW = 1 } hidden_state;
} config_t;
config_t config;
extern config_t config;
/**
* Start parsing the received bar configuration JSON string
* Parse the received bar configuration JSON string
*
*/
void parse_config_json(char *json);
void parse_config_json(const unsigned char *json, size_t size);
/**
* Parse the received bar configuration list. The only usecase right now is to
* automatically get the first bar id.
*
*/
void parse_get_first_i3bar_config(const unsigned char *json, size_t size);
/**
* free()s the color strings as soon as they are not needed anymore.

View File

@@ -18,7 +18,7 @@
* socket_path must be a valid path to the ipc_socket of i3
*
*/
int init_connection(const char *socket_path);
void init_connection(const char *socket_path);
/*
* Destroy the connection to i3.

View File

@@ -18,13 +18,13 @@
/* Name of current binding mode and its render width */
struct mode {
i3String *name;
int width;
int name_width;
};
typedef struct mode mode;
/*
* Start parsing the received JSON string
* Parse the received JSON string
*
*/
void parse_mode_json(char *json);
void parse_mode_json(const unsigned char *json, size_t size);

View File

@@ -19,13 +19,13 @@
typedef struct i3_output i3_output;
SLIST_HEAD(outputs_head, i3_output);
struct outputs_head* outputs;
extern struct outputs_head* outputs;
/*
* Start parsing the received JSON string
* Parse the received JSON string
*
*/
void parse_outputs_json(char* json);
void parse_outputs_json(const unsigned char* json, size_t size);
/*
* Initiate the outputs list
@@ -65,14 +65,11 @@ struct i3_output {
surface_t statusline_buffer;
/* How much of statusline_buffer's horizontal space was used on last statusline render. */
int statusline_width;
/* Whether statusline block short texts where used on last statusline render. */
bool statusline_short_text;
/* The actual window on which we draw. */
surface_t bar;
struct ws_head* workspaces; /* The workspaces on this output */
struct tc_head* trayclients; /* The tray clients on this output */
SLIST_ENTRY(i3_output)
slist; /* Pointer for the SLIST-Macro */
SLIST_ENTRY(i3_output) slist; /* Pointer for the SLIST-Macro */
};

View File

@@ -18,6 +18,8 @@ struct trayclient {
bool mapped; /* Whether this window is mapped */
int xe_version; /* The XEMBED version supported by the client */
TAILQ_ENTRY(trayclient)
tailq; /* Pointer for the TAILQ-Macro */
char *class_class;
char *class_instance;
TAILQ_ENTRY(trayclient) tailq; /* Pointer for the TAILQ-Macro */
};

View File

@@ -1,7 +1,7 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
*/

View File

@@ -18,10 +18,10 @@ typedef struct i3_ws i3_ws;
TAILQ_HEAD(ws_head, i3_ws);
/*
* Start parsing the received JSON string
* Parse the received JSON string
*
*/
void parse_workspaces_json(char *json);
void parse_workspaces_json(const unsigned char *json, size_t size);
/*
* free() all workspace data structures
@@ -30,6 +30,7 @@ void parse_workspaces_json(char *json);
void free_workspaces(void);
struct i3_ws {
uintptr_t id; /* Workspace ID - C pointer to a workspace container */
int num; /* The internal number of the ws */
char *canonical_name; /* The true name of the ws according to the ipc */
i3String *name; /* The name of the ws that is displayed on the bar */
@@ -37,9 +38,7 @@ struct i3_ws {
bool visible; /* If the ws is currently visible on an output */
bool focused; /* If the ws is currently focused */
bool urgent; /* If the urgent hint of the ws is set */
rect rect; /* The rect of the ws (not used (yet)) */
struct i3_output *output; /* The current output of the ws */
TAILQ_ENTRY(i3_ws)
tailq; /* Pointer for the TAILQ-Macro */
TAILQ_ENTRY(i3_ws) tailq; /* Pointer for the TAILQ-Macro */
};

View File

@@ -12,7 +12,6 @@
#include <config.h>
#include <stdint.h>
//#include "outputs.h"
#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
#define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1
@@ -53,14 +52,14 @@ struct xcb_color_strings_t {
typedef struct xcb_colors_t xcb_colors_t;
/* Cached width of the custom separator if one was set */
int separator_symbol_width;
extern int separator_symbol_width;
/*
* Early initialization of the connection to X11: Everything which does not
* depend on 'config'.
*
*/
char *init_xcb_early();
char *init_xcb_early(void);
/**
* Initialization which depends on 'config' being usable. Called after the

View File

@@ -8,31 +8,52 @@
*
*/
#include "common.h"
#include "queue.h"
#include "yajl_utils.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <stdarg.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <ctype.h> /* isspace */
#include <err.h>
#include <errno.h>
#include <ev.h>
#include <yajl/yajl_common.h>
#include <yajl/yajl_parse.h>
#include <yajl/yajl_version.h>
#include <yajl/yajl_gen.h>
#include <fcntl.h>
#include <paths.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/wait.h>
#include <unistd.h>
#include <yajl/yajl_gen.h>
#include <yajl/yajl_parse.h>
/* Global variables for child_*() */
i3bar_child child;
i3bar_child status_child = {0};
i3bar_child ws_child = {0};
/* stdin- and SIGCHLD-watchers */
ev_io *stdin_io;
ev_child *child_sig;
#define DLOG_CHILD(c) \
do { \
if ((c).pid == 0) { \
DLOG("%s: child pid = 0\n", __func__); \
} else if ((c).pid == status_child.pid) { \
DLOG("%s: status_command: pid=%ld stopped=%d stop_signal=%d cont_signal=%d click_events=%d click_events_init=%d\n", \
__func__, (long)(c).pid, (c).stopped, (c).stop_signal, (c).cont_signal, (c).click_events, (c).click_events_init); \
} else if ((c).pid == ws_child.pid) { \
DLOG("%s: workspace_command: pid=%ld stopped=%d stop_signal=%d cont_signal=%d click_events=%d click_events_init=%d\n", \
__func__, (long)(c).pid, (c).stopped, (c).stop_signal, (c).cont_signal, (c).click_events, (c).click_events_init); \
} else { \
ELOG("%s: unknown child, this should never happen " \
"pid=%ld stopped=%d stop_signal=%d cont_signal=%d click_events=%d click_events_init=%d\n", \
__func__, (long)(c).pid, (c).stopped, (c).stop_signal, (c).cont_signal, (c).click_events, (c).click_events_init); \
} \
} while (0)
#define DLOG_CHILDREN \
do { \
DLOG_CHILD(status_child); \
DLOG_CHILD(ws_child); \
} while (0)
/* JSON parser for stdin */
yajl_handle parser;
@@ -64,7 +85,7 @@ int child_stdin;
* Remove all blocks from the given statusline.
* If free_resources is set, the fields of each status block will be free'd.
*/
static void clear_statusline(struct statusline_head *head, bool free_resources) {
void clear_statusline(struct statusline_head *head, bool free_resources) {
struct status_block *first;
while (!TAILQ_EMPTY(head)) {
first = TAILQ_FIRST(head);
@@ -86,7 +107,7 @@ static void clear_statusline(struct statusline_head *head, bool free_resources)
static void copy_statusline(struct statusline_head *from, struct statusline_head *to) {
struct status_block *current;
TAILQ_FOREACH(current, from, blocks) {
TAILQ_FOREACH (current, from, blocks) {
struct status_block *new_block = smalloc(sizeof(struct status_block));
memcpy(new_block, current, sizeof(struct status_block));
TAILQ_INSERT_TAIL(to, new_block, blocks);
@@ -125,7 +146,7 @@ __attribute__((format(printf, 1, 2))) static void set_statusline_error(const cha
TAILQ_INSERT_TAIL(&statusline_head, message_block, blocks);
finish:
FREE(message);
free(message);
va_end(args);
}
@@ -133,18 +154,27 @@ finish:
* Stop and free() the stdin- and SIGCHLD-watchers
*
*/
void cleanup(void) {
if (stdin_io != NULL) {
ev_io_stop(main_loop, stdin_io);
FREE(stdin_io);
static void cleanup(i3bar_child *c) {
DLOG_CHILD(*c);
if (c->stdin_io != NULL) {
ev_io_stop(main_loop, c->stdin_io);
FREE(c->stdin_io);
if (c->pid == status_child.pid) {
close(child_stdin);
child_stdin = 0;
}
close(c->stdin_fd);
}
if (child_sig != NULL) {
ev_child_stop(main_loop, child_sig);
FREE(child_sig);
if (c->child_sig != NULL) {
ev_child_stop(main_loop, c->child_sig);
FREE(c->child_sig);
}
memset(&child, 0, sizeof(i3bar_child));
FREE(c->pending_line);
memset(c, 0, sizeof(i3bar_child));
}
/*
@@ -167,10 +197,17 @@ static int stdin_start_map(void *context) {
memset(&(ctx->block), '\0', sizeof(struct status_block));
/* Default width of the separator block. */
if (config.separator_symbol == NULL)
if (config.separator_symbol == NULL) {
ctx->block.sep_block_width = logical_px(9);
else
} else {
ctx->block.sep_block_width = logical_px(8) + separator_symbol_width;
}
/* By default we draw all four borders if a border is set. */
ctx->block.border_top = 1;
ctx->block.border_right = 1;
ctx->block.border_bottom = 1;
ctx->block.border_left = 1;
return 1;
}
@@ -184,6 +221,11 @@ static int stdin_map_key(void *context, const unsigned char *key, size_t len) {
static int stdin_boolean(void *context, int val) {
parser_ctx *ctx = context;
if (!ctx->last_map_key) {
return 0;
}
if (strcasecmp(ctx->last_map_key, "urgent") == 0) {
ctx->block.urgent = val;
return 1;
@@ -198,6 +240,11 @@ static int stdin_boolean(void *context, int val) {
static int stdin_string(void *context, const unsigned char *val, size_t len) {
parser_ctx *ctx = context;
if (!ctx->last_map_key) {
return 0;
}
if (strcasecmp(ctx->last_map_key, "full_text") == 0) {
ctx->block.full_text = i3string_from_markup_with_length((const char *)val, len);
return 1;
@@ -250,6 +297,11 @@ static int stdin_string(void *context, const unsigned char *val, size_t len) {
static int stdin_integer(void *context, long long val) {
parser_ctx *ctx = context;
if (!ctx->last_map_key) {
return 0;
}
if (strcasecmp(ctx->last_map_key, "min_width") == 0) {
ctx->block.min_width = (uint32_t)val;
return 1;
@@ -258,6 +310,22 @@ static int stdin_integer(void *context, long long val) {
ctx->block.sep_block_width = (uint32_t)val;
return 1;
}
if (strcasecmp(ctx->last_map_key, "border_top") == 0) {
ctx->block.border_top = (uint32_t)val;
return 1;
}
if (strcasecmp(ctx->last_map_key, "border_right") == 0) {
ctx->block.border_right = (uint32_t)val;
return 1;
}
if (strcasecmp(ctx->last_map_key, "border_bottom") == 0) {
ctx->block.border_bottom = (uint32_t)val;
return 1;
}
if (strcasecmp(ctx->last_map_key, "border_left") == 0) {
ctx->block.border_left = (uint32_t)val;
return 1;
}
return 1;
}
@@ -272,10 +340,12 @@ static int stdin_end_map(void *context) {
memcpy(new_block, &(ctx->block), sizeof(struct status_block));
/* Ensure we have a full_text set, so that when it is missing (or null),
* i3bar doesnt crash and the user gets an annoying message. */
if (!new_block->full_text)
if (!new_block->full_text) {
new_block->full_text = i3string_from_utf8("SPEC VIOLATION: full_text is NULL!");
if (new_block->urgent)
}
if (new_block->urgent) {
ctx->has_urgent = true;
}
if (new_block->min_width_str) {
i3String *text = i3string_from_utf8(new_block->min_width_str);
@@ -286,10 +356,13 @@ static int stdin_end_map(void *context) {
i3string_set_markup(new_block->full_text, new_block->pango_markup);
if (new_block->short_text != NULL)
new_block->use_short = false;
if (new_block->short_text != NULL) {
i3string_set_markup(new_block->short_text, new_block->pango_markup);
}
TAILQ_INSERT_TAIL(&statusline_buffer, new_block, blocks);
return 1;
}
@@ -304,7 +377,7 @@ static int stdin_end_array(void *context) {
DLOG("dumping statusline:\n");
struct status_block *current;
TAILQ_FOREACH(current, &statusline_head, blocks) {
TAILQ_FOREACH (current, &statusline_head, blocks) {
DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
DLOG("short_text = %s\n", (current->short_text == NULL ? NULL : i3string_as_utf8(current->short_text)));
DLOG("color = %s\n", current->color);
@@ -319,15 +392,13 @@ static int stdin_end_array(void *context) {
* Returns NULL on EOF.
*
*/
static unsigned char *get_buffer(ev_io *watcher, int *ret_buffer_len) {
int fd = watcher->fd;
int n = 0;
static unsigned char *get_buffer(int fd, int *ret_buffer_len) {
int rec = 0;
int buffer_len = STDIN_CHUNK_SIZE;
unsigned char *buffer = smalloc(buffer_len + 1);
buffer[0] = '\0';
while (1) {
n = read(fd, buffer + rec, buffer_len - rec);
const ssize_t n = read(fd, buffer + rec, buffer_len - rec);
if (n == -1) {
if (errno == EAGAIN) {
/* finish up */
@@ -347,10 +418,11 @@ static unsigned char *get_buffer(ev_io *watcher, int *ret_buffer_len) {
if (rec == buffer_len) {
buffer_len += STDIN_CHUNK_SIZE;
buffer = srealloc(buffer, buffer_len);
buffer = srealloc(buffer, buffer_len + 1);
}
}
if (*buffer == '\0') {
buffer[rec] = '\0';
if (buffer[0] == '\0') {
FREE(buffer);
rec = -1;
}
@@ -380,8 +452,9 @@ static bool read_json_input(unsigned char *input, int length) {
char *message = (char *)yajl_get_error(parser, 0, input, length);
/* strip the newline yajl adds to the error message */
if (message[strlen(message) - 1] == '\n')
if (message[strlen(message) - 1] == '\n') {
message[strlen(message) - 1] = '\0';
}
fprintf(stderr, "[i3bar] Could not parse JSON input (code = %d, message = %s): %.*s\n",
status, message, length, input);
@@ -400,13 +473,14 @@ static bool read_json_input(unsigned char *input, int length) {
* in statusline
*
*/
void stdin_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
static void stdin_io_cb(int fd) {
int rec;
unsigned char *buffer = get_buffer(watcher, &rec);
if (buffer == NULL)
unsigned char *buffer = get_buffer(fd, &rec);
if (buffer == NULL) {
return;
}
bool has_urgent = false;
if (child.version > 0) {
if (status_child.version > 0) {
has_urgent = read_json_input(buffer, rec);
} else {
read_flat_input((char *)buffer, rec);
@@ -420,22 +494,23 @@ void stdin_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
* whether this is JSON or plain text
*
*/
void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
static void stdin_io_first_line_cb(int fd) {
int rec;
unsigned char *buffer = get_buffer(watcher, &rec);
if (buffer == NULL)
unsigned char *buffer = get_buffer(fd, &rec);
if (buffer == NULL) {
return;
}
DLOG("Detecting input type based on buffer *%.*s*\n", rec, buffer);
/* Detect whether this is JSON or plain text. */
unsigned int consumed = 0;
/* At the moment, we dont care for the version. This might change
* in the future, but for now, we just discard it. */
parse_json_header(&child, buffer, rec, &consumed);
if (child.version > 0) {
/* If hide-on-modifier is set, we start of by sending the
* child a SIGSTOP, because the bars aren't mapped at start */
parse_json_header(&status_child, buffer, rec, &consumed);
if (status_child.version > 0) {
/* If hide-on-modifier is set, we start of by sending the status_child
* a SIGSTOP, because the bars aren't mapped at start */
if (config.hide_on_modifier) {
stop_child();
stop_children();
}
draw_bars(read_json_input(buffer + consumed, rec - consumed));
} else {
@@ -446,9 +521,133 @@ void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
read_flat_input((char *)buffer, rec);
}
free(buffer);
ev_io_stop(main_loop, stdin_io);
ev_io_init(stdin_io, &stdin_io_cb, STDIN_FILENO, EV_READ);
ev_io_start(main_loop, stdin_io);
}
static bool isempty(char *s) {
while (*s != '\0') {
if (!isspace(*s)) {
return false;
}
s++;
}
return true;
}
static char *append_string(const char *previous, const char *str) {
if (previous != NULL) {
char *result;
sasprintf(&result, "%s%s", previous, str);
return result;
}
return sstrdup(str);
}
static char *ws_last_json;
static void ws_stdin_io_cb(int fd) {
int rec;
unsigned char *buffer = get_buffer(fd, &rec);
if (buffer == NULL) {
return;
}
gchar **strings = g_strsplit((const char *)buffer, "\n", 0);
for (int idx = 0; strings[idx] != NULL; idx++) {
if (ws_child.pending_line == NULL && isempty(strings[idx])) {
/* In the normal case where the buffer ends with '\n', the last
* string should be empty */
continue;
}
if (strings[idx + 1] == NULL) {
/* This is the last string but it is not empty, meaning that we have
* read data that is incomplete, save it for later. */
char *new = append_string(ws_child.pending_line, strings[idx]);
free(ws_child.pending_line);
ws_child.pending_line = new;
continue;
}
free(ws_last_json);
ws_last_json = append_string(ws_child.pending_line, strings[idx]);
FREE(ws_child.pending_line);
parse_workspaces_json((const unsigned char *)ws_last_json, strlen(ws_last_json));
}
g_strfreev(strings);
free(buffer);
draw_bars(false);
}
static void common_stdin_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
if (watcher == status_child.stdin_io) {
if (status_child.version == (uint32_t)-1) {
stdin_io_first_line_cb(watcher->fd);
} else {
stdin_io_cb(watcher->fd);
}
} else if (watcher == ws_child.stdin_io) {
ws_stdin_io_cb(watcher->fd);
} else {
ELOG("Got callback for unknown watcher fd=%d\n", watcher->fd);
}
}
/*
* When workspace_command is enabled this function is used to re-parse the
* latest received JSON from the client.
*/
void repeat_last_ws_json(void) {
if (ws_last_json) {
DLOG("Repeating last workspace JSON\n");
parse_workspaces_json((const unsigned char *)ws_last_json, strlen(ws_last_json));
}
}
/*
* Wrapper around set_workspace_button_error to mimic the call of
* set_statusline_error.
*/
__attribute__((format(printf, 1, 2))) static void set_workspace_button_error_f(const char *format, ...) {
char *message;
va_list args;
va_start(args, format);
if (vasprintf(&message, format, args) == -1) {
goto finish;
}
set_workspace_button_error(message);
finish:
free(message);
va_end(args);
}
/*
* Replaces the workspace buttons with an error message.
*/
void set_workspace_button_error(const char *message) {
free_workspaces();
char *name = NULL;
sasprintf(&name, "Error: %s", message);
i3_output *output;
SLIST_FOREACH (output, outputs, slist) {
i3_ws *fake_ws = scalloc(1, sizeof(i3_ws));
/* Don't set the canonical_name field to make this workspace unfocusable. */
fake_ws->name = i3string_from_utf8(name);
fake_ws->name_width = predict_text_width(fake_ws->name);
fake_ws->num = -1;
fake_ws->urgent = fake_ws->visible = true;
fake_ws->output = output;
TAILQ_INSERT_TAIL(output->workspaces, fake_ws, tailq);
}
free(name);
}
/*
@@ -457,28 +656,46 @@ void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
* anymore
*
*/
void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) {
int exit_status = WEXITSTATUS(watcher->rstatus);
static void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) {
const int exit_status = WEXITSTATUS(watcher->rstatus);
ELOG("Child (pid: %d) unexpectedly exited with status %d\n",
child.pid,
watcher->pid,
exit_status);
void (*error_function_pointer)(const char *, ...) = NULL;
const char *command_type = "";
i3bar_child *c = NULL;
if (watcher->pid == status_child.pid) {
command_type = "status_command";
error_function_pointer = set_statusline_error;
c = &status_child;
} else if (watcher->pid == ws_child.pid) {
command_type = "workspace_command";
error_function_pointer = set_workspace_button_error_f;
c = &ws_child;
} else {
ELOG("Unknown child pid, this should never happen\n");
return;
}
DLOG_CHILD(*c);
/* this error is most likely caused by a user giving a nonexecutable or
* nonexistent file, so we will handle those cases separately. */
if (exit_status == 126)
set_statusline_error("status_command is not executable (exit %d)", exit_status);
else if (exit_status == 127)
set_statusline_error("status_command not found or is missing a library dependency (exit %d)", exit_status);
else
set_statusline_error("status_command process exited unexpectedly (exit %d)", exit_status);
if (exit_status == 126) {
error_function_pointer("%s is not executable (exit %d)", command_type, exit_status);
} else if (exit_status == 127) {
error_function_pointer("%s not found or is missing a library dependency (exit %d)", command_type, exit_status);
} else {
error_function_pointer("%s process exited unexpectedly (exit %d)", command_type, exit_status);
}
cleanup();
cleanup(c);
draw_bars(false);
}
void child_write_output(void) {
if (child.click_events) {
static void child_write_output(void) {
if (status_child.click_events) {
const unsigned char *output;
size_t size;
ssize_t n;
@@ -486,13 +703,14 @@ void child_write_output(void) {
yajl_gen_get_buf(gen, &output, &size);
n = writeall(child_stdin, output, size);
if (n != -1)
if (n != -1) {
n = writeall(child_stdin, "\n", 1);
}
yajl_gen_clear(gen);
if (n == -1) {
child.click_events = false;
status_child.click_events = false;
kill_child();
set_statusline_error("child_write_output failed");
draw_bars(false);
@@ -500,9 +718,44 @@ void child_write_output(void) {
}
}
static pid_t sfork(void) {
const pid_t pid = fork();
if (pid == -1) {
ELOG("Couldn't fork(): %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
return pid;
}
static void spipe(int pipedes[2]) {
if (pipe(pipedes) == -1) {
err(EXIT_FAILURE, "pipe(pipe_in)");
}
}
static void exec_shell(char *command) {
execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (char *)NULL);
}
static void setup_child_cb(i3bar_child *child) {
/* We set O_NONBLOCK because blocking is evil in event-driven software */
fcntl(child->stdin_fd, F_SETFL, O_NONBLOCK);
child->stdin_io = smalloc(sizeof(ev_io));
ev_io_init(child->stdin_io, &common_stdin_cb, child->stdin_fd, EV_READ);
ev_io_start(main_loop, child->stdin_io);
/* We must cleanup, if the child unexpectedly terminates */
child->child_sig = smalloc(sizeof(ev_child));
ev_child_init(child->child_sig, &child_sig_cb, child->pid, 0);
ev_child_start(main_loop, child->child_sig);
DLOG_CHILD(*child);
}
/*
* Start a child process with the specified command and reroute stdin.
* We actually start a $SHELL to execute the command so we don't have to care
* We actually start a shell to execute the command so we don't have to care
* about arguments and such.
*
* If `command' is NULL, such as in the case when no `status_command' is given
@@ -510,8 +763,9 @@ void child_write_output(void) {
*
*/
void start_child(char *command) {
if (command == NULL)
if (command == NULL) {
return;
}
/* Allocate a yajl parser which will be used to parse stdin. */
static yajl_callbacks callbacks = {
@@ -525,79 +779,86 @@ void start_child(char *command) {
.yajl_end_array = stdin_end_array,
};
parser = yajl_alloc(&callbacks, NULL, &parser_context);
gen = yajl_gen_alloc(NULL);
int pipe_in[2]; /* pipe we read from */
int pipe_out[2]; /* pipe we write to */
spipe(pipe_in);
spipe(pipe_out);
if (pipe(pipe_in) == -1)
err(EXIT_FAILURE, "pipe(pipe_in)");
if (pipe(pipe_out) == -1)
err(EXIT_FAILURE, "pipe(pipe_out)");
status_child.pid = sfork();
if (status_child.pid == 0) {
/* Child-process. Reroute streams and start shell */
close(pipe_in[0]);
close(pipe_out[1]);
child.pid = fork();
switch (child.pid) {
case -1:
ELOG("Couldn't fork(): %s\n", strerror(errno));
exit(EXIT_FAILURE);
case 0:
/* Child-process. Reroute streams and start shell */
dup2(pipe_in[1], STDOUT_FILENO);
dup2(pipe_out[0], STDIN_FILENO);
close(pipe_in[0]);
close(pipe_out[1]);
dup2(pipe_in[1], STDOUT_FILENO);
dup2(pipe_out[0], STDIN_FILENO);
setpgid(child.pid, 0);
execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (char *)NULL);
return;
default:
/* Parent-process. Reroute streams */
close(pipe_in[1]);
close(pipe_out[0]);
dup2(pipe_in[0], STDIN_FILENO);
child_stdin = pipe_out[1];
break;
setpgid(status_child.pid, 0);
exec_shell(command);
return;
}
/* Parent-process. Reroute streams */
close(pipe_in[1]);
close(pipe_out[0]);
/* We set O_NONBLOCK because blocking is evil in event-driven software */
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
status_child.stdin_fd = pipe_in[0];
child_stdin = pipe_out[1];
status_child.version = -1;
stdin_io = smalloc(sizeof(ev_io));
ev_io_init(stdin_io, &stdin_io_first_line_cb, STDIN_FILENO, EV_READ);
ev_io_start(main_loop, stdin_io);
/* We must cleanup, if the child unexpectedly terminates */
child_sig = smalloc(sizeof(ev_child));
ev_child_init(child_sig, &child_sig_cb, child.pid, 0);
ev_child_start(main_loop, child_sig);
atexit(kill_child_at_exit);
setup_child_cb(&status_child);
}
void child_click_events_initialize(void) {
if (!child.click_events_init) {
/*
* Same as start_child but starts the configured client that manages workspace
* buttons.
*
*/
void start_ws_child(char *command) {
if (command == NULL) {
return;
}
ws_child.stop_signal = SIGSTOP;
ws_child.cont_signal = SIGCONT;
int pipe_in[2]; /* pipe we read from */
spipe(pipe_in);
ws_child.pid = sfork();
if (ws_child.pid == 0) {
/* Child-process. Reroute streams and start shell */
close(pipe_in[0]);
dup2(pipe_in[1], STDOUT_FILENO);
setpgid(ws_child.pid, 0);
exec_shell(command);
return;
}
/* Parent-process. Reroute streams */
close(pipe_in[1]);
ws_child.stdin_fd = pipe_in[0];
setup_child_cb(&ws_child);
}
static void child_click_events_initialize(void) {
DLOG_CHILD(status_child);
if (!status_child.click_events_init) {
yajl_gen_array_open(gen);
child_write_output();
child.click_events_init = true;
status_child.click_events_init = true;
}
}
void child_click_events_key(const char *key) {
yajl_gen_string(gen, (const unsigned char *)key, strlen(key));
}
/*
* Generates a click event, if enabled.
*
*/
void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int width, int height) {
if (!child.click_events) {
void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int out_x, int out_y, int width, int height, int mods) {
if (!status_child.click_events) {
return;
}
@@ -606,65 +867,150 @@ void send_block_clicked(int button, const char *name, const char *instance, int
yajl_gen_map_open(gen);
if (name) {
child_click_events_key("name");
yajl_gen_string(gen, (const unsigned char *)name, strlen(name));
ystr("name");
ystr(name);
}
if (instance) {
child_click_events_key("instance");
yajl_gen_string(gen, (const unsigned char *)instance, strlen(instance));
ystr("instance");
ystr(instance);
}
child_click_events_key("button");
ystr("button");
yajl_gen_integer(gen, button);
child_click_events_key("x");
ystr("modifiers");
yajl_gen_array_open(gen);
if (mods & XCB_MOD_MASK_SHIFT) {
ystr("Shift");
}
if (mods & XCB_MOD_MASK_CONTROL) {
ystr("Control");
}
if (mods & XCB_MOD_MASK_1) {
ystr("Mod1");
}
if (mods & XCB_MOD_MASK_2) {
ystr("Mod2");
}
if (mods & XCB_MOD_MASK_3) {
ystr("Mod3");
}
if (mods & XCB_MOD_MASK_4) {
ystr("Mod4");
}
if (mods & XCB_MOD_MASK_5) {
ystr("Mod5");
}
yajl_gen_array_close(gen);
ystr("x");
yajl_gen_integer(gen, x);
child_click_events_key("y");
ystr("y");
yajl_gen_integer(gen, y);
child_click_events_key("relative_x");
ystr("relative_x");
yajl_gen_integer(gen, x_rel);
child_click_events_key("relative_y");
ystr("relative_y");
yajl_gen_integer(gen, y_rel);
child_click_events_key("width");
ystr("output_x");
yajl_gen_integer(gen, out_x);
ystr("output_y");
yajl_gen_integer(gen, out_y);
ystr("width");
yajl_gen_integer(gen, width);
child_click_events_key("height");
ystr("height");
yajl_gen_integer(gen, height);
yajl_gen_map_close(gen);
child_write_output();
}
static bool is_alive(i3bar_child *c) {
return c->pid > 0;
}
/*
* Returns true if the status child process is alive.
*
*/
bool status_child_is_alive(void) {
return is_alive(&status_child);
}
/*
* Returns true if the workspace child process is alive.
*
*/
bool ws_child_is_alive(void) {
return is_alive(&ws_child);
}
/*
* kill()s the child process (if any). Called when exit()ing.
*
*/
void kill_child_at_exit(void) {
if (child.pid > 0) {
if (child.cont_signal > 0 && child.stopped)
killpg(child.pid, child.cont_signal);
killpg(child.pid, SIGTERM);
void kill_children_at_exit(void) {
DLOG_CHILDREN;
cont_children();
if (is_alive(&status_child)) {
killpg(status_child.pid, SIGTERM);
}
if (is_alive(&ws_child)) {
killpg(ws_child.pid, SIGTERM);
}
}
static void cont_child(i3bar_child *c) {
if (is_alive(c) && c->cont_signal > 0 && c->stopped) {
c->stopped = false;
killpg(c->pid, c->cont_signal);
}
}
static void kill_and_wait(i3bar_child *c) {
DLOG_CHILD(*c);
if (!is_alive(c)) {
return;
}
cont_child(c);
killpg(c->pid, SIGTERM);
int status;
waitpid(c->pid, &status, 0);
cleanup(c);
}
/*
* kill()s the child process (if existent) and closes and
* free()s the stdin- and SIGCHLD-watchers
* kill()s the child process (if any) and closes and free()s the stdin- and
* SIGCHLD-watchers
*
*/
void kill_child(void) {
if (child.pid > 0) {
if (child.cont_signal > 0 && child.stopped)
killpg(child.pid, child.cont_signal);
killpg(child.pid, SIGTERM);
int status;
waitpid(child.pid, &status, 0);
cleanup();
kill_and_wait(&status_child);
}
/*
* kill()s the workspace child process (if any) and closes and free()s the
* stdin- and SIGCHLD-watchers.
* Similar to kill_child.
*
*/
void kill_ws_child(void) {
kill_and_wait(&ws_child);
}
static void stop_child(i3bar_child *c) {
if (c->stop_signal > 0 && !c->stopped) {
c->stopped = true;
killpg(c->pid, c->stop_signal);
}
}
@@ -672,22 +1018,21 @@ void kill_child(void) {
* Sends a SIGSTOP to the child process (if existent)
*
*/
void stop_child(void) {
if (child.stop_signal > 0 && !child.stopped) {
child.stopped = true;
killpg(child.pid, child.stop_signal);
}
void stop_children(void) {
DLOG_CHILDREN;
stop_child(&status_child);
stop_child(&ws_child);
}
/*
* Sends a SIGCONT to the child process (if existent)
*
*/
void cont_child(void) {
if (child.cont_signal > 0 && child.stopped) {
child.stopped = false;
killpg(child.pid, child.cont_signal);
}
void cont_children(void) {
DLOG_CHILDREN;
cont_child(&status_child);
cont_child(&ws_child);
}
/*
@@ -695,5 +1040,5 @@ void cont_child(void) {
*
*/
bool child_want_click_events(void) {
return child.click_events;
return status_child.click_events;
}

View File

@@ -9,19 +9,17 @@
*/
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <i3/ipc.h>
#include <stdlib.h>
#include <string.h>
#include <yajl/yajl_parse.h>
#include <yajl/yajl_version.h>
#include <X11/Xlib.h>
config_t config;
static char *cur_key;
static bool parsing_bindings;
static bool parsing_tray_outputs;
static bool parsing_padding;
/*
* Parse a key.
@@ -41,12 +39,17 @@ static int config_map_key_cb(void *params_, const unsigned char *keyVal, size_t
parsing_tray_outputs = true;
}
if (strcmp(cur_key, "padding") == 0) {
parsing_padding = true;
}
return 1;
}
static int config_end_array_cb(void *params_) {
parsing_bindings = false;
parsing_tray_outputs = false;
parsing_padding = false;
return 1;
}
@@ -73,8 +76,9 @@ static int config_null_cb(void *params_) {
static int config_string_cb(void *params_, const unsigned char *val, size_t _len) {
int len = (int)_len;
/* The id and socket_path are ignored, we already know them. */
if (!strcmp(cur_key, "id") || !strcmp(cur_key, "socket_path"))
if (!strcmp(cur_key, "id") || !strcmp(cur_key, "socket_path")) {
return 1;
}
if (parsing_bindings) {
if (strcmp(cur_key, "command") == 0) {
@@ -119,6 +123,7 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len
return 1;
}
/* Kept for backwards compatibility. */
if (!strcmp(cur_key, "modifier")) {
DLOG("modifier = %.*s\n", len, val);
if (len == strlen("none") && !strncmp((const char *)val, "none", strlen("none"))) {
@@ -127,31 +132,31 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len
}
if (len == strlen("shift") && !strncmp((const char *)val, "shift", strlen("shift"))) {
config.modifier = ShiftMask;
config.modifier = XCB_MOD_MASK_SHIFT;
return 1;
}
if (len == strlen("ctrl") && !strncmp((const char *)val, "ctrl", strlen("ctrl"))) {
config.modifier = ControlMask;
config.modifier = XCB_MOD_MASK_CONTROL;
return 1;
}
if (len == strlen("Mod") + 1 && !strncmp((const char *)val, "Mod", strlen("Mod"))) {
switch (val[3]) {
case '1':
config.modifier = Mod1Mask;
config.modifier = XCB_MOD_MASK_1;
return 1;
case '2':
config.modifier = Mod2Mask;
config.modifier = XCB_MOD_MASK_2;
return 1;
case '3':
config.modifier = Mod3Mask;
config.modifier = XCB_MOD_MASK_3;
return 1;
case '5':
config.modifier = Mod5Mask;
config.modifier = XCB_MOD_MASK_5;
return 1;
}
}
config.modifier = Mod4Mask;
config.modifier = XCB_MOD_MASK_4;
return 1;
}
@@ -184,12 +189,17 @@ static int config_string_cb(void *params_, const unsigned char *val, size_t _len
}
if (!strcmp(cur_key, "status_command")) {
DLOG("command = %.*s\n", len, val);
FREE(config.command);
DLOG("status_command = %.*s\n", len, val);
sasprintf(&config.command, "%.*s", len, val);
return 1;
}
if (!strcmp(cur_key, "workspace_command")) {
DLOG("workspace_command = %.*s\n", len, val);
sasprintf(&config.workspace_command, "%.*s", len, val);
return 1;
}
if (!strcmp(cur_key, "font")) {
DLOG("font = %.*s\n", len, val);
FREE(config.fontname);
@@ -297,9 +307,17 @@ static int config_boolean_cb(void *params_, int val) {
return 1;
}
if (!strcmp(cur_key, "strip_workspace_name")) {
DLOG("strip_workspace_name = %d\n", val);
config.strip_ws_name = val;
return 1;
}
if (!strcmp(cur_key, "verbose")) {
DLOG("verbose = %d\n", val);
config.verbose = val;
if (!config.verbose) {
DLOG("verbose = %d\n", val);
config.verbose = val;
}
return 1;
}
@@ -324,38 +342,76 @@ static int config_integer_cb(void *params_, long long val) {
return 0;
}
if (parsing_padding) {
if (strcmp(cur_key, "x") == 0) {
DLOG("padding.x = %lld\n", val);
config.padding.x = (uint32_t)val;
return 1;
}
if (strcmp(cur_key, "y") == 0) {
DLOG("padding.y = %lld\n", val);
config.padding.y = (uint32_t)val;
return 1;
}
if (strcmp(cur_key, "width") == 0) {
DLOG("padding.width = %lld\n", val);
config.padding.width = (uint32_t)val;
return 1;
}
if (strcmp(cur_key, "height") == 0) {
DLOG("padding.height = %lld\n", val);
config.padding.height = (uint32_t)val;
return 1;
}
}
if (!strcmp(cur_key, "bar_height")) {
DLOG("bar_height = %lld\n", val);
config.bar_height = (uint32_t)val;
return 1;
}
if (!strcmp(cur_key, "tray_padding")) {
DLOG("tray_padding = %lld\n", val);
config.tray_padding = val;
return 1;
}
if (!strcmp(cur_key, "modifier")) {
DLOG("modifier = %lld\n", val);
config.modifier = (uint32_t)val;
return 1;
}
if (!strcmp(cur_key, "workspace_min_width")) {
DLOG("workspace_min_width = %lld\n", val);
config.ws_min_width = val;
return 1;
}
return 0;
}
/* A datastructure to pass all these callbacks to yajl */
static yajl_callbacks outputs_callbacks = {
.yajl_null = config_null_cb,
.yajl_boolean = config_boolean_cb,
.yajl_integer = config_integer_cb,
.yajl_boolean = config_boolean_cb,
.yajl_string = config_string_cb,
.yajl_end_array = config_end_array_cb,
.yajl_map_key = config_map_key_cb,
};
/*
* Start parsing the received bar configuration JSON string
* Parse the received bar configuration JSON string
*
*/
void parse_config_json(char *json) {
yajl_handle handle;
yajl_status state;
handle = yajl_alloc(&outputs_callbacks, NULL, NULL);
void parse_config_json(const unsigned char *json, size_t size) {
TAILQ_INIT(&(config.bindings));
TAILQ_INIT(&(config.tray_outputs));
state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
yajl_handle handle = yajl_alloc(&outputs_callbacks, NULL, NULL);
yajl_status state = yajl_parse(handle, json, size);
/* FIXME: Proper error handling for JSON parsing */
switch (state) {
@@ -368,6 +424,30 @@ void parse_config_json(char *json) {
break;
}
if (config.disable_ws && config.workspace_command) {
ELOG("You have specified 'workspace_buttons no'. Your 'workspace_command %s' will be ignored.\n", config.workspace_command);
FREE(config.workspace_command);
}
yajl_free(handle);
}
static int i3bar_config_string_cb(void *params_, const unsigned char *val, size_t _len) {
sasprintf(&config.bar_id, "%.*s", (int)_len, val);
return 0; /* Stop parsing */
}
/*
* Parse the received bar configuration list. The only usecase right now is to
* automatically get the first bar id.
*
*/
void parse_get_first_i3bar_config(const unsigned char *json, size_t size) {
yajl_callbacks configs_callbacks = {
.yajl_string = i3bar_config_string_cb,
};
yajl_handle handle = yajl_alloc(&configs_callbacks, NULL, NULL);
yajl_parse(handle, json, size);
yajl_free(handle);
}

View File

@@ -9,16 +9,13 @@
*/
#include "common.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <i3/ipc.h>
#include <ev.h>
#include <i3/ipc.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef I3_ASAN_ENABLED
#include <sanitizer/lsan_interface.h>
#endif
@@ -27,14 +24,24 @@ ev_io *i3_connection;
const char *sock_path;
typedef void (*handler_t)(char *);
typedef void (*handler_t)(const unsigned char *, size_t);
/*
* Returns true when i3bar is configured to read workspace information from i3
* via JSON over the i3 IPC interface, as opposed to reading workspace
* information from the workspace_command via JSON over stdout.
*
*/
static bool i3_provides_workspaces(void) {
return !config.disable_ws && config.workspace_command == NULL;
}
/*
* Called, when we get a reply to a command from i3.
* Since i3 does not give us much feedback on commands, we do not much
*
*/
void got_command_reply(char *reply) {
static void got_command_reply(const unsigned char *reply, size_t size) {
/* TODO: Error handling for command replies */
}
@@ -42,9 +49,9 @@ void got_command_reply(char *reply) {
* Called, when we get a reply with workspaces data
*
*/
void got_workspace_reply(char *reply) {
static void got_workspace_reply(const unsigned char *reply, size_t size) {
DLOG("Got workspace data!\n");
parse_workspaces_json(reply);
parse_workspaces_json(reply, size);
draw_bars(false);
}
@@ -53,7 +60,7 @@ void got_workspace_reply(char *reply) {
* Since i3 does not give us much feedback on commands, we do not much
*
*/
void got_subscribe_reply(char *reply) {
static void got_subscribe_reply(const unsigned char *reply, size_t size) {
DLOG("Got subscribe reply: %s\n", reply);
/* TODO: Error handling for subscribe commands */
}
@@ -62,22 +69,33 @@ void got_subscribe_reply(char *reply) {
* Called, when we get a reply with outputs data
*
*/
void got_output_reply(char *reply) {
static void got_output_reply(const unsigned char *reply, size_t size) {
DLOG("Clearing old output configuration...\n");
free_outputs();
DLOG("Parsing outputs JSON...\n");
parse_outputs_json(reply);
parse_outputs_json(reply, size);
DLOG("Reconfiguring windows...\n");
reconfig_windows(false);
i3_output *o_walk;
SLIST_FOREACH(o_walk, outputs, slist) {
SLIST_FOREACH (o_walk, outputs, slist) {
kick_tray_clients(o_walk);
}
if (!config.disable_ws) {
if (i3_provides_workspaces()) {
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
} else if (config.workspace_command) {
/* Communication with the workspace child is one-way. Since we called
* free_outputs() and free_workspaces() we have lost our workspace
* information which will result in no workspace buttons. A
* well-behaving client should be subscribed to output events as well
* and re-send the output information to i3bar. Even in that case
* though there is a race condition where the child can send the new
* workspace information after the output change before i3bar receives
* the output event from i3. For this reason, we re-parse the latest
* received JSON. */
repeat_last_ws_json();
}
draw_bars(false);
@@ -87,7 +105,21 @@ void got_output_reply(char *reply) {
* Called when we get the configuration for our bar instance
*
*/
void got_bar_config(char *reply) {
static void got_bar_config(const unsigned char *reply, size_t size) {
if (!config.bar_id) {
DLOG("Received bar list \"%s\"\n", reply);
parse_get_first_i3bar_config(reply, size);
if (!config.bar_id) {
ELOG("No bar configuration found, please configure a bar block in your i3 config file.\n");
exit(EXIT_FAILURE);
}
LOG("Using first bar config: %s. Use --bar_id to manually select a different bar configuration.\n", config.bar_id);
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id);
return;
}
DLOG("Received bar config \"%s\"\n", reply);
/* We initiate the main function by requesting infos about the outputs and
* workspaces. Everything else (creating the bars, showing the right workspace-
@@ -95,13 +127,14 @@ void got_bar_config(char *reply) {
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
free_colors(&(config.colors));
parse_config_json(reply);
parse_config_json(reply, size);
/* Now we can actually use 'config', so let's subscribe to the appropriate
* events and request the workspaces if necessary. */
subscribe_events();
if (!config.disable_ws)
if (i3_provides_workspaces()) {
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
}
/* Initialize the rest of XCB */
init_xcb_late(config.fontname);
@@ -110,24 +143,30 @@ void got_bar_config(char *reply) {
init_colors(&(config.colors));
start_child(config.command);
start_ws_child(config.workspace_command);
}
/* Data structure to easily call the reply handlers later */
handler_t reply_handlers[] = {
&got_command_reply,
&got_workspace_reply,
&got_subscribe_reply,
&got_output_reply,
NULL,
NULL,
&got_bar_config,
&got_command_reply, /* I3_IPC_REPLY_TYPE_COMMAND */
&got_workspace_reply, /* I3_IPC_REPLY_TYPE_WORKSPACES */
&got_subscribe_reply, /* I3_IPC_REPLY_TYPE_SUBSCRIBE */
&got_output_reply, /* I3_IPC_REPLY_TYPE_OUTPUTS */
NULL, /* I3_IPC_REPLY_TYPE_TREE */
NULL, /* I3_IPC_REPLY_TYPE_MARKS */
&got_bar_config, /* I3_IPC_REPLY_TYPE_BAR_CONFIG */
NULL, /* I3_IPC_REPLY_TYPE_VERSION */
NULL, /* I3_IPC_REPLY_TYPE_BINDING_MODES */
NULL, /* I3_IPC_REPLY_TYPE_CONFIG */
NULL, /* I3_IPC_REPLY_TYPE_TICK */
NULL, /* I3_IPC_REPLY_TYPE_SYNC */
};
/*
* Called, when a workspace event arrives (i.e. the user changed the workspace)
*
*/
void got_workspace_event(char *event) {
static void got_workspace_event(const unsigned char *event, size_t size) {
DLOG("Got workspace event!\n");
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
}
@@ -136,36 +175,46 @@ void got_workspace_event(char *event) {
* Called, when an output event arrives (i.e. the screen configuration changed)
*
*/
void got_output_event(char *event) {
static void got_output_event(const unsigned char *event, size_t size) {
DLOG("Got output event!\n");
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
if (!config.disable_ws) {
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
}
}
/*
* Called, when a mode event arrives (i3 changed binding mode).
*
*/
void got_mode_event(char *event) {
static void got_mode_event(const unsigned char *event, size_t size) {
DLOG("Got mode event!\n");
parse_mode_json(event);
parse_mode_json(event, size);
draw_bars(false);
}
static bool strings_differ(char *a, char *b) {
const bool a_null = (a == NULL);
const bool b_null = (b == NULL);
if (a_null != b_null) {
return true;
}
if (a_null && b_null) {
return false;
}
return strcmp(a, b) != 0;
}
/*
* Called, when a barconfig_update event arrives (i.e. i3 changed the bar hidden_state or mode)
*
*/
void got_bar_config_update(char *event) {
static void got_bar_config_update(const unsigned char *event, size_t size) {
/* check whether this affect this bar instance by checking the bar_id */
char *expected_id;
sasprintf(&expected_id, "\"id\":\"%s\"", config.bar_id);
char *found_id = strstr(event, expected_id);
char *found_id = strstr((const char *)event, expected_id);
FREE(expected_id);
if (found_id == NULL)
if (found_id == NULL) {
return;
}
/* reconfigure the bar based on the current outputs */
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
@@ -174,9 +223,14 @@ void got_bar_config_update(char *event) {
/* update the configuration with the received settings */
DLOG("Received bar config update \"%s\"\n", event);
char *old_command = config.command ? sstrdup(config.command) : NULL;
char *old_command = config.command;
char *old_workspace_command = config.workspace_command;
config.command = NULL;
config.workspace_command = NULL;
bar_display_mode_t old_mode = config.hide_on_modifier;
parse_config_json(event);
parse_config_json(event, size);
if (old_mode != config.hide_on_modifier) {
reconfig_windows(true);
}
@@ -186,12 +240,21 @@ void got_bar_config_update(char *event) {
init_colors(&(config.colors));
/* restart status command process */
if (old_command && strcmp(old_command, config.command) != 0) {
if (!status_child_is_alive() || strings_differ(old_command, config.command)) {
kill_child();
clear_statusline(&statusline_head, true);
start_child(config.command);
}
free(old_command);
/* restart workspace command process */
if (!ws_child_is_alive() || strings_differ(old_workspace_command, config.workspace_command)) {
free_workspaces();
kill_ws_child();
start_ws_child(config.workspace_command);
}
free(old_workspace_command);
draw_bars(false);
}
@@ -208,7 +271,7 @@ handler_t event_handlers[] = {
* Called, when we get a message from i3
*
*/
void got_data(struct ev_loop *loop, ev_io *watcher, int events) {
static void got_data(struct ev_loop *loop, ev_io *watcher, int events) {
DLOG("Got data!\n");
int fd = watcher->fd;
@@ -255,7 +318,7 @@ void got_data(struct ev_loop *loop, ev_io *watcher, int events) {
/* Now that we know, what to expect, we can start read()ing the rest
* of the message */
char *buffer = smalloc(size + 1);
unsigned char *buffer = smalloc(size + 1);
rec = 0;
while (rec < size) {
@@ -273,12 +336,13 @@ void got_data(struct ev_loop *loop, ev_io *watcher, int events) {
buffer[size] = '\0';
/* And call the callback (indexed by the type) */
if (type & (1 << 31)) {
type ^= 1 << 31;
event_handlers[type](buffer);
if (type & (1UL << 31)) {
type ^= 1UL << 31;
event_handlers[type](buffer, size);
} else {
if (reply_handlers[type])
reply_handlers[type](buffer);
if (reply_handlers[type]) {
reply_handlers[type](buffer, size);
}
}
FREE(header);
@@ -304,15 +368,16 @@ int i3_send_msg(uint32_t type, const char *payload) {
char *buffer = smalloc(to_write);
char *walk = buffer;
strncpy(buffer, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC));
memcpy(buffer, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC));
walk += strlen(I3_IPC_MAGIC);
memcpy(walk, &len, sizeof(uint32_t));
walk += sizeof(uint32_t);
memcpy(walk, &type, sizeof(uint32_t));
walk += sizeof(uint32_t);
if (payload != NULL)
strncpy(walk, payload, len);
if (payload != NULL) {
memcpy(walk, payload, len);
}
swrite(i3_connection->fd, buffer, to_write);
@@ -326,13 +391,12 @@ int i3_send_msg(uint32_t type, const char *payload) {
* socket_path must be a valid path to the ipc_socket of i3
*
*/
int init_connection(const char *socket_path) {
void init_connection(const char *socket_path) {
sock_path = socket_path;
int sockfd = ipc_connect(socket_path);
i3_connection = smalloc(sizeof(ev_io));
ev_io_init(i3_connection, &got_data, sockfd, EV_READ);
ev_io_start(main_loop, i3_connection);
return 1;
}
/*
@@ -348,9 +412,9 @@ void destroy_connection(void) {
*
*/
void subscribe_events(void) {
if (config.disable_ws) {
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"output\", \"mode\", \"barconfig_update\" ]");
} else {
if (i3_provides_workspaces()) {
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"workspace\", \"output\", \"mode\", \"barconfig_update\" ]");
} else {
i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"output\", \"mode\", \"barconfig_update\" ]");
}
}

View File

@@ -7,15 +7,15 @@
*/
#include "common.h"
#include <stdio.h>
#include <i3/ipc.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <ev.h>
#include <getopt.h>
#include <glob.h>
#include <i3/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ev_loop *main_loop;
/*
* Having verboselog(), errorlog() and debuglog() is necessary when using libi3.
@@ -44,7 +44,7 @@ void debuglog(char *fmt, ...) {
* Glob path, i.e. expand ~
*
*/
char *expand_path(char *path) {
static char *expand_path(char *path) {
static glob_t globbuf;
if (glob(path, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0) {
ELOG("glob() failed\n");
@@ -55,13 +55,15 @@ char *expand_path(char *path) {
return result;
}
void print_usage(char *elf_name) {
printf("Usage: %s -b bar_id [-s sock_path] [-h] [-v]\n", elf_name);
static void print_usage(char *elf_name) {
printf("Usage: %s [-b bar_id] [-s sock_path] [-t] [-h] [-v] [-V]\n", elf_name);
printf("\n");
printf("-b, --bar_id <bar_id>\tBar ID for which to get the configuration\n");
printf("-s, --socket <sock_path>\tConnect to i3 via <sock_path>\n");
printf("-h, --help Display this help message and exit\n");
printf("-v, --version Display version number and exit\n");
printf("-b, --bar_id <bar_id>\tBar ID for which to get the configuration, defaults to the first bar from the i3 config\n");
printf("-s, --socket <sock_path>\tConnect to i3 via <sock_path>\n");
printf("-t, --transparency Enable transparency (RGBA colors)\n");
printf("-h, --help Display this help message and exit\n");
printf("-v, --version Display version number and exit\n");
printf("-V, --verbose Enable verbose mode\n");
printf("\n");
printf(" PLEASE NOTE that i3bar will be automatically started by i3\n"
" as soon as there is a 'bar' configuration block in your\n"
@@ -75,7 +77,7 @@ void print_usage(char *elf_name) {
* in main() with that
*
*/
void sig_cb(struct ev_loop *loop, ev_signal *watcher, int revents) {
static void sig_cb(struct ev_loop *loop, ev_signal *watcher, int revents) {
switch (watcher->signum) {
case SIGTERM:
DLOG("Got a SIGTERM, stopping\n");
@@ -90,13 +92,7 @@ void sig_cb(struct ev_loop *loop, ev_signal *watcher, int revents) {
}
int main(int argc, char **argv) {
int opt;
int option_index = 0;
char *socket_path = getenv("I3SOCK");
if (socket_path != NULL) {
socket_path = sstrdup(socket_path);
}
char *i3_default_sock_path = "/tmp/i3-ipc.sock";
char *socket_path = NULL;
/* Initialize the standard config to use 0 as default */
memset(&config, '\0', sizeof(config_t));
@@ -104,11 +100,15 @@ int main(int argc, char **argv) {
static struct option long_opt[] = {
{"socket", required_argument, 0, 's'},
{"bar_id", required_argument, 0, 'b'},
{"transparency", no_argument, 0, 't'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{"verbose", no_argument, 0, 'V'},
{NULL, 0, 0, 0}};
while ((opt = getopt_long(argc, argv, "b:s:hv", long_opt, &option_index)) != -1) {
int opt;
int option_index = 0;
while ((opt = getopt_long(argc, argv, "b:s:thvV", long_opt, &option_index)) != -1) {
switch (opt) {
case 's':
socket_path = expand_path(optarg);
@@ -120,24 +120,32 @@ int main(int argc, char **argv) {
case 'b':
config.bar_id = sstrdup(optarg);
break;
case 't':
config.transparency = true;
break;
case 'V':
config.verbose = true;
break;
default:
print_usage(argv[0]);
exit(EXIT_SUCCESS);
exit(EXIT_FAILURE);
break;
}
}
if (!config.bar_id) {
/* TODO: maybe we want -f which will automatically ask i3 for the first
* configured bar (and error out if there are too many)? */
ELOG("No bar_id passed. Please let i3 start i3bar or specify --bar_id\n");
exit(EXIT_FAILURE);
}
main_loop = ev_default_loop(0);
LOG("i3bar version " I3_VERSION "\n");
main_loop = ev_default_loop(0); /* needed in init_xcb_early */
char *atom_sock_path = init_xcb_early();
/* Select a socket_path if the user hasn't specified one */
if (socket_path == NULL) {
socket_path = getenv("I3SOCK");
if (socket_path != NULL) {
socket_path = sstrdup(socket_path);
}
}
if (socket_path == NULL) {
socket_path = atom_sock_path;
} else {
@@ -145,17 +153,21 @@ int main(int argc, char **argv) {
}
if (socket_path == NULL) {
char *i3_default_sock_path = "/tmp/i3-ipc.sock";
ELOG("No socket path specified, default to %s\n", i3_default_sock_path);
socket_path = expand_path(i3_default_sock_path);
socket_path = sstrdup(i3_default_sock_path);
}
init_dpi();
init_outputs();
if (init_connection(socket_path)) {
/* Request the bar configuration. When it arrives, we fill the config array. */
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id);
}
init_connection(socket_path);
/* Request the bar configuration. When it arrives, we fill the config
* array. In case that config.bar_id is empty, we will receive a list of
* available configs and then request the configuration for the first bar.
* See got_bar_config for more. */
i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id);
free(socket_path);
/* We listen to SIGTERM/QUIT/INT and try to exit cleanly, by stopping the main loop.
@@ -173,12 +185,12 @@ int main(int argc, char **argv) {
ev_signal_start(main_loop, sig_int);
ev_signal_start(main_loop, sig_hup);
atexit(kill_children_at_exit);
/* From here on everything should run smooth for itself, just start listening for
* events. We stop simply stop the event loop, when we are finished */
ev_loop(main_loop, 0);
kill_child();
clean_xcb();
ev_default_destroy();

View File

@@ -9,16 +9,13 @@
*/
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <yajl/yajl_parse.h>
#include <yajl/yajl_version.h>
/* A datatype to pass through the callbacks to save the state */
struct mode_json_params {
char *json;
char *cur_key;
char *name;
bool pango_markup;
@@ -81,7 +78,7 @@ static int mode_end_map_cb(void *params_) {
params->mode->name = i3string_from_utf8(params->name);
i3string_set_markup(params->mode->name, params->pango_markup);
/* Save its rendered width */
params->mode->width = predict_text_width(params->mode->name);
params->mode->name_width = predict_text_width(params->mode->name);
DLOG("Got mode change: %s\n", i3string_as_utf8(params->mode->name));
FREE(params->cur_key);
@@ -98,26 +95,17 @@ static yajl_callbacks mode_callbacks = {
};
/*
* Start parsing the received JSON string
* Parse the received JSON string
*
*/
void parse_mode_json(char *json) {
/* FIXME: Fasciliate stream processing, i.e. allow starting to interpret
* JSON in chunks */
void parse_mode_json(const unsigned char *json, size_t size) {
struct mode_json_params params;
mode binding;
params.cur_key = NULL;
params.json = json;
params.mode = &binding;
yajl_handle handle;
yajl_status state;
handle = yajl_alloc(&mode_callbacks, NULL, (void *)&params);
state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
yajl_handle handle = yajl_alloc(&mode_callbacks, NULL, (void *)&params);
yajl_status state = yajl_parse(handle, json, size);
/* FIXME: Proper error handling for JSON parsing */
switch (state) {
@@ -131,8 +119,9 @@ void parse_mode_json(char *json) {
}
/* We don't want to indicate default binding mode */
if (strcmp("default", i3string_as_utf8(params.mode->name)) == 0)
if (strcmp("default", i3string_as_utf8(params.mode->name)) == 0) {
I3STRING_FREE(params.mode->name);
}
/* Set the new binding mode */
set_current_mode(&binding);

View File

@@ -9,20 +9,17 @@
*/
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <i3/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <yajl/yajl_parse.h>
#include <yajl/yajl_version.h>
/* A datatype to pass through the callbacks to save the state */
struct outputs_json_params {
struct outputs_head *outputs;
i3_output *outputs_walk;
char *cur_key;
char *json;
bool in_rect;
};
@@ -115,8 +112,9 @@ static int outputs_string_cb(void *params_, const unsigned char *val, size_t len
errno = 0;
long parsed_num = strtol(copy, &end, 10);
if (errno == 0 &&
(end && *end == '\0'))
(end && *end == '\0')) {
params->outputs_walk->ws = parsed_num;
}
FREE(copy);
FREE(params->cur_key);
@@ -149,7 +147,6 @@ static int outputs_start_map_cb(void *params_) {
new_output->visible = false;
new_output->ws = 0,
new_output->statusline_width = 0;
new_output->statusline_short_text = false;
memset(&new_output->rect, 0, sizeof(rect));
memset(&new_output->bar, 0, sizeof(surface_t));
memset(&new_output->buffer, 0, sizeof(surface_t));
@@ -193,11 +190,12 @@ static int outputs_end_map_cb(void *params_) {
/* See if we actually handle that output */
if (config.num_outputs > 0) {
const bool is_primary = params->outputs_walk->primary;
bool handle_output = false;
for (int c = 0; c < config.num_outputs; c++) {
if (strcasecmp(params->outputs_walk->name, config.outputs[c]) == 0 ||
(strcasecmp(config.outputs[c], "primary") == 0 &&
params->outputs_walk->primary)) {
if ((strcasecmp(params->outputs_walk->name, config.outputs[c]) == 0) ||
(strcasecmp(config.outputs[c], "primary") == 0 && is_primary) ||
(strcasecmp(config.outputs[c], "nonprimary") == 0 && !is_primary)) {
handle_output = true;
break;
}
@@ -252,6 +250,7 @@ static yajl_callbacks outputs_callbacks = {
.yajl_end_map = outputs_end_map_cb,
};
struct outputs_head *outputs;
/*
* Initiate the outputs list
*
@@ -262,21 +261,17 @@ void init_outputs(void) {
}
/*
* Start parsing the received JSON string
* Parse the received JSON string
*
*/
void parse_outputs_json(char *json) {
void parse_outputs_json(const unsigned char *json, size_t size) {
struct outputs_json_params params;
params.outputs_walk = NULL;
params.cur_key = NULL;
params.json = json;
params.in_rect = false;
yajl_handle handle;
yajl_status state;
handle = yajl_alloc(&outputs_callbacks, NULL, (void *)&params);
state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
yajl_handle handle = yajl_alloc(&outputs_callbacks, NULL, (void *)&params);
yajl_status state = yajl_parse(handle, json, size);
/* FIXME: Proper errorhandling for JSON-parsing */
switch (state) {
@@ -290,6 +285,7 @@ void parse_outputs_json(char *json) {
}
yajl_free(handle);
free(params.cur_key);
}
/*
@@ -303,7 +299,7 @@ void free_outputs(void) {
if (outputs == NULL) {
return;
}
SLIST_FOREACH(outputs_walk, outputs, slist) {
SLIST_FOREACH (outputs_walk, outputs, slist) {
destroy_window(outputs_walk);
if (outputs_walk->trayclients != NULL && !TAILQ_EMPTY(outputs_walk->trayclients)) {
FREE_TAILQ(outputs_walk->trayclients, trayclient);
@@ -318,12 +314,14 @@ void free_outputs(void) {
*
*/
i3_output *get_output_by_name(char *name) {
i3_output *walk;
if (name == NULL) {
return NULL;
}
SLIST_FOREACH(walk, outputs, slist) {
if (!strcmp(walk->name, name)) {
const bool is_primary = !strcasecmp(name, "primary");
i3_output *walk;
SLIST_FOREACH (walk, outputs, slist) {
if ((is_primary && walk->primary) || !strcmp(walk->name, name)) {
break;
}
}
@@ -337,7 +335,7 @@ i3_output *get_output_by_name(char *name) {
*/
bool output_has_focus(i3_output *output) {
i3_ws *ws_walk;
TAILQ_FOREACH(ws_walk, output->workspaces, tailq) {
TAILQ_FOREACH (ws_walk, output->workspaces, tailq) {
if (ws_walk->focused) {
return true;
}

View File

@@ -10,22 +10,10 @@
*/
#include "common.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include <ev.h>
#include <stdbool.h>
#include <stdint.h>
#include <yajl/yajl_common.h>
#include <yajl/yajl_parse.h>
#include <yajl/yajl_version.h>
static enum {
KEY_VERSION,
@@ -118,11 +106,13 @@ void parse_json_header(i3bar_child *child, const unsigned char *buffer, int leng
yajl_status state = yajl_parse(handle, buffer, length);
if (state != yajl_status_ok) {
child_init(child);
if (consumed != NULL)
if (consumed != NULL) {
*consumed = 0;
}
} else {
if (consumed != NULL)
if (consumed != NULL) {
*consumed = yajl_get_bytes_consumed(handle);
}
}
yajl_free(handle);

View File

@@ -9,19 +9,18 @@
*/
#include "common.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <yajl/yajl_parse.h>
#include <yajl/yajl_version.h>
/* A datatype to pass through the callbacks to save the state */
struct workspaces_json_params {
struct ws_head *workspaces;
i3_ws *workspaces_walk;
char *cur_key;
char *json;
bool need_output;
bool parsing_rect;
};
/*
@@ -61,32 +60,35 @@ static int workspaces_boolean_cb(void *params_, int val) {
static int workspaces_integer_cb(void *params_, long long val) {
struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
if (!strcmp(params->cur_key, "id")) {
params->workspaces_walk->id = val;
FREE(params->cur_key);
return 1;
}
if (!strcmp(params->cur_key, "num")) {
params->workspaces_walk->num = (int)val;
FREE(params->cur_key);
return 1;
}
/* rect is unused, so we don't bother to save it */
if (!strcmp(params->cur_key, "x")) {
params->workspaces_walk->rect.x = (int)val;
FREE(params->cur_key);
return 1;
}
if (!strcmp(params->cur_key, "y")) {
params->workspaces_walk->rect.y = (int)val;
FREE(params->cur_key);
return 1;
}
if (!strcmp(params->cur_key, "width")) {
params->workspaces_walk->rect.w = (int)val;
FREE(params->cur_key);
return 1;
}
if (!strcmp(params->cur_key, "height")) {
params->workspaces_walk->rect.h = (int)val;
FREE(params->cur_key);
return 1;
}
@@ -106,9 +108,9 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, size_t
const char *ws_name = (const char *)val;
params->workspaces_walk->canonical_name = sstrndup(ws_name, len);
if (config.strip_ws_numbers && params->workspaces_walk->num >= 0) {
/* Special case: strip off the workspace number */
static char ws_num[10];
if ((config.strip_ws_numbers || config.strip_ws_name) && params->workspaces_walk->num >= 0) {
/* Special case: strip off the workspace number/name */
static char ws_num[32];
snprintf(ws_num, sizeof(ws_num), "%d", params->workspaces_walk->num);
@@ -116,14 +118,18 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, size_t
size_t offset = strspn(ws_name, ws_num);
/* Also strip off the conventional ws name delimiter */
if (offset && ws_name[offset] == ':')
if (offset && ws_name[offset] == ':') {
offset += 1;
}
/* Offset may be equal to length, in which case display the number */
params->workspaces_walk->name = (offset < len
? i3string_from_markup_with_length(ws_name + offset, len - offset)
: i3string_from_markup(ws_num));
if (config.strip_ws_numbers) {
/* Offset may be equal to length, in which case display the number */
params->workspaces_walk->name = (offset < len
? i3string_from_markup_with_length(ws_name + offset, len - offset)
: i3string_from_markup(ws_num));
} else {
params->workspaces_walk->name = i3string_from_markup(ws_num);
}
} else {
/* Default case: just save the name */
params->workspaces_walk->name = i3string_from_markup_with_length(ws_name, len);
@@ -149,15 +155,16 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, size_t
sasprintf(&output_name, "%.*s", len, val);
i3_output *target = get_output_by_name(output_name);
i3_ws *ws = params->workspaces_walk;
if (target != NULL) {
params->workspaces_walk->output = target;
TAILQ_INSERT_TAIL(params->workspaces_walk->output->workspaces,
params->workspaces_walk,
tailq);
ws->output = target;
TAILQ_INSERT_TAIL(ws->output->workspaces, ws, tailq);
}
params->need_output = false;
FREE(output_name);
FREE(params->cur_key);
return 1;
}
@@ -165,28 +172,42 @@ static int workspaces_string_cb(void *params_, const unsigned char *val, size_t
}
/*
* We hit the start of a JSON map (rect or a new output)
* We hit the start of a JSON map (rect or a new workspace)
*
*/
static int workspaces_start_map_cb(void *params_) {
struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
i3_ws *new_workspace = NULL;
if (params->cur_key == NULL) {
new_workspace = smalloc(sizeof(i3_ws));
i3_ws *new_workspace = scalloc(1, sizeof(i3_ws));
new_workspace->num = -1;
new_workspace->name = NULL;
new_workspace->visible = 0;
new_workspace->focused = 0;
new_workspace->urgent = 0;
memset(&new_workspace->rect, 0, sizeof(rect));
new_workspace->output = NULL;
params->workspaces_walk = new_workspace;
params->need_output = true;
params->parsing_rect = false;
} else {
params->parsing_rect = true;
}
return 1;
}
static int workspaces_end_map_cb(void *params_) {
struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
i3_ws *ws = params->workspaces_walk;
const bool parsing_rect = params->parsing_rect;
params->parsing_rect = false;
if (parsing_rect || !ws || !ws->name || !params->need_output) {
return 1;
}
ws->output = get_output_by_name("primary");
if (ws->output == NULL) {
ws->output = SLIST_FIRST(outputs);
}
TAILQ_INSERT_TAIL(ws->output->workspaces, ws, tailq);
return 1;
}
@@ -209,43 +230,42 @@ static yajl_callbacks workspaces_callbacks = {
.yajl_integer = workspaces_integer_cb,
.yajl_string = workspaces_string_cb,
.yajl_start_map = workspaces_start_map_cb,
.yajl_end_map = workspaces_end_map_cb,
.yajl_map_key = workspaces_map_key_cb,
};
/*
* Start parsing the received JSON string
* Parse the received JSON string
*
*/
void parse_workspaces_json(char *json) {
/* FIXME: Fasciliate stream processing, i.e. allow starting to interpret
* JSON in chunks */
struct workspaces_json_params params;
void parse_workspaces_json(const unsigned char *json, size_t size) {
free_workspaces();
params.workspaces_walk = NULL;
params.cur_key = NULL;
params.json = json;
yajl_handle handle;
yajl_status state;
handle = yajl_alloc(&workspaces_callbacks, NULL, (void *)&params);
state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
struct workspaces_json_params params = {0};
yajl_handle handle = yajl_alloc(&workspaces_callbacks, NULL, (void *)&params);
yajl_status state = yajl_parse(handle, json, size);
/* FIXME: Proper error handling for JSON parsing */
switch (state) {
case yajl_status_ok:
break;
case yajl_status_client_canceled:
case yajl_status_error:
ELOG("Could not parse workspaces reply!\n");
exit(EXIT_FAILURE);
case yajl_status_error: {
unsigned char *err = yajl_get_error(handle, 1, json, size);
ELOG("Could not parse workspaces reply, error:\n%s\njson:---%s---\n", err, json);
yajl_free_error(handle, err);
if (config.workspace_command) {
kill_ws_child();
set_workspace_button_error("Could not parse workspace_command's JSON");
} else {
exit(EXIT_FAILURE);
}
break;
}
}
yajl_free(handle);
FREE(params.cur_key);
}
@@ -254,15 +274,15 @@ void parse_workspaces_json(char *json) {
*
*/
void free_workspaces(void) {
i3_output *outputs_walk;
if (outputs == NULL) {
return;
}
i3_ws *ws_walk;
SLIST_FOREACH(outputs_walk, outputs, slist) {
i3_output *outputs_walk;
SLIST_FOREACH (outputs_walk, outputs, slist) {
if (outputs_walk->workspaces != NULL && !TAILQ_EMPTY(outputs_walk->workspaces)) {
TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
i3_ws *ws_walk;
TAILQ_FOREACH (ws_walk, outputs_walk->workspaces, tailq) {
I3STRING_FREE(ws_walk->name);
FREE(ws_walk->canonical_name);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* This header file includes all relevant files of i3 and the most often used
@@ -15,31 +15,24 @@
#include <config.h>
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <glob.h>
#include <errno.h>
#include <err.h>
#include <stdint.h>
#include <inttypes.h>
#include <math.h>
#include <limits.h>
#include <xcb/xcb.h>
#include <xcb/xcb_aux.h>
#include <xcb/xcb_keysyms.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_keysyms.h>
#include <yajl/yajl_gen.h>
#include <yajl/yajl_version.h>
#include "libi3.h"
#include "data.h"
#include "util.h"
#include "ipc.h"
@@ -53,6 +46,8 @@
#include "click.h"
#include "key_press.h"
#include "floating.h"
#include "gaps.h"
#include "drag.h"
#include "configuration.h"
#include "handlers.h"
#include "randr.h"
@@ -62,16 +57,15 @@
#include "render.h"
#include "window.h"
#include "match.h"
#include "cmdparse.h"
#include "xcursor.h"
#include "resize.h"
#include "tiling_drag.h"
#include "sighandler.h"
#include "move.h"
#include "output.h"
#include "ewmh.h"
#include "assignments.h"
#include "regex.h"
#include "libi3.h"
#include "startup.h"
#include "scratchpad.h"
#include "commands.h"
@@ -82,4 +76,5 @@
#include "fake_outputs.h"
#include "display_version.h"
#include "restore_layout.h"
#include "sync.h"
#include "main.h"

View File

@@ -1,7 +1,7 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* assignments.c: Assignments for specific windows (for_window).

View File

@@ -1,2 +0,0 @@
#include "atoms_NET_SUPPORTED.xmacro"
#include "atoms_rest.xmacro"

View File

@@ -1,34 +0,0 @@
xmacro(_NET_SUPPORTED)
xmacro(_NET_SUPPORTING_WM_CHECK)
xmacro(_NET_WM_NAME)
xmacro(_NET_WM_VISIBLE_NAME)
xmacro(_NET_WM_MOVERESIZE)
xmacro(_NET_WM_STATE_STICKY)
xmacro(_NET_WM_STATE_FULLSCREEN)
xmacro(_NET_WM_STATE_DEMANDS_ATTENTION)
xmacro(_NET_WM_STATE_MODAL)
xmacro(_NET_WM_STATE_HIDDEN)
xmacro(_NET_WM_STATE)
xmacro(_NET_WM_WINDOW_TYPE)
xmacro(_NET_WM_WINDOW_TYPE_NORMAL)
xmacro(_NET_WM_WINDOW_TYPE_DOCK)
xmacro(_NET_WM_WINDOW_TYPE_DIALOG)
xmacro(_NET_WM_WINDOW_TYPE_UTILITY)
xmacro(_NET_WM_WINDOW_TYPE_TOOLBAR)
xmacro(_NET_WM_WINDOW_TYPE_SPLASH)
xmacro(_NET_WM_WINDOW_TYPE_MENU)
xmacro(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
xmacro(_NET_WM_WINDOW_TYPE_POPUP_MENU)
xmacro(_NET_WM_WINDOW_TYPE_TOOLTIP)
xmacro(_NET_WM_WINDOW_TYPE_NOTIFICATION)
xmacro(_NET_WM_DESKTOP)
xmacro(_NET_WM_STRUT_PARTIAL)
xmacro(_NET_CLIENT_LIST)
xmacro(_NET_CLIENT_LIST_STACKING)
xmacro(_NET_CURRENT_DESKTOP)
xmacro(_NET_NUMBER_OF_DESKTOPS)
xmacro(_NET_DESKTOP_NAMES)
xmacro(_NET_DESKTOP_VIEWPORT)
xmacro(_NET_ACTIVE_WINDOW)
xmacro(_NET_CLOSE_WINDOW)
xmacro(_NET_MOVERESIZE_WINDOW)

View File

@@ -1,19 +0,0 @@
xmacro(_NET_WM_USER_TIME)
xmacro(_NET_STARTUP_ID)
xmacro(_NET_WORKAREA)
xmacro(WM_PROTOCOLS)
xmacro(WM_DELETE_WINDOW)
xmacro(UTF8_STRING)
xmacro(WM_STATE)
xmacro(WM_CLIENT_LEADER)
xmacro(WM_TAKE_FOCUS)
xmacro(WM_WINDOW_ROLE)
xmacro(I3_SOCKET_PATH)
xmacro(I3_CONFIG_PATH)
xmacro(I3_SYNC)
xmacro(I3_SHMLOG_PATH)
xmacro(I3_PID)
xmacro(I3_FLOATING_WINDOW)
xmacro(_NET_REQUEST_FRAME_EXTENTS)
xmacro(_NET_FRAME_EXTENTS)
xmacro(_MOTIF_WM_HINTS)

View File

@@ -1,7 +1,7 @@
/*
* vim:ts=4:sw=4:expandtab
*
* i3 - an improved dynamic tiling window manager
* i3 - an improved tiling window manager
* © 2009 Michael Stapelberg and contributors (see also: LICENSE)
*
* bindings.h: Functions for configuring, finding, and running bindings.

Some files were not shown because too many files have changed in this diff Show More