forked from mirrors/i3
Compare commits
60 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
853b0d9161 | ||
|
|
9dc5230000 | ||
|
|
2746e0319b | ||
|
|
e107254f1e | ||
|
|
2f9ffa3178 | ||
|
|
d64e5df5b4 | ||
|
|
454fb63392 | ||
|
|
4a42eb085c | ||
|
|
4661e74b5e | ||
|
|
d05eed3c01 | ||
|
|
45d8f98fd5 | ||
|
|
05feaecf8a | ||
|
|
5413c15e97 | ||
|
|
be840af45c | ||
|
|
4215998929 | ||
|
|
1ee963ede9 | ||
|
|
11c0a9567f | ||
|
|
822477cb35 | ||
|
|
cd6573493c | ||
|
|
1993b7e318 | ||
|
|
3b1747a107 | ||
|
|
9a69c1eecf | ||
|
|
82a1c101fd | ||
|
|
093e3cf1f7 | ||
|
|
00aaa84ab0 | ||
|
|
caf5b32d5c | ||
|
|
854696cfb5 | ||
|
|
c06ac08aab | ||
|
|
1597ec27ee | ||
|
|
6094944345 | ||
|
|
d54a10b200 | ||
|
|
e020701df1 | ||
|
|
5834b7e824 | ||
|
|
91ce3bdbd5 | ||
|
|
ffbbbf3477 | ||
|
|
051d3537e3 | ||
|
|
d91597b1c1 | ||
|
|
47cab33aa8 | ||
|
|
910e58585f | ||
|
|
6a530de220 | ||
|
|
0639167185 | ||
|
|
60cc6ce174 | ||
|
|
b9a796b24a | ||
|
|
f8befe378a | ||
|
|
230147c815 | ||
|
|
c3173af2f1 | ||
|
|
ca510e5e0f | ||
|
|
f169624560 | ||
|
|
5fdfb14530 | ||
|
|
a56670bca8 | ||
|
|
b660d6a902 | ||
|
|
9aba43119b | ||
|
|
96d3762712 | ||
|
|
69f68dcd74 | ||
|
|
a36618f96c | ||
|
|
b42dc21068 | ||
|
|
f1f2282947 | ||
|
|
1da50c4ae0 | ||
|
|
06b3137bd7 | ||
|
|
ee12c2d1e1 |
@@ -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 ]
|
||||
|
||||
72
.github/ISSUE_TEMPLATE/bug_report.md
vendored
72
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -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
107
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Executable 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
|
||||
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +1,7 @@
|
||||
contact_links:
|
||||
- name: Userguide
|
||||
url: https://i3wm.org/docs/userguide.html
|
||||
about: i3 User’s 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
|
||||
|
||||
56
.github/ISSUE_TEMPLATE/feature_request.md
vendored
56
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -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
57
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Executable 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
|
||||
9
.github/workflows/main.yml
vendored
9
.github/workflows/main.yml
vendored
@@ -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
1
.gitignore
vendored
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 that’s 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};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!perl -T
|
||||
#!perl
|
||||
|
||||
use Test::More tests => 1;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!perl -T
|
||||
#!perl
|
||||
# vim:ts=4:sw=4:expandtab
|
||||
|
||||
use Test::More tests => 3;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!perl -T
|
||||
#!perl
|
||||
# vim:ts=4:sw=4:expandtab
|
||||
|
||||
use Test::More tests => 3;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!perl -T
|
||||
#!perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!perl -T
|
||||
#!perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!perl -T
|
||||
#!perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
@@ -27,7 +27,7 @@ https://mesonbuild.com/Quick-guide.html#compiling-a-meson-project
|
||||
In case you’re unfamiliar:
|
||||
|
||||
$ mkdir -p build && cd build
|
||||
$ meson ..
|
||||
$ meson setup
|
||||
$ ninja
|
||||
|
||||
Please make sure that i3-migrate-config-to-v4 and i3-config-wizard are
|
||||
|
||||
@@ -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 i3bar’s 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
62
RELEASE-NOTES-4.24
Normal 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
|
||||
@@ -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 |
@@ -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
12
debian/changelog
vendored
@@ -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
2
debian/control
vendored
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 you’re unfamiliar:
|
||||
|
||||
$ mkdir -p build && cd build
|
||||
$ meson ..
|
||||
$ ninja
|
||||
mkdir -p build
|
||||
meson setup build
|
||||
meson compile -C build
|
||||
|
||||
=== Build system features
|
||||
|
||||
|
||||
@@ -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" ]'
|
||||
------------------------------
|
||||
|
||||
38
docs/ipc
38
docs/ipc
@@ -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
|
||||
|
||||
138
docs/testsuite
138
docs/testsuite
@@ -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 don’t 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 don’t 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
|
||||
|
||||
@@ -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 don’t 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 (don’t map it). This won’t 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 (don’t map it). This won’t 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, let’s 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, let’s 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);
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -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 doesn’t 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");
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
252
i3bar/src/xcb.c
252
i3bar/src/xcb.c
@@ -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, don’t even send the workspace
|
||||
* command, otherwise (with workspace auto_back_and_forth) we’d 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, don’t even send the workspace
|
||||
* command, otherwise (with workspace auto_back_and_forth) we’d 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, don’t 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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user