1
0
forked from mirrors/i3

Compare commits

...

60 Commits
4.23 ... 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
348 changed files with 3543 additions and 2134 deletions

View File

@@ -1,13 +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
SortIncludes: false
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 ]

View File

@@ -1,72 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
---
<!--
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
-->
## I'm submitting a…
<!-- Please check one of the following options with "x" -->
<pre>
[x] Bug
[ ] Feature Request
[ ] Documentation Request
[ ] Other (Please describe in detail)
</pre>
## Current Behavior
<!--
Describe the current behavior,
e.g., »When pressing Alt+j (focus left), the window above the current window is focused.«
-->
## 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.«
-->
## Reproduction Instructions
<!--
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«
-->
## 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>
<!--
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.
-->
<details><summary>Config file</summary><pre>
</pre>
</details>
<!--
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

View File

@@ -1,4 +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

View File

@@ -1,56 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
---
<!--
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
-->
## I'm submitting a…
<!-- Check one of the following options with "x" -->
<pre>
[ ] Bug
[x] Feature Request
[ ] Documentation Request
[ ] Other (Please describe in detail)
</pre>
## Current Behavior
<!--
Describe the current behavior,
e.g., »When pressing Alt+j (focus left), the window above the current window is focused.«
-->
## Desired 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.«
-->
## Impact
<!--
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>
[ ] This feature requires new configuration and/or commands
</pre>
## 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>
<!--
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>

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

View File

@@ -39,6 +39,13 @@ jobs:
- 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
@@ -46,7 +53,7 @@ jobs:
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@v2
uses: actions/upload-artifact@v4
with:
name: test-logs
path: build/testsuite-*

1
.gitignore vendored
View File

@@ -50,4 +50,3 @@ LAST_VERSION
# 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,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
@@ -132,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;
}
@@ -182,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;
}
@@ -315,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};
}

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;

View File

@@ -27,7 +27,7 @@ https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project
In case youre unfamiliar:
$ mkdir -p build && cd build
$ meson ..
$ meson setup
$ ninja
Please make sure that i3-migrate-config-to-v4 and i3-config-wizard are

View File

@@ -1,53 +0,0 @@
┌──────────────────────────────┐
│ Release notes for i3 v4.23 │
└──────────────────────────────┘
This is i3 v4.23. This version is considered stable. All users of i3 are
strongly encouraged to upgrade.
The biggest feature of this release is i3bars workspace button protocol,
which allows the workspace_command program or script to filter, re-arrange,
or otherwise customize the displayed workspaces:
https://i3wm.org/docs/i3bar-workspace-protocol.html
┌────────────────────────────┐
│ Changes in i3 v4.23 │
└────────────────────────────┘
• docs/userguide: add an example for negative lookaheads
• docs/userguide: fix default binding mistake
• docs/userguide: add link to tiling drag
• docs/hacking-howto: update build instructions, startup
• docs/debugging: add note about ptrace
• man/i3: remove outdated I3SOCK description
• all: build with -D_FORTIFY_SOURCE=3
• i3bar: fix configuring bars on “output nonprimary”
• i3bar: implement workspace button protocol
• add “focus workspace” command
• allow switching workspaces when in global fullscreen mode
• exec: single-fork instead of double-forking
• share X11 graphics context (GC) globally
┌────────────────────────────┐
│ Bugfixes │
└────────────────────────────┘
• fix regression with i3bar's output nonprimary
• fix top border resizing on tiling windows
• fix workspace not being focused on title bar scroll
• fix mouse bindings in modes
• fix crashes when using machine criterion
• fix for_window not working with urgency flags
• motif hints: respect maximum border style in append_layout
┌────────────────────────────┐
│ Thanks! │
└────────────────────────────┘
Thanks for testing, bugfixes, discussions and everything I forgot go out to:
Harm te Hennepe, Nikita Bobko, Nikolay Nechaev, Orestis Floros, Sergey
Zhmylove, slyshot, Uli Schlachter, Wesley Schwengle
-- Michael Stapelberg, 2023-10-29

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

@@ -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

@@ -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

12
debian/changelog vendored
View File

@@ -1,3 +1,15 @@
i3-wm (4.24-1) unstable; urgency=medium
* New upstream release.
-- 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.

2
debian/control vendored
View File

@@ -44,7 +44,7 @@ Architecture: any
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

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}

View File

@@ -28,9 +28,9 @@ 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:
$ mkdir -p build && cd build
$ meson ..
$ ninja
mkdir -p build
meson setup build
meson compile -C build
=== Build system features

View File

@@ -86,7 +86,7 @@ name (string)::
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 monitors.
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
@@ -129,7 +129,7 @@ i3-msg -t subscribe -m '["workspace", "output"]' | {
# avoids having an empty bar when starting up.
i3-msg -t get_workspaces;
# Then, while we receive events, update the workspace information.
while read; do i3-msg -t get_workspaces; done;
while read EVENT; do i3-msg -t get_workspaces; done;
}
------------------------------
@@ -139,7 +139,7 @@ i3-msg -t subscribe -m '["workspace", "output"]' | {
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
i3-msg -t get_workspaces;
while read; do i3-msg -t get_workspaces; done;
while read EVENT; do i3-msg -t get_workspaces; done;
} | jq --unbuffered -c '[ .[] | select(.name != "foo" or .focused) ]'
------------------------------
@@ -153,7 +153,7 @@ might mean that you are getting an empty bar until enough events are written.
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
i3-msg -t get_workspaces;
while read; do i3-msg -t get_workspaces; done;
while read EVENT; do i3-msg -t get_workspaces; done;
} | jq --unbuffered -c '
def fake_ws(name): {
name: name,
@@ -169,7 +169,7 @@ i3-msg -t subscribe -m '["workspace", "output"]' | {
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
i3-msg -t get_workspaces;
while read; do i3-msg -t get_workspaces; done;
while read EVENT; do i3-msg -t get_workspaces; done;
} | jq --unbuffered -c 'sort_by(.name) | reverse'
------------------------------
@@ -179,6 +179,6 @@ i3-msg -t subscribe -m '["workspace", "output"]' | {
#!/bin/sh
i3-msg -t subscribe -m '["workspace", "output"]' | {
i3-msg -t get_workspaces;
while read; do i3-msg -t get_workspaces; done;
while read EVENT; do i3-msg -t get_workspaces; done;
} | jq --unbuffered -c '[ .[] | .name |= . + " foo" ]'
------------------------------

View File

@@ -10,15 +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
executing +i3 --get-socketpath+, which will print the path to the standard
output (plus a newline).
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!
@@ -997,9 +1004,18 @@ 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
+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

View File

@@ -76,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
@@ -119,48 +109,57 @@ tests are run under Xvfb.
---------------------------------------
$ cd ~/i3
$ mkdir -p build && cd build
$ mkdir -p build
$ meson ..
$ meson setup build
$ cd build
$ ninja
$ 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:
@@ -172,37 +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
$ mkdir -p build && cd build
$ mkdir -p build
$ meson ..
$ meson setup build
$ cd build
$ ninja
# output omitted because it is very long
$ ninja test
[1/102] Generating config.h with a custom command
[1/2] Running all tests.
1/1 complete-run OK 34.39s
$ 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
============================================================================
Ok: 1
Expected Fail: 0
Fail: 0
Unexpected Pass: 0
Skipped: 0
Timeout: 0
$ less test-suite.log
Full log written to i3/build/meson-logs/testlog.txt
$ less latest/complete-run.log
----------------------------------------
==== Coverage testing

View File

@@ -216,6 +216,10 @@ Drop on container::
This happens when the mouse is relatively near the center of a container.
If the mouse is released, the result is exactly as if you had run the
+move container to mark+ command. See <<move_to_mark>>.
If the swap modifier is pressed before initiating the drag (+tiling_drag
swap_modifier+ set to Shift by default), the containers are swapped
instead. In that case, the result is exactly as if you had run the +swap
container with mark+ command. See <<swapping_containers>>.
Drop as sibling::
This happens when the mouse is relatively near the edge of a container. If
the mouse is released, the dragged container will become a sibling of the
@@ -354,15 +358,6 @@ keyboard layout. To start the wizard, use the command +i3-config-wizard+.
Please note that you must not have +~/.i3/config+, otherwise the wizard will
exit.
Since i3 4.0, a new configuration format is used. i3 will try to automatically
detect the format version of a config file based on a few different keywords,
but if you want to make sure that your config is read with the new format,
include the following line in your config file:
---------------------
# i3 config file (v4)
---------------------
[[include]]
=== Include directive
@@ -512,8 +507,8 @@ your bindings in the same physical location on the keyboard, use keycodes.
If you dont switch layouts, and want a clean and simple config file, use
keysyms.
Some tools (such as +import+ or +xdotool+) might be unable to run upon a
KeyPress event, because the keyboard/pointer is still grabbed. For these
Some tools (such as +xdotool+) might be unable to run upon a
KeyPress event, because the keyboard is still grabbed. For these
situations, the +--release+ flag can be used, which will execute the command
after the keys have been released.
@@ -743,8 +738,11 @@ This option determines which border style *new* windows will have. The default
+normal+. Note that default_floating_border applies only to windows which are starting out as
floating windows, e.g., dialog windows, but not windows that are floated later on.
Setting border style to +pixel+ eliminates title bars. The border style +normal+ allows you to
adjust edge border width while keeping your title bar.
Setting border style to +pixel+ eliminates title bars in split layouts. The border style
+normal+ allows you to adjust edge border width while keeping your title bar.
The title bar is always visible in stacking and tabbed layouts, and this cannot be changed
through configuration.
*Syntax*:
---------------------------------------------
@@ -789,6 +787,10 @@ The "smart_no_gaps" setting hides edge-specific borders of a container if the
container is the only container on its workspace and the gaps to the screen edge
are +0+.
[[_smart_borders]]
+hide_edge_borders+ has replaced the old +smart_borders+ syntax. Use the former
instead of the latter.
*Syntax*:
-----------------------------------------------
hide_edge_borders none|vertical|horizontal|both|smart|smart_no_gaps
@@ -799,27 +801,6 @@ hide_edge_borders none|vertical|horizontal|both|smart|smart_no_gaps
hide_edge_borders vertical
----------------------
[[_smart_borders]]
=== Smart borders
Smart borders will draw borders on windows only if there is more than one window
in a workspace. This feature can also be enabled only if the gap size between
window and screen edge is +0+.
*Syntax*:
-----------------------------------------------
smart_borders on|off|no_gaps
-----------------------------------------------
*Example*:
----------------------
# Activate smart borders (always)
smart_borders on
# Activate smart borders (only when there are effectively no gaps)
smart_borders no_gaps
----------------------
[[for_window]]
=== Arbitrary commands for specific windows (for_window)
@@ -1243,19 +1224,21 @@ mouse_warping none
When you are in fullscreen mode, some applications still open popup windows
(take Xpdf for example). This is because these applications might not be aware
that they are in fullscreen mode (they do not check the corresponding hint).
There are three things which are possible to do in this situation:
i3 supports four options for this situation:
1. Display the popup if it belongs to the fullscreen application only. This is
the default and should be reasonable behavior for most users.
2. Just ignore the popup (dont map it). This wont interrupt you while you are
in fullscreen. However, some apps might react badly to this (deadlock until
you go out of fullscreen).
3. Leave fullscreen mode.
1. +smart+: Display the popup if it belongs to the fullscreen application only.
This is the default and should be reasonable behavior for most users.
2. +ignore+: Just ignore the popup (dont map it). This wont interrupt you
while you are in fullscreen. However, some apps might react badly to this
(deadlock until you go out of fullscreen).
3. +leave_fullscreen+: Leave fullscreen mode.
4. +all+: Since i3 4.24: Display all floating windows regardless to which
application they belong to.
*Syntax*:
-----------------------------------------------------
popup_during_fullscreen smart|ignore|leave_fullscreen
-----------------------------------------------------
---------------------------------------------------------
popup_during_fullscreen smart|ignore|leave_fullscreen|all
---------------------------------------------------------
*Example*:
------------------------------
@@ -1441,10 +1424,16 @@ You can configure how to initiate the tiling drag feature (see <<tiling_drag>>).
The default is +modifier+.
Since i3 4.24, you can configure a modifier key which, when pressed, will swap
instead of moving containers when dropping directly onto another container.
Defaults to +Shift+. Note that you have to be pressing both the floating
modifer and the swap modifier before the drag is initiated.
*Syntax*:
--------------------------------
tiling_drag off
tiling_drag modifier|titlebar [modifier|titlebar]
tiling_drag swap_modifier <modifier>
--------------------------------
*Examples*:
@@ -1457,6 +1446,14 @@ tiling_drag modifier titlebar
# Disable tiling drag altogether
tiling_drag off
# Use Control to swap containers
tiling_drag swap_modifier Control
# Setting the swap_modifier to be the same key as the floating modifier will
# always swap without the need to hold two keys
floating_modifier Mod4
tiling_drag swap_modifier Mod4
--------------------------------
[[gaps]]
@@ -2486,7 +2483,7 @@ bindsym $mod+u focus parent
bindsym $mod+g focus mode_toggle
# Focus the next output (effectively toggles when you only have two outputs)
bindsym $mod+x move workspace to output next
bindsym $mod+x focus output next
# Focus the output right to the current one
bindsym $mod+x focus output right
@@ -2558,6 +2555,7 @@ bindsym $mod+c move absolute position center
bindsym $mod+m move position mouse
-------------------------------------------------------
[[swapping_containers]]
=== Swapping containers
Two containers can be swapped (i.e., move to each other's position) by using

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

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
@@ -157,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;
@@ -184,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;
@@ -204,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)
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;
@@ -233,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;
}
}
@@ -269,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));
@@ -303,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;
}
@@ -329,8 +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++;
}
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,27 +429,32 @@ 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) {
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 data
* structure for commands which do *not* specify any
* criteria, we re-initialize the criteria system after
@@ -513,17 +541,19 @@ static int handle_expose(void) {
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);
@@ -562,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. */
@@ -573,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) */
@@ -583,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;
@@ -596,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;
@@ -614,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;
@@ -640,20 +676,24 @@ static void finish(void) {
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;
@@ -684,8 +724,9 @@ static void finish(void) {
#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;
@@ -699,10 +740,11 @@ static void finish(void) {
/* 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;
}
@@ -767,12 +809,13 @@ int main(int argc, char *argv[]) {
return 0;
case 'm':
headless_run = true;
if (strcmp(optarg, "alt") == 0)
if (strcmp(optarg, "alt") == 0) {
modifier = MOD_Mod1;
else if (strcmp(optarg, "win") == 0)
} else if (strcmp(optarg, "win") == 0) {
modifier = MOD_Mod4;
else
} else {
err(EXIT_FAILURE, "Invalid modifier key %s", optarg);
}
break;
case 'h':
printf("i3-config-wizard " I3_VERSION "\n");
@@ -789,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);
@@ -799,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);
@@ -815,8 +861,9 @@ int main(int argc, char *argv[]) {
int screen;
if ((conn = xcb_connect(NULL, &screen)) == NULL ||
xcb_connection_has_error(conn))
xcb_connection_has_error(conn)) {
errx(1, "Cannot open display");
}
if (xkb_x11_setup_xkb_extension(conn,
XKB_X11_MIN_MAJOR_XKB_VERSION,
@@ -825,8 +872,9 @@ 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;
@@ -852,8 +900,9 @@ int main(int argc, char *argv[]) {
root_screen = xcb_aux_get_screen(conn, screen);
root = root_screen->root;
if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL)))
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);

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.
@@ -39,8 +39,9 @@ static int ipcfd = -1;
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;
@@ -53,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. */
@@ -148,8 +150,9 @@ int main(int argc, char *argv[]) {
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;
@@ -175,8 +178,9 @@ 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;
@@ -211,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++;
}

View File

@@ -822,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,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-input/main.c: Utility which lets the user input commands and sends them
@@ -170,7 +170,7 @@ static void finish_input(void) {
cnt++;
}
}
printf("occurrences = %ld\n", cnt);
printf("occurrences = %zu\n", cnt);
/* allocate space for the output */
const size_t input_len = strlen(command);
@@ -226,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) {
@@ -236,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]);
@@ -262,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);
@@ -287,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;
@@ -402,7 +407,7 @@ int main(int argc, char *argv[]) {
socket_path = sstrdup(optarg);
break;
case 'v':
printf("i3-input " I3_VERSION);
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 */
@@ -442,8 +447,9 @@ int main(int argc, char *argv[]) {
int screen;
conn = xcb_connect(NULL, &screen);
if (!conn || xcb_connection_has_error(conn))
if (!conn || xcb_connection_has_error(conn)) {
die("Cannot open display");
}
sockfd = ipc_connect(socket_path);
@@ -456,8 +462,9 @@ int main(int argc, char *argv[]) {
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();

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
@@ -61,22 +61,24 @@ 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 = sstrndup((const char *)val, len);
if (strcmp(last_key, "error") == 0)
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;
}
@@ -146,10 +148,6 @@ 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;
@@ -244,12 +242,14 @@ 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);
uint32_t reply_length;
@@ -257,12 +257,14 @@ int main(int argc, char *argv[]) {
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) {
@@ -303,8 +305,9 @@ int main(int argc, char *argv[]) {
do {
free(reply);
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);
}

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-nagbar is a utility which displays a nag message, for example in the case
@@ -126,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;
}
@@ -148,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
@@ -460,8 +464,9 @@ int main(int argc, char *argv[]) {
buttons[buttoncnt].action);
buttoncnt++;
printf("now %d buttons\n", buttoncnt);
if (optind < argc)
if (optind < argc) {
optind++;
}
break;
}
}
@@ -470,8 +475,9 @@ int main(int argc, char *argv[]) {
int screens;
if ((conn = xcb_connect(NULL, &screens)) == NULL ||
xcb_connection_has_error(conn))
xcb_connection_has_error(conn)) {
die("Cannot open display");
}
/* Place requests for the atoms we need as soon as possible */
#define xmacro(atom) \
@@ -507,11 +513,6 @@ 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
/* 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) {

View File

@@ -14,7 +14,7 @@
# 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; do
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

@@ -46,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;

View File

@@ -65,8 +65,6 @@ 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;

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

@@ -8,6 +8,7 @@
*
*/
#include "common.h"
#include "queue.h"
#include "yajl_utils.h"
#include <ctype.h> /* isspace */
@@ -21,6 +22,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -195,10 +197,11 @@ 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;
@@ -337,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);
@@ -351,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;
}
@@ -444,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);
@@ -694,8 +703,9 @@ static 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);
@@ -871,20 +881,27 @@ void send_block_clicked(int button, const char *name, const char *instance, int
ystr("modifiers");
yajl_gen_array_open(gen);
if (mods & XCB_MOD_MASK_SHIFT)
if (mods & XCB_MOD_MASK_SHIFT) {
ystr("Shift");
if (mods & XCB_MOD_MASK_CONTROL)
}
if (mods & XCB_MOD_MASK_CONTROL) {
ystr("Control");
if (mods & XCB_MOD_MASK_1)
}
if (mods & XCB_MOD_MASK_1) {
ystr("Mod1");
if (mods & XCB_MOD_MASK_2)
}
if (mods & XCB_MOD_MASK_2) {
ystr("Mod2");
if (mods & XCB_MOD_MASK_3)
}
if (mods & XCB_MOD_MASK_3) {
ystr("Mod3");
if (mods & XCB_MOD_MASK_4)
}
if (mods & XCB_MOD_MASK_4) {
ystr("Mod4");
if (mods & XCB_MOD_MASK_5)
}
if (mods & XCB_MOD_MASK_5) {
ystr("Mod5");
}
yajl_gen_array_close(gen);
ystr("x");

View File

@@ -76,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) {

View File

@@ -212,8 +212,9 @@ static void got_bar_config_update(const unsigned char *event, size_t size) {
sasprintf(&expected_id, "\"id\":\"%s\"", config.bar_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);

View File

@@ -119,8 +119,9 @@ void parse_mode_json(const unsigned char *json, size_t size) {
}
/* 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

@@ -112,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);
@@ -146,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));

View File

@@ -106,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

@@ -118,8 +118,9 @@ 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;
}
if (config.strip_ws_numbers) {
/* Offset may be equal to length, in which case display the number */

View File

@@ -12,6 +12,7 @@
#include <err.h>
#include <ev.h>
#include <i3/ipc.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -138,8 +139,9 @@ int _xcb_request_failed(xcb_void_cookie_t cookie, char *err_msg, int line) {
}
static uint32_t get_sep_offset(struct status_block *block) {
if (!block->no_separator && block->sep_block_width > 0)
if (!block->no_separator && block->sep_block_width > 0) {
return block->sep_block_width / 2 + block->sep_block_width % 2;
}
return 0;
}
@@ -147,12 +149,14 @@ static int get_tray_width(struct tc_head *trayclients) {
trayclient *trayclient;
int tray_width = 0;
TAILQ_FOREACH_REVERSE (trayclient, trayclients, tc_head, tailq) {
if (!trayclient->mapped)
if (!trayclient->mapped) {
continue;
}
tray_width += icon_size + logical_px(config.tray_padding);
}
if (tray_width > 0)
if (tray_width > 0) {
tray_width += logical_px(tray_loff_px);
}
return tray_width;
}
@@ -165,8 +169,9 @@ static void draw_separator(i3_output *output, uint32_t x, struct status_block *b
color_t bar_bg = (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg);
uint32_t sep_offset = get_sep_offset(block);
if (TAILQ_NEXT(block, blocks) == NULL || sep_offset == 0)
if (TAILQ_NEXT(block, blocks) == NULL || sep_offset == 0) {
return;
}
uint32_t center_x = x - sep_offset;
if (config.separator_symbol == NULL) {
@@ -184,50 +189,103 @@ static void draw_separator(i3_output *output, uint32_t x, struct status_block *b
}
}
static uint32_t predict_statusline_length(bool use_short_text) {
static void predict_block_length(struct status_block *block) {
i3String *text = block->full_text;
struct status_block_render_desc *render = &block->full_render;
if (block->use_short && block->short_text != NULL) {
text = block->short_text;
render = &block->short_render;
}
if (i3string_get_num_bytes(text) == 0) {
block->render_length = 0;
return;
}
render->width = predict_text_width(text);
if (block->border) {
render->width += logical_px(block->border_left + block->border_right);
}
/* Compute offset and append for text alignment in min_width. */
if (block->min_width <= render->width) {
render->x_offset = 0;
render->x_append = 0;
} else {
uint32_t padding_width = block->min_width - render->width;
switch (block->align) {
case ALIGN_LEFT:
render->x_append = padding_width;
break;
case ALIGN_RIGHT:
render->x_offset = padding_width;
break;
case ALIGN_CENTER:
render->x_offset = padding_width / 2;
render->x_append = padding_width / 2 + padding_width % 2;
break;
}
}
block->render_length = render->width + render->x_offset + render->x_append;
}
static uint32_t predict_statusline_length(void) {
uint32_t width = 0;
struct status_block *block;
TAILQ_FOREACH (block, &statusline_head, blocks) {
i3String *text = block->full_text;
struct status_block_render_desc *render = &block->full_render;
if (use_short_text && block->short_text != NULL) {
text = block->short_text;
render = &block->short_render;
}
if (i3string_get_num_bytes(text) == 0)
predict_block_length(block);
uint32_t block_width = block->render_length;
if (block_width == 0) {
continue;
render->width = predict_text_width(text);
if (block->border)
render->width += logical_px(block->border_left + block->border_right);
/* Compute offset and append for text alignment in min_width. */
if (block->min_width <= render->width) {
render->x_offset = 0;
render->x_append = 0;
} else {
uint32_t padding_width = block->min_width - render->width;
switch (block->align) {
case ALIGN_LEFT:
render->x_append = padding_width;
break;
case ALIGN_RIGHT:
render->x_offset = padding_width;
break;
case ALIGN_CENTER:
render->x_offset = padding_width / 2;
render->x_append = padding_width / 2 + padding_width % 2;
break;
}
}
width += render->width + render->x_offset + render->x_append;
width += block_width;
/* If this is not the last block, add some pixels for a separator. */
if (TAILQ_NEXT(block, blocks) != NULL)
if (TAILQ_NEXT(block, blocks) != NULL) {
width += block->sep_block_width;
}
}
return width;
}
static uint32_t switch_block_to_short(struct status_block *block) {
/* Skip blocks that have no short form or are already in short form */
if (block->short_text == NULL || block->use_short) {
return 0;
}
uint32_t full = block->render_length;
block->use_short = true;
predict_block_length(block);
return full - block->render_length;
}
static uint32_t adjust_statusline_length(uint32_t max_length) {
uint32_t width = predict_statusline_length();
/* Progressively switch the blocks to short mode */
struct status_block *block;
TAILQ_FOREACH (block, &statusline_head, blocks) {
if (width < max_length) {
break;
}
width -= switch_block_to_short(block);
/* Provide support for representing a single logical block using multiple
* JSON blocks: if one block is shortened, ensure that all other blocks
* with the same name are also shortened such that the entire logical block uses
* the short form text. */
if (block->name) {
struct status_block *other;
TAILQ_FOREACH (other, &statusline_head, blocks) {
if (other->name && !strcmp(other->name, block->name)) {
width -= switch_block_to_short(other);
}
}
}
}
return width;
@@ -236,7 +294,7 @@ static uint32_t predict_statusline_length(bool use_short_text) {
/*
* Redraws the statusline to the output's statusline_buffer
*/
static void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_colors, bool use_short_text) {
static void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_colors) {
struct status_block *block;
color_t bar_color = (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg);
@@ -254,13 +312,14 @@ static void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focu
TAILQ_FOREACH (block, &statusline_head, blocks) {
i3String *text = block->full_text;
struct status_block_render_desc *render = &block->full_render;
if (use_short_text && block->short_text != NULL) {
if (block->use_short && block->short_text != NULL) {
text = block->short_text;
render = &block->short_render;
}
if (i3string_get_num_bytes(text) == 0)
if (i3string_get_num_bytes(text) == 0) {
continue;
}
color_t fg_color;
if (block->urgent) {
@@ -284,10 +343,12 @@ static void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focu
border_color = colors.urgent_ws_border;
bg_color = colors.urgent_ws_bg;
} else {
if (block->border)
if (block->border) {
border_color = draw_util_hex_to_color(block->border);
if (block->background)
}
if (block->background) {
bg_color = draw_util_hex_to_color(block->background);
}
}
/* Draw the border. */
@@ -363,10 +424,11 @@ static void unhide_bars(void) {
XCB_CONFIG_WINDOW_HEIGHT |
XCB_CONFIG_WINDOW_STACK_MODE;
values[0] = walk->rect.x;
if (config.position == POS_TOP)
if (config.position == POS_TOP) {
values[1] = walk->rect.y;
else
} else {
values[1] = walk->rect.y + walk->rect.h - bar_height;
}
values[2] = walk->rect.w;
values[3] = bar_height;
values[4] = XCB_STACK_MODE_ABOVE;
@@ -434,8 +496,9 @@ void init_colors(const struct xcb_color_strings_t *new_colors) {
static bool execute_custom_command(xcb_keycode_t input_code, bool event_is_release) {
binding_t *binding;
TAILQ_FOREACH (binding, &(config.bindings), bindings) {
if ((binding->input_code != input_code) || (binding->release != event_is_release))
if ((binding->input_code != input_code) || (binding->release != event_is_release)) {
continue;
}
i3_send_msg(I3_IPC_MESSAGE_TYPE_RUN_COMMAND, binding->command);
return true;
@@ -454,7 +517,7 @@ static void child_handle_button(xcb_button_press_event_t *event, i3_output *outp
TAILQ_FOREACH (block, &statusline_head, blocks) {
i3String *text;
struct status_block_render_desc *render;
if (output->statusline_short_text && block->short_text != NULL) {
if (block->use_short && block->short_text != NULL) {
text = block->short_text;
render = &block->short_render;
} else {
@@ -569,19 +632,27 @@ static void handle_button(xcb_button_press_event_t *event) {
/* During button release events, only check for custom commands. */
const bool event_is_release = (event->response_type & ~0x80) == XCB_BUTTON_RELEASE;
int32_t x = event->event_x >= 0 ? event->event_x : 0;
const int x = (event->event_x >= 0 ? event->event_x : 0) - logical_px(config.padding.x);
if (x < 0) {
/* Ignore clicks in padding */
return;
}
int workspace_width = 0;
i3_ws *cur_ws = NULL, *clicked_ws = NULL, *ws_walk;
TAILQ_FOREACH (ws_walk, walk->workspaces, tailq) {
int w = predict_button_width(ws_walk->name_width);
if (x >= workspace_width && x <= workspace_width + w)
if (x >= workspace_width && x <= workspace_width + w) {
clicked_ws = ws_walk;
if (ws_walk->visible)
}
if (ws_walk->visible) {
cur_ws = ws_walk;
}
workspace_width += w;
if (TAILQ_NEXT(ws_walk, tailq) != NULL)
if (TAILQ_NEXT(ws_walk, tailq) != NULL) {
workspace_width += logical_px(ws_spacing_px);
}
}
if (child_want_click_events() && x > workspace_width) {
@@ -626,8 +697,9 @@ static void handle_button(xcb_button_press_event_t *event) {
* If there is no more workspace, dont even send the workspace
* command, otherwise (with workspace auto_back_and_forth) wed end
* up on the wrong workspace. */
if (cur_ws == TAILQ_FIRST(walk->workspaces))
if (cur_ws == TAILQ_FIRST(walk->workspaces)) {
return;
}
cur_ws = TAILQ_PREV(cur_ws, ws_head, tailq);
break;
@@ -637,8 +709,9 @@ static void handle_button(xcb_button_press_event_t *event) {
* If there is no more workspace, dont even send the workspace
* command, otherwise (with workspace auto_back_and_forth) wed end
* up on the wrong workspace. */
if (cur_ws == TAILQ_LAST(walk->workspaces, ws_head))
if (cur_ws == TAILQ_LAST(walk->workspaces, ws_head)) {
return;
}
cur_ws = TAILQ_NEXT(cur_ws, tailq);
break;
@@ -649,14 +722,16 @@ static void handle_button(xcb_button_press_event_t *event) {
* workspace if it is not already focused */
if (cur_ws == NULL) {
TAILQ_FOREACH (cur_ws, walk->workspaces, tailq) {
if (cur_ws->visible && !cur_ws->focused)
if (cur_ws->visible && !cur_ws->focused) {
break;
}
}
}
/* if there is nothing to focus, we are done */
if (cur_ws == NULL)
if (cur_ws == NULL) {
return;
}
break;
default:
@@ -885,8 +960,9 @@ static void handle_client_message(xcb_client_message_event_t *event) {
DLOG("xembed flags = %d\n", xembed[1]);
map_it = ((xembed[1] & XEMBED_MAPPED) == XEMBED_MAPPED);
xe_version = xembed[0];
if (xe_version > 1)
if (xe_version > 1) {
xe_version = 1;
}
free(xembedr);
} else {
ELOG("Window %08x violates the XEMBED protocol, _XEMBED_INFO not set\n", client);
@@ -904,8 +980,9 @@ static void handle_client_message(xcb_client_message_event_t *event) {
output_for_tray->bar.id,
output_for_tray->rect.w - icon_size - logical_px(config.tray_padding),
logical_px(config.tray_padding));
if (xcb_request_failed(rcookie, "Could not reparent window. Maybe it is using an incorrect depth/visual?"))
if (xcb_request_failed(rcookie, "Could not reparent window. Maybe it is using an incorrect depth/visual?")) {
return;
}
/* We reconfigure the window to use a reasonable size. The systray
* specification explicitly says:
@@ -1104,17 +1181,20 @@ static void handle_configuration_change(xcb_window_t window) {
trayclient *trayclient;
i3_output *output;
SLIST_FOREACH (output, outputs, slist) {
if (!output->active)
if (!output->active) {
continue;
}
int clients = 0;
TAILQ_FOREACH_REVERSE (trayclient, output->trayclients, tc_head, tailq) {
if (!trayclient->mapped)
if (!trayclient->mapped) {
continue;
}
clients++;
if (trayclient->win != window)
if (trayclient->win != window) {
continue;
}
xcb_rectangle_t rect;
rect.x = output->rect.w - (clients * (icon_size + logical_px(config.tray_padding)));
@@ -1361,8 +1441,9 @@ static void deregister_xkb_keyevents(void) {
*
*/
void init_xcb_late(char *fontname) {
if (fontname == NULL)
if (fontname == NULL) {
fontname = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
}
/* Load the font */
font = load_font(fontname, true);
@@ -1390,13 +1471,15 @@ void init_xcb_late(char *fontname) {
bar_height = default_px + padding_scaled;
icon_size = bar_height - 2 * logical_px(config.tray_padding);
if (config.separator_symbol)
if (config.separator_symbol) {
separator_symbol_width = predict_text_width(config.separator_symbol);
}
xcb_flush(xcb_connection);
if (config.hide_on_modifier == M_HIDE)
if (config.hide_on_modifier == M_HIDE) {
register_xkb_keyevents();
}
}
/*
@@ -1432,11 +1515,15 @@ static void send_tray_clientmessage(void) {
static void init_tray(void) {
DLOG("Initializing system tray functionality\n");
/* request the tray manager atom for the X11 display we are running on */
char atomname[strlen("_NET_SYSTEM_TRAY_S") + 11];
snprintf(atomname, strlen("_NET_SYSTEM_TRAY_S") + 11, "_NET_SYSTEM_TRAY_S%d", screen);
/* The following line cannot use strlen as that makes compilation fail with
* some versions of clang (-Wgnu-folding-constant): */
const size_t systray_len = strlen("_NET_SYSTEM_TRAY_S") + 11;
char atomname[systray_len];
snprintf(atomname, systray_len, "_NET_SYSTEM_TRAY_S%d", screen);
xcb_intern_atom_cookie_t tray_cookie;
if (tray_reply == NULL)
if (tray_reply == NULL) {
tray_cookie = xcb_intern_atom(xcb_connection, 0, strlen(atomname), atomname);
}
/* tray support: we need a window to own the selection */
selwin = xcb_generate_id(xcb_connection);
@@ -1603,8 +1690,9 @@ void get_atoms(void) {
*
*/
void kick_tray_clients(i3_output *output) {
if (TAILQ_EMPTY(output->trayclients))
if (TAILQ_EMPTY(output->trayclients)) {
return;
}
trayclient *trayclient;
while (!TAILQ_EMPTY(output->trayclients)) {
@@ -1899,10 +1987,11 @@ void reconfig_windows(bool redraw_bars) {
XCB_CONFIG_WINDOW_HEIGHT |
XCB_CONFIG_WINDOW_STACK_MODE;
values[0] = walk->rect.x;
if (config.position == POS_TOP)
if (config.position == POS_TOP) {
values[1] = walk->rect.y;
else
} else {
values[1] = walk->rect.y + walk->rect.h - bar_height;
}
values[2] = walk->rect.w;
values[3] = bar_height;
values[4] = XCB_STACK_MODE_ABOVE;
@@ -2025,9 +2114,6 @@ static void draw_button(surface_t *surface, color_t fg_color, color_t bg_color,
void draw_bars(bool unhide) {
DLOG("Drawing bars...\n");
uint32_t full_statusline_width = predict_statusline_length(false);
uint32_t short_statusline_width = predict_statusline_length(true);
i3_output *outputs_walk;
SLIST_FOREACH (outputs_walk, outputs, slist) {
int workspace_width = logical_px(config.padding.x);
@@ -2078,8 +2164,9 @@ void draw_bars(bool unhide) {
workspace_width, w, ws_walk->name_width, ws_walk->name);
workspace_width += w;
if (TAILQ_NEXT(ws_walk, tailq) != NULL)
if (TAILQ_NEXT(ws_walk, tailq) != NULL) {
workspace_width += logical_px(ws_spacing_px);
}
}
}
@@ -2101,27 +2188,28 @@ void draw_bars(bool unhide) {
uint32_t hoff = logical_px(((workspace_width > 0) + (tray_width > 0)) * sb_hoff_px);
uint32_t max_statusline_width = outputs_walk->rect.w - workspace_width - tray_width - hoff;
uint32_t clip_left = 0;
uint32_t statusline_width = full_statusline_width;
bool use_short_text = false;
/* Reset short mode between outputs */
struct status_block *block;
TAILQ_FOREACH (block, &statusline_head, blocks) {
block->use_short = false;
}
uint32_t statusline_width = adjust_statusline_length(max_statusline_width);
if (statusline_width > max_statusline_width) {
statusline_width = short_statusline_width;
use_short_text = true;
if (statusline_width > max_statusline_width) {
clip_left = statusline_width - max_statusline_width;
}
clip_left = statusline_width - max_statusline_width;
}
int16_t visible_statusline_width = MIN(statusline_width, max_statusline_width);
int x_dest = outputs_walk->rect.w - tray_width - logical_px((tray_width > 0) * sb_hoff_px) - visible_statusline_width;
x_dest -= logical_px(config.padding.width);
draw_statusline(outputs_walk, clip_left, use_focus_colors, use_short_text);
draw_statusline(outputs_walk, clip_left, use_focus_colors);
draw_util_copy_surface(&outputs_walk->statusline_buffer, &outputs_walk->buffer, 0, 0,
x_dest, 0, visible_statusline_width, (int16_t)bar_height);
outputs_walk->statusline_width = statusline_width;
outputs_walk->statusline_short_text = use_short_text;
}
}

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

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,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.

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)
*
* click.c: Button press (mouse click) events.

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)
*
* commands.c: all command functions (see commands_parser.c)

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)
*
* commands.c: all command functions (see commands_parser.c)

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)
*
* con.c: Functions which deal with containers directly (creating containers,
@@ -83,6 +83,22 @@ bool con_is_split(Con *con);
*/
bool con_is_hidden(Con *con);
/**
* Returns true if the container is maximized in the given orientation.
*
* If the container is floating or fullscreen, it is not considered maximized.
* Otherwise, it is maximized if it doesn't share space with any other
* container in the given orientation. For example, if a workspace contains
* a single splitv container with three children, none of them are considered
* vertically maximized, but they are all considered horizontally maximized.
*
* Passing "maximized" hints to the application can help it make the right
* choices about how to draw its borders. See discussion in
* https://github.com/i3/i3/pull/2380.
*
*/
bool con_is_maximized(Con *con, orientation_t orientation);
/**
* Returns whether the container or any of its children is sticky.
*

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)
*
* config_directives.h: all config storing functions (see config_parser.c)
@@ -69,6 +69,7 @@ CFGFUN(no_focus);
CFGFUN(ipc_socket, const char *path);
CFGFUN(ipc_kill_timeout, const long timeout_ms);
CFGFUN(tiling_drag, const char *value);
CFGFUN(tiling_drag_swap_modifier, const char *modifiers);
CFGFUN(restart_state, const char *path);
CFGFUN(popup_during_fullscreen, const char *value);
CFGFUN(color, const char *colorclass, const char *border, const char *background, const char *text, const char *indicator, const char *child_border);

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)
*
* config_parser.h: config parser-related definitions
@@ -35,7 +35,6 @@ struct stack {
struct parser_ctx {
bool use_nagbar;
bool assume_v4;
int state;
Match current_match;

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)
*
* include/configuration.h: Contains all structs/variables for the configurable
@@ -227,6 +227,9 @@ struct Config {
/** The modifier which needs to be pressed in combination with your mouse
* buttons to do things with floating windows (move, resize) */
uint32_t floating_modifier;
/** The modifier which needs to be pressed in combination with the floating
* modifier and your mouse buttons to swap containers during tiling drag */
uint32_t swap_modifier;
/** Maximum and minimum dimensions of a floating window */
int32_t floating_maximum_width;
@@ -262,6 +265,9 @@ struct Config {
/* just ignore the popup, that is, dont map it */
PDF_IGNORE = 2,
/* display all floating windows */
PDF_ALL = 3,
} popup_during_fullscreen;
/* The number of currently parsed barconfigs */
@@ -272,9 +278,6 @@ struct Config {
/* Gap sizes */
gaps_t gaps;
/* Should single containers on a workspace receive a border? */
smart_borders_t smart_borders;
/* Disable gaps if there is only one container on the workspace */
smart_gaps_t smart_gaps;
};

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)
*
* include/data.h: This file defines all data structures used by i3
@@ -81,10 +81,6 @@ typedef enum { ADJ_NONE = 0,
ADJ_UPPER_SCREEN_EDGE = (1 << 2),
ADJ_LOWER_SCREEN_EDGE = (1 << 4) } adjacent_t;
typedef enum { SMART_BORDERS_OFF,
SMART_BORDERS_ON,
SMART_BORDERS_NO_GAPS } smart_borders_t;
typedef enum { SMART_GAPS_OFF,
SMART_GAPS_ON,
SMART_GAPS_INVERSE_OUTER } smart_gaps_t;

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)
*
* display_version.c: displays the running i3 version, runs as part of

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)
*
* drag.c: click and drag.

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)
*
* ewmh.c: Get/set certain EWMH properties easily.

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)
*
* Faking outputs is useful in pathological situations (like network X servers

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)
*
* floating.c: Floating windows.

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

@@ -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)
*
* handlers.c: Small handlers for various events (keypresses, focus changes,

View File

@@ -11,6 +11,8 @@ xmacro(_NET_WM_STATE_DEMANDS_ATTENTION) \
xmacro(_NET_WM_STATE_MODAL) \
xmacro(_NET_WM_STATE_HIDDEN) \
xmacro(_NET_WM_STATE_FOCUSED) \
xmacro(_NET_WM_STATE_MAXIMIZED_VERT) \
xmacro(_NET_WM_STATE_MAXIMIZED_HORZ) \
xmacro(_NET_WM_STATE) \
xmacro(_NET_WM_WINDOW_TYPE) \
xmacro(_NET_WM_WINDOW_TYPE_NORMAL) \

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.h: global variables that are used all over i3.

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 public header defines the different constants and message types to use

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)
*
* ipc.c: UNIX domain socket IPC (initialization, client handling, protocol).

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)
*
* key_press.c: key press handler

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)
*
* libi3: contains functions which are used by i3 *and* accompanying tools such

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)
*
* load_layout.c: Restore (parts of) the layout, for example after an inplace

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)
*
* log.c: Logging functions.

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)
*
* main.c: Initialization, main loop

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)
*
* manage.c: Initially managing new windows (or existing ones on restart).

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)
*
* A "match" is a data structure which acts like a mask or expression to match

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)
*
* move.c: Moving containers into some direction.

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)
*
* output.c: Output (monitor) related functions.
@@ -31,8 +31,10 @@ Output *get_output_from_string(Output *current_output, const char *output_str);
char *output_primary_name(Output *output);
/**
* Returns the output for the given con.
*
* Retrieves the output for a given container. Never returns NULL.
* There is an assertion that _will_ fail if the container is inside an
* internal workspace. Use con_is_internal() if needed before calling this
* function.
*/
Output *get_output_for_con(Con *con);

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)
*
* For more information on RandR, please see the X.org RandR specification at

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)
*
* regex.c: Interface to libPCRE (perl compatible regular expressions).

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)
*
* render.c: Renders (determines position/sizes) the layout tree, updating the

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)
*
* resize.c: Interactive resizing.

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)
*
* restore_layout.c: Everything for restored containers that is not pure state

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)
*
* scratchpad.c: Scratchpad functions (TODO: more description)

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)
*
* The format of the shmlog data structure which i3 development versions use by

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

@@ -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)
*
* startup.c: Startup notification code. Ensures a startup notification context

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)
*
* sync.c: i3 sync protocol: https://i3wm.org/docs/testsuite.html#i3_sync

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)
*
* tiling_drag.h: Reposition tiled windows by dragging.

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)
*
* tree.c: Everything that primarily modifies the layout tree data structure.

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)
*
* util.c: Utility functions, which can be useful everywhere within i3 (see

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)
*
* window.c: Updates window attributes (X11 hints/properties).

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)
*
* workspace.c: Modifying workspaces, accessing them, moving containers to

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)
*
* x.c: Interface to X11, transfers our in-memory state to X11 (see also

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)
*
* xcb.c: Helper functions for easier usage of XCB

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)
*
* xcursor.c: libXcursor support for themed cursors.

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 is LEGACY code (we support RandR, which can do much more than

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)
*
* yajl_utils.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)
*
*/

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