├── .clang-format ├── .dockerignore ├── .editorconfig ├── .github ├── CONTRIBUTING.md ├── GOVERNANCE.md ├── ISSUE_TEMPLATE.md ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md └── workflows │ └── main.yml ├── .gitignore ├── AnyEvent-I3 ├── Changes ├── MANIFEST ├── MANIFEST.SKIP ├── Makefile.PL ├── README ├── lib │ └── AnyEvent │ │ └── I3.pm └── t │ ├── 00-load.t │ ├── 01-workspaces.t │ ├── 02-sugar.t │ ├── boilerplate.t │ ├── manifest.t │ ├── pod-coverage.t │ └── pod.t ├── DEPENDS ├── I3_VERSION ├── LICENSE ├── PACKAGE-MAINTAINER ├── README.md ├── RELEASE-NOTES-4.21.1 ├── contrib ├── banner.svg ├── dump-asy.pl ├── gtk-tree-watch.pl ├── i3-wsbar ├── per-workspace-layout.pl ├── show-download-count.sh ├── sticker-7x5cm-stickma.tif.lzma ├── sticker_stickma_black.svg └── trivial-bar-script.sh ├── debian ├── changelog ├── compat ├── control ├── copyright ├── i3-wm.doc-base ├── i3-wm.install ├── i3-wm.links ├── i3-wm.wm ├── rules ├── upstream │ └── signing-key.asc └── watch ├── docs ├── GPN-2009-06-27 │ ├── i3.tex │ ├── reparenting.dia │ ├── reparenting.eps │ ├── screenshot.png │ ├── screenshot.ps │ ├── xft.eps │ ├── xft.jpg │ ├── xserver_konzept.dia │ └── xserver_konzept.eps ├── NoName-2009-03-12 │ ├── i3.tex │ └── screenshot.png ├── asciidoc-git.conf ├── bigpicture.asy ├── bigpicture.png ├── debugging ├── hacking-howto ├── i3-pod2html ├── i3-sync-working.dia ├── i3-sync-working.png ├── i3-sync.dia ├── i3-sync.png ├── i3bar-protocol ├── ipc ├── keyboard-layer1.png ├── keyboard-layer1.svg ├── keyboard-layer2.png ├── keyboard-layer2.svg ├── layout-saving ├── layout-saving-1.png ├── logo-30.png ├── modes.png ├── multi-monitor ├── refcard.html ├── refcard_style.css ├── single_terminal.png ├── slides-2012-01-25 │ ├── TdilE.jpg │ ├── Ubuntu_Linux_Jaunty_screenshot.png │ └── i3.tex ├── slides-2012-03-16 │ ├── TdilE.jpg │ ├── Ubuntu_Linux_Jaunty_screenshot.png │ └── i3.tex ├── snapping.png ├── testsuite ├── tree-layout1.png ├── tree-layout2.png ├── tree-shot1.png ├── tree-shot2.png ├── tree-shot3.png ├── tree-shot4.png ├── two_columns.png ├── two_terminals.png ├── userguide ├── wsbar ├── wsbar.dia └── wsbar.png ├── etc ├── config └── config.keycodes ├── generate-command-parser.pl ├── i3-config-wizard ├── i3-config-wizard-atoms.xmacro.h ├── main.c └── xcb.h ├── i3-dmenu-desktop ├── i3-dump-log └── main.c ├── i3-input ├── UnicodeData.txt ├── convmap.pl ├── i3-input.h ├── keysym.map ├── keysym2ucs.c ├── keysym2ucs.h └── main.c ├── i3-migrate-config-to-v4 ├── i3-msg └── main.c ├── i3-nagbar ├── i3-nagbar-atoms.xmacro.h └── main.c ├── i3-save-tree ├── i3-sensible-editor ├── i3-sensible-pager ├── i3-sensible-terminal ├── i3bar ├── .gitignore ├── LICENSE ├── include │ ├── child.h │ ├── common.h │ ├── configuration.h │ ├── ipc.h │ ├── mode.h │ ├── outputs.h │ ├── parse_json_header.h │ ├── trayclients.h │ ├── util.h │ ├── workspaces.h │ ├── xcb.h │ └── xcb_atoms.def └── src │ ├── child.c │ ├── config.c │ ├── ipc.c │ ├── main.c │ ├── mode.c │ ├── outputs.c │ ├── parse_json_header.c │ ├── workspaces.c │ └── xcb.c ├── include ├── all.h ├── assignments.h ├── bindings.h ├── click.h ├── commands.h ├── commands_parser.h ├── con.h ├── config_directives.h ├── config_parser.h ├── configuration.h ├── data.h ├── display_version.h ├── drag.h ├── ewmh.h ├── fake_outputs.h ├── floating.h ├── handlers.h ├── i3-atoms_NET_SUPPORTED.xmacro.h ├── i3-atoms_rest.xmacro.h ├── i3.h ├── i3 │ └── ipc.h ├── ipc.h ├── key_press.h ├── libi3.h ├── load_layout.h ├── log.h ├── main.h ├── manage.h ├── match.h ├── move.h ├── output.h ├── queue.h ├── randr.h ├── regex.h ├── render.h ├── resize.h ├── restore_layout.h ├── scratchpad.h ├── sd-daemon.h ├── shmlog.h ├── sighandler.h ├── startup.h ├── sync.h ├── tiling_drag.h ├── tree.h ├── util.h ├── window.h ├── workspace.h ├── x.h ├── xcb.h ├── xcursor.h ├── xinerama.h └── yajl_utils.h ├── libi3 ├── README ├── boolstr.c ├── create_socket.c ├── dpi.c ├── draw_util.c ├── fake_configure_notify.c ├── font.c ├── format_placeholders.c ├── g_utf8_make_valid.c ├── get_colorpixel.c ├── get_config_path.c ├── get_exe_path.c ├── get_mod_mask.c ├── get_process_filename.c ├── get_visualtype.c ├── ipc_connect.c ├── ipc_recv_message.c ├── ipc_send_message.c ├── is_background_set.c ├── is_debug_build.c ├── mkdirp.c ├── nonblock.c ├── path_exists.c ├── resolve_tilde.c ├── root_atom_contents.c ├── safewrappers.c ├── screenshot_wallpaper.c ├── string.c ├── strndup.c └── ucs2_conversion.c ├── logo.svg ├── man ├── asciidoc.conf.in ├── i3-config-wizard.man ├── i3-dump-log.man ├── i3-input.man ├── i3-migrate-config-to-v4.man ├── i3-msg.man ├── i3-nagbar.man ├── i3-sensible-editor.man ├── i3-sensible-pager.man ├── i3-sensible-terminal.man ├── i3.man └── i3bar.man ├── meson.build ├── meson ├── meson-dist-script └── meson-install-i3-with-shmlog ├── meson_options.txt ├── parser-specs ├── commands.spec ├── config.spec └── highlighting.vim ├── pseudo-doc.doxygen ├── release-notes ├── bugfixes │ ├── 0-example │ ├── 1-motifs │ ├── 2-focus-click │ ├── 3-drag-cursor │ └── 4-drop-scratchpad ├── changes │ ├── 0-example │ ├── 1-tiling-drag │ └── 2-tiling-drag-targets └── generator.pl ├── release.sh ├── share ├── applications │ └── i3.desktop └── xsessions │ ├── i3-with-shmlog.desktop │ └── i3.desktop ├── src ├── assignments.c ├── bindings.c ├── click.c ├── commands.c ├── commands_parser.c ├── con.c ├── config.c ├── config_directives.c ├── config_parser.c ├── display_version.c ├── drag.c ├── ewmh.c ├── fake_outputs.c ├── floating.c ├── handlers.c ├── ipc.c ├── key_press.c ├── load_layout.c ├── log.c ├── main.c ├── manage.c ├── match.c ├── move.c ├── output.c ├── randr.c ├── regex.c ├── render.c ├── resize.c ├── restore_layout.c ├── scratchpad.c ├── sd-daemon.c ├── sighandler.c ├── startup.c ├── sync.c ├── tiling_drag.c ├── tree.c ├── util.c ├── version.c ├── window.c ├── workspace.c ├── x.c ├── xcb.c ├── xcursor.c └── xinerama.c ├── testcases ├── .gitignore ├── Makefile.PL ├── complete-run.pl.in ├── i3-test.config ├── inject_randr1.5.c ├── lib │ ├── SocketActivation.pm │ ├── StartXServer.pm │ ├── StatusLine.pm │ ├── TestWorker.pm │ ├── i3test.pm.in │ └── i3test │ │ ├── Test.pm │ │ ├── Util.pm │ │ └── XTEST.pm ├── new-test ├── restart-state.golden ├── t │ ├── 000-load-deps.t │ ├── 001-tile.t │ ├── 002-i3-sync.t │ ├── 003-ipc.t │ ├── 004-unmanaged.t │ ├── 005-floating.t │ ├── 100-fullscreen.t │ ├── 101-focus.t │ ├── 102-dock.t │ ├── 104-focus-stack.t │ ├── 111-goto.t │ ├── 112-floating-resize.t │ ├── 113-urgent.t │ ├── 114-client-leader.t │ ├── 115-ipc-workspaces.t │ ├── 116-nestedcons.t │ ├── 117-workspace.t │ ├── 118-openkill.t │ ├── 119-match.t │ ├── 120-multiple-cmds.t │ ├── 121-next-prev.t │ ├── 122-split.t │ ├── 124-move.t │ ├── 126-regress-close.t │ ├── 127-regress-floating-parent.t │ ├── 128-open-order.t │ ├── 129-focus-after-close.t │ ├── 130-close-empty-split.t │ ├── 131-stacking-order.t │ ├── 132-move-workspace.t │ ├── 133-size-hints.t │ ├── 134-invalid-command.t │ ├── 135-floating-focus.t │ ├── 136-floating-ws-empty.t │ ├── 137-floating-unmap.t │ ├── 138-floating-attach.t │ ├── 139-ws-numbers.t │ ├── 140-focus-lost.t │ ├── 141-resize.t │ ├── 142-regress-move-floating.t │ ├── 143-regress-floating-restart.t │ ├── 144-regress-floating-resize.t │ ├── 145-flattening.t │ ├── 146-floating-reinsert.t │ ├── 147-regress-floatingmove.t │ ├── 148-regress-floatingmovews.t │ ├── 150-regress-dock-restart.t │ ├── 151-regress-float-size.t │ ├── 152-regress-level-up.t │ ├── 153-floating-originalsize.t │ ├── 154-regress-multiple-dock.t │ ├── 155-floating-split-size.t │ ├── 156-fullscreen-focus.t │ ├── 158-wm_take_focus.t │ ├── 159-socketpaths.t │ ├── 161-regress-borders-restart.t │ ├── 162-regress-dock-urgent.t │ ├── 163-wm-state.t │ ├── 164-kill-win-vs-client.t │ ├── 165-for_window.t │ ├── 166-assign.t │ ├── 167-workspace_layout.t │ ├── 168-regress-fullscreen-restart.t │ ├── 169-border-toggle.t │ ├── 170-force_focus_wrapping.t │ ├── 171-config-migrate.t │ ├── 172-start-on-named-ws.t │ ├── 173-get-marks.t │ ├── 174-border-config.t │ ├── 175-startup-notification.t │ ├── 176-workspace-baf.t │ ├── 177-bar-config.t │ ├── 178-regress-workspace-open.t │ ├── 179-regress-multiple-ws.t │ ├── 180-fd-leaks.t │ ├── 181-regress-float-border.t │ ├── 182-regress-focus-dock.t │ ├── 183-config-variables.t │ ├── 184-regress-float-split-resize.t │ ├── 185-scratchpad.t │ ├── 186-regress-assign-focus-parent.t │ ├── 187-commands-parser.t │ ├── 188-regress-focus-restart.t │ ├── 189-floating-constraints.t │ ├── 190-scratchpad-diff-ws.t │ ├── 191-resize-levels.t │ ├── 192-layout.t │ ├── 193-ipc-version.t │ ├── 194-regress-floating-size.t │ ├── 195-net-active-window.t │ ├── 196-randr-output-names.t │ ├── 197-regression-move-vanish.t │ ├── 198-regression-scratchpad-crash.t │ ├── 199-ipc-mode-event.t │ ├── 200-urgency-timer.t │ ├── 201-config-parser.t │ ├── 202-scratchpad-criteria.t │ ├── 203-regress-assign-and-move.t │ ├── 204-regress-scratchpad-move.t │ ├── 205-ipc-windows.t │ ├── 206-fullscreen-scratchpad.t │ ├── 207-shmlog.t │ ├── 208-regress-floating-criteria.t │ ├── 209-ewmh-net-workarea.t │ ├── 210-mark-unmark.t │ ├── 211-regress-urgency-assign.t │ ├── 212-assign-urgency.t │ ├── 213-layout-restore-simple.t │ ├── 214-layout-restore-criteria.t │ ├── 215-layout-restore-crash.t │ ├── 216-layout-restore-split-swallows.t │ ├── 217-NET_CURRENT_DESKTOP.t │ ├── 218-regress-floating-split.t │ ├── 219-ipc-window-focus.t │ ├── 220-ipc-window-title.t │ ├── 221-floating-type-hints.t │ ├── 222-regress-dock-resize.t │ ├── 223-net-client-list.t │ ├── 224-regress-resize-branch.t │ ├── 225-ipc-window-fullscreen.t │ ├── 226-internal-workspaces.t │ ├── 227-ipc-workspace-empty.t │ ├── 228-border-widths.t │ ├── 229-cleanup-tmpdir.t │ ├── 230-floating-fullscreen-restart.t │ ├── 231-ipc-floating-event.t │ ├── 232-cmd-move-criteria.t │ ├── 233-regress-manage-focus-unmapped.t │ ├── 234-ewmh-desktop-names.t │ ├── 235-check-config-no-x.t │ ├── 236-floating-focus-raise.t │ ├── 237-regress-assign-focus.t │ ├── 238-ipc-binding-event.t │ ├── 239-net-close-window-request.t │ ├── 240-focus-on-window-activation.t │ ├── 241-consistent-center.t │ ├── 242-no-focus.t │ ├── 243-move-to-mark.t │ ├── 244-new-workspace-floating-enable-center.t │ ├── 245-move-position-mouse.t │ ├── 246-window-decoration-focus.t │ ├── 247-config-line-continuation.t │ ├── 248-regress-urgency-clear.t │ ├── 249-layout-restore-floating.t │ ├── 250-layout-restore-multiple-criteria.t │ ├── 251-command-criteria-focused.t │ ├── 252-floating-size.t │ ├── 253-multiple-net-wm-state-atoms.t │ ├── 254-move-to-output-with-criteria.t │ ├── 255-multiple-marks.t │ ├── 256-no-auto-back-and-forth.t │ ├── 257-keypress-group1-fallback.t │ ├── 258-keypress-release.t │ ├── 259-net-wm-user-time.t │ ├── 260-invalid-criteria.t │ ├── 261-match-con_id-con_mark-combinations.t │ ├── 262-config-validation.t │ ├── 263-config-reload-reverts-bind-mode.t │ ├── 264-dock-criteria.t │ ├── 265-ipc-mark.t │ ├── 266-net-moveresize-window.t │ ├── 267-regress-mark-restart.t │ ├── 268-ipc-config.t │ ├── 269-focus-stack-above.t │ ├── 270-config-no-newline-end.t │ ├── 271-for_window_tilingfloating.t │ ├── 272-regress-focus-assign.t │ ├── 273-regress-focus-toggle.t │ ├── 274-move-branch-position.t │ ├── 275-ipc-window-close.t │ ├── 276-ipc-window-move.t │ ├── 277-ipc-window-urgent.t │ ├── 278-layout-restore-output.t │ ├── 279-regress-default-floating-border.t │ ├── 280-wm-class-change-handler.t │ ├── 281-regress-reload-bindsym.t │ ├── 282-tabbed-floating-disable-crash.t │ ├── 283-net-wm-state-hidden.t │ ├── 284-ewmh-visible-name.t │ ├── 285-sticky.t │ ├── 286-root-window-mouse-binding.t │ ├── 287-edge-borders.t │ ├── 288-i3-floating-window-atom.t │ ├── 289-ipc-shutdown-event.t │ ├── 290-keypress-numlock.t │ ├── 291-swap.t │ ├── 292-regress-layout-toggle.t │ ├── 293-focus-follows-mouse.t │ ├── 293-sticky-output-crash.t │ ├── 294-focus-order.t │ ├── 294-update-ewmh-atoms.t │ ├── 295-net-wm-state-focused.t │ ├── 296-regress-focus-behind-fullscreen-floating.t │ ├── 297-assign-workspace-to-output.t │ ├── 297-scroll-tabbed.t │ ├── 298-ipc-misbehaving-connection.t │ ├── 299-regress-scratchpad-focus.t │ ├── 300-restart-non-utf8.t │ ├── 301-shape.t │ ├── 302-tree.t │ ├── 303-regress-move-floating.t │ ├── 304-ipc-workspace-init.t │ ├── 305-restart-reply.t │ ├── 306-move-to-parent.t │ ├── 307-focus-next-prev.t │ ├── 308-focus_wrapping.t │ ├── 309-crash-move-parent.t │ ├── 310-client-message-sticky.t │ ├── 311-get-binding-modes.t │ ├── 312-regress-layout-default.t │ ├── 313-include.t │ ├── 314-window-icon-padding.t │ ├── 315-all-criterion.t │ ├── 315-long-commands.t │ ├── 316-drag-container.t │ ├── 316-transient-for-loop.t │ ├── 317-bar-config-font-order.t │ ├── 317-bar-output-trailing-space.t │ ├── 318-i3-dmenu-desktop.t │ ├── 500-multi-monitor.t │ ├── 501-scratchpad.t │ ├── 502-focus-output.t │ ├── 503-workspace.t │ ├── 504-move-workspace-to-output.t │ ├── 505-scratchpad-resolution.t │ ├── 506-focus-right.t │ ├── 507-workspace-move-crash.t │ ├── 509-workspace_layout.t │ ├── 510-focus-across-outputs.t │ ├── 511-scratchpad-configure-request.t │ ├── 512-move-wraps.t │ ├── 513-move-workspace.t │ ├── 514-ipc-workspace-multi-monitor.t │ ├── 515-create-workspace.t │ ├── 516-move.t │ ├── 517-regress-move-direction-ipc.t │ ├── 518-interpret-workspace-numbers.t │ ├── 519-mouse-warping.t │ ├── 520-regress-focus-direction-floating.t │ ├── 521-ewmh-desktop-viewport.t │ ├── 522-rename-assigned-workspace.t │ ├── 523-move-position-center.t │ ├── 524-move.t │ ├── 525-i3bar-mouse-bindings.t │ ├── 526-reconfigure-dock.t │ ├── 527-focus-fallback.t │ ├── 528-workspace-next-prev-reversed.t │ ├── 529-net-wm-desktop.t │ ├── 530-bug-2229.t │ ├── 531-fullscreen-on-given-output.t │ ├── 532-xresources.t │ ├── 533-randr15.t │ ├── 534-dont-warp.t │ ├── 535-workspace-next-prev.t │ ├── 536-net-wm-desktop_mm.t │ ├── 537-move-single-to-output.t │ ├── 538-i3bar-primary-output.t │ ├── 539-disable_focus_wrapping.t │ ├── 540-sigterm-cleanup.t │ ├── 541-resize-set-tiling.t │ ├── 542-layout-restore-remanage.t │ ├── 543-move-workspace-to-multiple-outputs.t │ ├── 544-focus-multiple-outputs.t │ ├── 545-i3-registration.t │ ├── 546-empty-bindcommand.t │ ├── 547-explicit-mode-default.t │ ├── 547-nested-variables.t │ └── 548-motif-hints.t └── valgrind.supp └── travis ├── check-safe-wrappers.sh ├── check-spelling.pl ├── debian-build.sh ├── deploy-github-pages.sh ├── docker-build-and-push.sh ├── docs.sh ├── ha.sh ├── push-balto.sh ├── run-tests.sh ├── skip-pkg.sh ├── travis-base-386.Dockerfile ├── travis-base-ubuntu-386.Dockerfile ├── travis-base-ubuntu.Dockerfile └── travis-base.Dockerfile /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: google 2 | AllowShortIfStatementsOnASingleLine: false 3 | AllowShortLoopsOnASingleLine: false 4 | AllowShortFunctionsOnASingleLine: None 5 | AllowShortBlocksOnASingleLine: false 6 | AlwaysBreakBeforeMultilineStrings: false 7 | IndentWidth: 4 8 | PointerBindsToType: false 9 | ColumnLimit: 0 10 | SpaceBeforeParens: ControlStatements 11 | SortIncludes: false 12 | ForEachMacros: [ TAILQ_FOREACH, TAILQ_FOREACH_REVERSE, SLIST_FOREACH, CIRCLEQ_FOREACH, CIRCLEQ_FOREACH_REVERSE, NODES_FOREACH, NODES_FOREACH_REVERSE, FOREACH_NONINTERNAL] 13 | TypenameMacros: [ SLIST_HEAD, SLIST_ENTRY, LIST_HEAD, LIST_ENTRY, SIMPLEQ_HEAD, SIMPLEQ_ENTRY, TAILQ_HEAD, TAILQ_ENTRY, CIRCLEQ_HEAD, CIRCLEQ_ENTRY ] 14 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | 8 | [*.{c,h}] 9 | indent_style = space 10 | indent_size = 4 11 | trim_trailing_whitespace = true 12 | -------------------------------------------------------------------------------- /.github/GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # i3 project governance 2 | 3 | ## Overview 4 | 5 | The i3 project uses a governance model commonly described as Benevolent 6 | Dictator For Life (BDFL). This document outlines our understanding of what this 7 | means. 8 | 9 | ## Roles 10 | 11 | * user: anyone who interacts with the i3 project 12 | * core contributor: a handful of people who have contributed significantly to 13 | the project by any means (issue triage, support, documentation, code, etc.). 14 | Core contributors are recognizable via GitHub’s “Member” badge. 15 | * BDFL: a single individual who makes decisions when consensus cannot be 16 | reached. i3’s current BDFL is [@stapelberg](https://github.com/stapelberg). 17 | 18 | ## Decision making process 19 | 20 | In general, we try to reach consensus in discussions. In case consensus cannot 21 | be reached, the BDFL makes a decision. 22 | 23 | For feature requests and code contributions specifically, the values with which 24 | we consider them can be found on the bottom of https://i3wm.org/. These values 25 | are not set in stone and are to be treated as guiding principles, not absolute 26 | rules that must be followed in every case. 27 | 28 | ## Contribution process 29 | 30 | Please see [CONTRIBUTING](CONTRIBUTING.md). 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Ask a question or request support for using i3 3 | url: https://github.com/i3/i3/discussions/new 4 | about: Ask a question or request support for using i3 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | tags 3 | include/GENERATED_*.h 4 | include/all.h.pch 5 | *~ 6 | *.swp 7 | *.gcda 8 | *.gcno 9 | *.dSYM 10 | test.commands_parser 11 | test.config_parser 12 | testcases/MYMETA.json 13 | testcases/MYMETA.yml 14 | testcases/blib/ 15 | testcases/pm_to_blib 16 | AnyEvent-I3/Makefile 17 | AnyEvent-I3/META.yml 18 | AnyEvent-I3/MYMETA.json 19 | AnyEvent-I3/MYMETA.yml 20 | AnyEvent-I3/blib/ 21 | AnyEvent-I3/inc/ 22 | AnyEvent-I3/pm_to_blib 23 | *.output 24 | *.tab.* 25 | *.yy.c 26 | man/*.1 27 | man/*.xml 28 | man/*.html 29 | *.tar.bz2* 30 | *.tar.xz* 31 | i3 32 | i3-input/i3-input 33 | i3-nagbar/i3-nagbar 34 | i3-msg/i3-msg 35 | i3-config-wizard/i3-config-wizard 36 | i3-dump-log/i3-dump-log 37 | libi3.a 38 | docs/*.pdf 39 | docs/*.html 40 | !/docs/refcard.html 41 | i3-command-parser.stamp 42 | i3-config-parser.stamp 43 | .clang_complete 44 | compile_commands.json 45 | /.ccls-cache 46 | /.clangd 47 | LAST_VERSION 48 | build 49 | 50 | # We recommend building in a subdirectory called build. 51 | # If you chose a different directory name, 52 | # it is up to you to arrange for it to be ignored by git, 53 | # e.g. by listing your directory in .git/info/exclude. 54 | /build 55 | 56 | -------------------------------------------------------------------------------- /AnyEvent-I3/MANIFEST: -------------------------------------------------------------------------------- 1 | Changes 2 | lib/AnyEvent/I3.pm 3 | Makefile.PL 4 | MANIFEST This list of files 5 | MANIFEST.SKIP 6 | README 7 | t/00-load.t 8 | t/01-workspaces.t 9 | t/02-sugar.t 10 | t/boilerplate.t 11 | t/manifest.t 12 | t/pod-coverage.t 13 | t/pod.t 14 | -------------------------------------------------------------------------------- /AnyEvent-I3/MANIFEST.SKIP: -------------------------------------------------------------------------------- 1 | ^\.git/ 2 | \.bak$ 3 | blib/ 4 | ^Makefile$ 5 | ^Makefile.old$ 6 | Build 7 | Build.bat 8 | ^pm_to_blib 9 | \.tar\.gz$ 10 | ^pod2htm(.*).tmp$ 11 | ^AnyEvent-I3- 12 | ^MYMETA.* 13 | ^MANIFEST\.bak 14 | -------------------------------------------------------------------------------- /AnyEvent-I3/README: -------------------------------------------------------------------------------- 1 | AnyEvent-I3 2 | 3 | This module connects to the i3 window manager using the UNIX socket based 4 | IPC interface it provides (if enabled in the configuration file). You can 5 | then subscribe to events or send messages and receive their replies. 6 | 7 | INSTALLATION 8 | 9 | To install this module, run the following commands: 10 | 11 | perl Makefile.PL 12 | make 13 | make test 14 | make install 15 | 16 | SUPPORT AND DOCUMENTATION 17 | 18 | After installing, you can find documentation for this module with the 19 | perldoc command. 20 | 21 | perldoc AnyEvent::I3 22 | 23 | You can also look for information at: 24 | 25 | RT, CPAN's request tracker 26 | https://rt.cpan.org/NoAuth/Bugs.html?Dist=AnyEvent-I3 27 | 28 | The i3 window manager website 29 | https://i3wm.org 30 | 31 | 32 | LICENSE AND COPYRIGHT 33 | 34 | Copyright (C) 2010 Michael Stapelberg 35 | 36 | This program is free software; you can redistribute it and/or modify it 37 | under the terms of either: the GNU General Public License as published 38 | by the Free Software Foundation; or the Artistic License. 39 | 40 | See https://dev.perl.org/licenses/ for more information. 41 | -------------------------------------------------------------------------------- /AnyEvent-I3/t/00-load.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | 3 | use Test::More tests => 1; 4 | 5 | BEGIN { 6 | use_ok( 'AnyEvent::I3' ) || print "Bail out! 7 | "; 8 | } 9 | 10 | diag( "Testing AnyEvent::I3 $AnyEvent::I3::VERSION, Perl $], $^X" ); 11 | -------------------------------------------------------------------------------- /AnyEvent-I3/t/01-workspaces.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | # vim:ts=4:sw=4:expandtab 3 | 4 | use Test::More tests => 3; 5 | use AnyEvent::I3; 6 | use AnyEvent; 7 | 8 | my $i3 = i3(); 9 | my $cv = AnyEvent->condvar; 10 | 11 | # Try to connect to i3 12 | $i3->connect->cb(sub { my ($v) = @_; $cv->send($v->recv) }); 13 | 14 | # But cancel if we are not connected after 0.5 seconds 15 | my $t = AnyEvent->timer(after => 0.5, cb => sub { $cv->send(0) }); 16 | my $connected = $cv->recv; 17 | 18 | SKIP: { 19 | skip 'No connection to i3', 3 unless $connected; 20 | 21 | my $workspaces = $i3->message(1)->recv; 22 | isa_ok($workspaces, 'ARRAY'); 23 | 24 | ok(@{$workspaces} > 0, 'More than zero workspaces found'); 25 | 26 | ok(defined(@{$workspaces}[0]->{num}), 'JSON deserialized'); 27 | } 28 | 29 | diag( "Testing AnyEvent::I3 $AnyEvent::I3::VERSION, Perl $], $^X" ); 30 | -------------------------------------------------------------------------------- /AnyEvent-I3/t/02-sugar.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | # vim:ts=4:sw=4:expandtab 3 | 4 | use Test::More tests => 3; 5 | use AnyEvent::I3; 6 | use AnyEvent; 7 | 8 | my $i3 = i3(); 9 | my $cv = AnyEvent->condvar; 10 | 11 | # Try to connect to i3 12 | $i3->connect->cb(sub { my ($v) = @_; $cv->send($v->recv) }); 13 | 14 | # But cancel if we are not connected after 0.5 seconds 15 | my $t = AnyEvent->timer(after => 0.5, cb => sub { $cv->send(0) }); 16 | my $connected = $cv->recv; 17 | 18 | SKIP: { 19 | skip 'No connection to i3', 3 unless $connected; 20 | 21 | my $workspaces = i3->get_workspaces->recv; 22 | isa_ok($workspaces, 'ARRAY'); 23 | 24 | ok(@{$workspaces} > 0, 'More than zero workspaces found'); 25 | 26 | ok(defined(@{$workspaces}[0]->{num}), 'JSON deserialized'); 27 | } 28 | 29 | diag( "Testing AnyEvent::I3 $AnyEvent::I3::VERSION, Perl $], $^X" ); 30 | -------------------------------------------------------------------------------- /AnyEvent-I3/t/boilerplate.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | 3 | use strict; 4 | use warnings; 5 | use Test::More tests => 3; 6 | 7 | sub not_in_file_ok { 8 | my ($filename, %regex) = @_; 9 | open( my $fh, '<', $filename ) 10 | or die "couldn't open $filename for reading: $!"; 11 | 12 | my %violated; 13 | 14 | while (my $line = <$fh>) { 15 | while (my ($desc, $regex) = each %regex) { 16 | if ($line =~ $regex) { 17 | push @{$violated{$desc}||=[]}, $.; 18 | } 19 | } 20 | } 21 | 22 | if (%violated) { 23 | fail("$filename contains boilerplate text"); 24 | diag "$_ appears on lines @{$violated{$_}}" for keys %violated; 25 | } else { 26 | pass("$filename contains no boilerplate text"); 27 | } 28 | } 29 | 30 | sub module_boilerplate_ok { 31 | my ($module) = @_; 32 | not_in_file_ok($module => 33 | 'the great new $MODULENAME' => qr/ - The great new /, 34 | 'boilerplate description' => qr/Quick summary of what the module/, 35 | 'stub function definition' => qr/function[12]/, 36 | ); 37 | } 38 | 39 | TODO: { 40 | local $TODO = "Need to replace the boilerplate text"; 41 | 42 | not_in_file_ok(README => 43 | "The README is used..." => qr/The README is used/, 44 | "'version information here'" => qr/to provide version information/, 45 | ); 46 | 47 | not_in_file_ok(Changes => 48 | "placeholder date/time" => qr(Date/time) 49 | ); 50 | 51 | module_boilerplate_ok('lib/AnyEvent/I3.pm'); 52 | 53 | 54 | } 55 | 56 | -------------------------------------------------------------------------------- /AnyEvent-I3/t/manifest.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | 3 | use strict; 4 | use warnings; 5 | use Test::More; 6 | 7 | unless ( $ENV{RELEASE_TESTING} ) { 8 | plan( skip_all => "Author tests not required for installation" ); 9 | } 10 | 11 | eval "use Test::CheckManifest 0.9"; 12 | plan skip_all => "Test::CheckManifest 0.9 required" if $@; 13 | ok_manifest(); 14 | -------------------------------------------------------------------------------- /AnyEvent-I3/t/pod-coverage.t: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use Test::More; 4 | 5 | # Ensure a recent version of Test::Pod::Coverage 6 | my $min_tpc = 1.08; 7 | eval "use Test::Pod::Coverage $min_tpc"; 8 | plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" 9 | if $@; 10 | 11 | # Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, 12 | # but older versions don't recognize some common documentation styles 13 | my $min_pc = 0.18; 14 | eval "use Pod::Coverage $min_pc"; 15 | plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" 16 | if $@; 17 | 18 | all_pod_coverage_ok(); 19 | -------------------------------------------------------------------------------- /AnyEvent-I3/t/pod.t: -------------------------------------------------------------------------------- 1 | #!perl -T 2 | 3 | use strict; 4 | use warnings; 5 | use Test::More; 6 | 7 | # Ensure a recent version of Test::Pod 8 | my $min_tp = 1.22; 9 | eval "use Test::Pod $min_tp"; 10 | plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; 11 | 12 | all_pod_files_ok(); 13 | -------------------------------------------------------------------------------- /I3_VERSION: -------------------------------------------------------------------------------- 1 | 4.19.1-non-git 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2009, Michael Stapelberg and contributors 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions 5 | are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 3. Neither the name of the copyright holder nor the names of its 13 | contributors may be used to endorse or promote products derived 14 | from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 22 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /contrib/show-download-count.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # © 2012 Han Boetes (see also: LICENSE) 3 | 4 | YEAR=`date "+%Y"` 5 | weblog=$(mktemp) 6 | zcat $(find /var/log/lighttpd/build.i3wm.org -type f -name "access.log.*.gz" | sort | tail -5) > $weblog 7 | # this will match the latest logfile, which is not yet gzipped 8 | find /var/log/lighttpd/build.i3wm.org/log$YEAR -type f \! -name "access.log.*.gz" -exec cat '{}' \; >> $weblog 9 | cat /var/log/lighttpd/build.i3wm.org/access.log >> $weblog 10 | gitlog=$(mktemp) 11 | 12 | # create a git output logfile. Only keep the first 6 chars of the release hash 13 | git log -150 --pretty=' %h %s' next > $gitlog 14 | 15 | awk '/i3-wm_.*\.deb/ {print $7}' $weblog|awk -F'/' '{print $NF}'|awk -F'_' '{print $2 }'|awk -F'-' '{print $NF}' |cut -c 2-8|sort |uniq -c | while read line; do 16 | set -- $line 17 | # $1 is the number of downloads, $2 is the release md5sum 18 | sed -i "/$2/s|^ |$(printf '%3i' $1) d/l |" $gitlog 19 | done 20 | 21 | cat $gitlog 22 | rm $gitlog 23 | rm $weblog 24 | -------------------------------------------------------------------------------- /contrib/sticker-7x5cm-stickma.tif.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/contrib/sticker-7x5cm-stickma.tif.lzma -------------------------------------------------------------------------------- /contrib/trivial-bar-script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # vim:ts=4:sw=4:expandtab 3 | # © 2012 Michael Stapelberg, Public Domain 4 | 5 | # This script is a trivial shell script to send your own output to i3bar while 6 | # using the JSON protocol. 7 | # 8 | # It is ugly and that is inherent to using JSON with shell scripts. You 9 | # _really_ should not do that. See i3status or i3status’s contrib/ directory 10 | # for examples of how to handle the output in higher-level languages. 11 | # 12 | # This example is purely for illustration of the protocol. DO NOT USE IT IN THE 13 | # REAL WORLD. 14 | 15 | # Send the header so that i3bar knows we want to use JSON: 16 | echo '{ "version": 1 }' 17 | 18 | # Begin the endless array. 19 | echo '[' 20 | 21 | # We send an empty first array of blocks to make the loop simpler: 22 | echo '[]' 23 | 24 | # Now send blocks with information forever: 25 | while :; 26 | do 27 | echo ",[{\"name\":\"time\",\"full_text\":\"$(date)\"}]" 28 | sleep 1 29 | done 30 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /debian/i3-wm.doc-base: -------------------------------------------------------------------------------- 1 | Document: i3-wm 2 | Title: i3 documentation 3 | Author: Michael Stapelberg 4 | Abstract: The documentation explains how to use and modify the i3 window 5 | manager. 6 | Section: Window Managers 7 | 8 | Format: HTML 9 | Files: /usr/share/doc/i3-wm/*.html 10 | Index: /usr/share/doc/i3-wm/userguide.html 11 | -------------------------------------------------------------------------------- /debian/i3-wm.install: -------------------------------------------------------------------------------- 1 | debian/tmp/etc 2 | debian/tmp/usr 3 | contrib/dump-asy.pl usr/share/doc/i3-wm/examples/ 4 | contrib/gtk-tree-watch.pl usr/share/doc/i3-wm/examples/ 5 | contrib/i3-wsbar usr/share/doc/i3-wm/examples/ 6 | contrib/per-workspace-layout.pl usr/share/doc/i3-wm/examples/ 7 | contrib/trivial-bar-script.sh usr/share/doc/i3-wm/examples/ 8 | -------------------------------------------------------------------------------- /debian/i3-wm.links: -------------------------------------------------------------------------------- 1 | usr/share/man/man1/i3.1.gz usr/share/man/man1/i3-with-shmlog.1.gz 2 | -------------------------------------------------------------------------------- /debian/i3-wm.wm: -------------------------------------------------------------------------------- 1 | /usr/bin/i3 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # vi: ts=8 sw=8 noet 3 | 4 | export V:=1 5 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all 6 | 7 | override_dh_installchangelogs: 8 | dh_installchangelogs RELEASE-NOTES-* 9 | 10 | override_dh_strip: 11 | dh_strip --dbg-package=i3-wm-dbg 12 | 13 | override_dh_auto_test: 14 | # TODO: enable tests 15 | 16 | override_dh_auto_configure: 17 | # Set -Ddocdir; the default is /usr/share/doc/i3 18 | dh_auto_configure -- -Ddocdir=/usr/share/doc/i3-wm -Dmans=true 19 | 20 | %: 21 | dh $@ --buildsystem=meson 22 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | version=3 2 | opts=pgpsigurlmangle=s/$/.asc/ \ 3 | https://i3wm.org/downloads/ /downloads/i3-(.*)\.tar\.bz2 4 | -------------------------------------------------------------------------------- /docs/GPN-2009-06-27/reparenting.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/GPN-2009-06-27/reparenting.dia -------------------------------------------------------------------------------- /docs/GPN-2009-06-27/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/GPN-2009-06-27/screenshot.png -------------------------------------------------------------------------------- /docs/GPN-2009-06-27/xft.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/GPN-2009-06-27/xft.jpg -------------------------------------------------------------------------------- /docs/GPN-2009-06-27/xserver_konzept.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/GPN-2009-06-27/xserver_konzept.dia -------------------------------------------------------------------------------- /docs/NoName-2009-03-12/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/NoName-2009-03-12/screenshot.png -------------------------------------------------------------------------------- /docs/bigpicture.asy: -------------------------------------------------------------------------------- 1 | import drawtree; 2 | treeLevelStep = 2cm; 3 | TreeNode n94457831379296 = makeNode("``root'' (splith) []"); 4 | TreeNode n94457831380944 = makeNode(n94457831379296, "``\_\_i3'' (output) []"); 5 | TreeNode n94457831384048 = makeNode(n94457831380944, "``content'' (splith) []"); 6 | TreeNode n94457831387184 = makeNode(n94457831384048, "``\_\_i3\_scratch'' (splith) []"); 7 | TreeNode n94457831390576 = makeNode(n94457831379296, "``eDP-1'' (output) []"); 8 | TreeNode n94457831393744 = makeNode(n94457831390576, "``topdock'' (dockarea) []"); 9 | TreeNode n94457831396992 = makeNode(n94457831390576, "``content'' (splith) []"); 10 | TreeNode n94457831628304 = makeNode(n94457831396992, "``1'' (splith) []"); 11 | TreeNode n94457831571040 = makeNode(n94457831628304, "``Hacking i3: How To - Mozilla Firefox'' (leaf) []"); 12 | TreeNode n94457831246384 = makeNode(n94457831628304, "``vim'' (leaf) []"); 13 | TreeNode n94457831461088 = makeNode(n94457831396992, "``Named workspace'' (splith) []"); 14 | TreeNode n94457831471424 = makeNode(n94457831461088, "``[Empty]'' (tabbed) []"); 15 | TreeNode n94457831570576 = makeNode(n94457831471424, "``contrib/dump-asy.pl --no-gv'' (leaf) [Marks go here]"); 16 | TreeNode n94457831645488 = makeNode(n94457831471424, "``ipython'' (leaf) []"); 17 | TreeNode n94457831400192 = makeNode(n94457831390576, "``bottomdock'' (dockarea) []"); 18 | TreeNode n94457831424848 = makeNode(n94457831400192, "``i3bar for output eDP-1'' (leaf) []"); 19 | draw(n94457831379296, (0, 0)); 20 | -------------------------------------------------------------------------------- /docs/bigpicture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/bigpicture.png -------------------------------------------------------------------------------- /docs/i3-sync-working.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/i3-sync-working.dia -------------------------------------------------------------------------------- /docs/i3-sync-working.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/i3-sync-working.png -------------------------------------------------------------------------------- /docs/i3-sync.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/i3-sync.dia -------------------------------------------------------------------------------- /docs/i3-sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/i3-sync.png -------------------------------------------------------------------------------- /docs/keyboard-layer1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/keyboard-layer1.png -------------------------------------------------------------------------------- /docs/keyboard-layer2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/keyboard-layer2.png -------------------------------------------------------------------------------- /docs/layout-saving-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/layout-saving-1.png -------------------------------------------------------------------------------- /docs/logo-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/logo-30.png -------------------------------------------------------------------------------- /docs/modes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/modes.png -------------------------------------------------------------------------------- /docs/single_terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/single_terminal.png -------------------------------------------------------------------------------- /docs/slides-2012-01-25/TdilE.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/slides-2012-01-25/TdilE.jpg -------------------------------------------------------------------------------- /docs/slides-2012-01-25/Ubuntu_Linux_Jaunty_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/slides-2012-01-25/Ubuntu_Linux_Jaunty_screenshot.png -------------------------------------------------------------------------------- /docs/slides-2012-03-16/TdilE.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/slides-2012-03-16/TdilE.jpg -------------------------------------------------------------------------------- /docs/slides-2012-03-16/Ubuntu_Linux_Jaunty_screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/slides-2012-03-16/Ubuntu_Linux_Jaunty_screenshot.png -------------------------------------------------------------------------------- /docs/snapping.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/snapping.png -------------------------------------------------------------------------------- /docs/tree-layout1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/tree-layout1.png -------------------------------------------------------------------------------- /docs/tree-layout2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/tree-layout2.png -------------------------------------------------------------------------------- /docs/tree-shot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/tree-shot1.png -------------------------------------------------------------------------------- /docs/tree-shot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/tree-shot2.png -------------------------------------------------------------------------------- /docs/tree-shot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/tree-shot3.png -------------------------------------------------------------------------------- /docs/tree-shot4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/tree-shot4.png -------------------------------------------------------------------------------- /docs/two_columns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/two_columns.png -------------------------------------------------------------------------------- /docs/two_terminals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/two_terminals.png -------------------------------------------------------------------------------- /docs/wsbar.dia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/wsbar.dia -------------------------------------------------------------------------------- /docs/wsbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Airblader/i3/9f3e4157e66501fb3dc89abde5dc0d826193b77f/docs/wsbar.png -------------------------------------------------------------------------------- /i3-config-wizard/i3-config-wizard-atoms.xmacro.h: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | #define CONFIG_WIZARD_ATOMS_XMACRO \ 3 | xmacro(_NET_WM_NAME) \ 4 | xmacro(_NET_WM_WINDOW_TYPE) \ 5 | xmacro(_NET_WM_WINDOW_TYPE_DIALOG) \ 6 | xmacro(ATOM) \ 7 | xmacro(CARDINAL) \ 8 | xmacro(UTF8_STRING) 9 | -------------------------------------------------------------------------------- /i3-config-wizard/xcb.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* from X11/keysymdef.h */ 4 | #define XCB_NUM_LOCK 0xff7f 5 | 6 | #include "i3-config-wizard-atoms.xmacro.h" 7 | 8 | #define xmacro(atom) xcb_atom_t A_##atom; 9 | CONFIG_WIZARD_ATOMS_XMACRO 10 | #undef xmacro 11 | -------------------------------------------------------------------------------- /i3-input/i3-input.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #define die(...) errx(EXIT_FAILURE, __VA_ARGS__); 8 | #define FREE(pointer) \ 9 | do { \ 10 | free(pointer); \ 11 | pointer = NULL; \ 12 | } while (0) 13 | 14 | extern xcb_window_t root; 15 | -------------------------------------------------------------------------------- /i3-input/keysym2ucs.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long keysym2ucs(xcb_keysym_t keysym); 4 | -------------------------------------------------------------------------------- /i3-nagbar/i3-nagbar-atoms.xmacro.h: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | #define NAGBAR_ATOMS_XMACRO \ 3 | xmacro(_NET_WM_WINDOW_TYPE) \ 4 | xmacro(_NET_WM_WINDOW_TYPE_DOCK) \ 5 | xmacro(_NET_WM_STRUT_PARTIAL) \ 6 | xmacro(I3_SOCKET_PATH) \ 7 | xmacro(ATOM) \ 8 | xmacro(CARDINAL) 9 | -------------------------------------------------------------------------------- /i3-sensible-editor: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This code is released in public domain by Han Boetes 4 | # 5 | # This script tries to exec an editor by trying some known editors if $EDITOR is 6 | # not set. 7 | # 8 | # Distributions/packagers can enhance this script with a distribution-specific 9 | # mechanism to find the preferred editor 10 | 11 | # Hopefully one of these is installed (no flamewars about preference please!): 12 | for editor in "$VISUAL" "$EDITOR" nano nvim vim vi emacs pico qe mg jed gedit mcedit gvim; do 13 | if command -v "$editor" > /dev/null 2>&1; then 14 | exec "$editor" "$@" 15 | fi 16 | done 17 | -------------------------------------------------------------------------------- /i3-sensible-pager: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This code is released in public domain by Han Boetes 4 | 5 | # This script tries to exec a pager by trying some known pagers if $PAGER is 6 | # not set. 7 | # 8 | # Distributions/packagers can enhance this script with a 9 | # distribution-specific mechanism to find the preferred pager. 10 | 11 | # The less -E and -F options exit immediately for short files, strip if present. 12 | case "$LESS" in 13 | *[EF]*) LESS=`echo "$LESS" | tr -d EF` 14 | esac 15 | 16 | # Hopefully one of these is installed (no flamewars about preference please!): 17 | # We don't use 'more' because it will exit if the file is too short. 18 | # Worst case scenario we'll open the file in your editor. 19 | for pager in "$PAGER" less most w3m pg i3-sensible-editor; do 20 | if command -v "$pager" > /dev/null 2>&1; then 21 | exec "$pager" "$@" 22 | fi 23 | done 24 | -------------------------------------------------------------------------------- /i3-sensible-terminal: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This code is released in public domain by Han Boetes 4 | # 5 | # This script tries to exec a terminal emulator by trying some known terminal 6 | # emulators. 7 | # 8 | # We welcome patches that add distribution-specific mechanisms to find the 9 | # preferred terminal emulator. On Debian, there is the x-terminal-emulator 10 | # symlink for example. 11 | # 12 | # Invariants: 13 | # 1. $TERMINAL must come first 14 | # 2. Distribution-specific mechanisms come next, e.g. x-terminal-emulator 15 | # 3. The terminal emulator with best accessibility comes first. 16 | # 4. No order is guaranteed/desired for the remaining terminal emulators. 17 | 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 18 | if command -v "$terminal" > /dev/null 2>&1; then 19 | exec "$terminal" "$@" 20 | fi 21 | done 22 | 23 | i3-nagbar -m 'i3-sensible-terminal could not find a terminal emulator. Please install one.' 24 | -------------------------------------------------------------------------------- /i3bar/.gitignore: -------------------------------------------------------------------------------- 1 | i3bar 2 | *.o 3 | core 4 | doc/i3bar.1 5 | -------------------------------------------------------------------------------- /i3bar/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2010 Axel Wagner 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | * Neither the name of Axel Wagner nor the 15 | names of contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY Axel Wagner ''AS IS'' AND ANY 19 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL Axel Wagner BE LIABLE FOR ANY 22 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /i3bar/include/ipc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3bar - an xcb-based status- and ws-bar for i3 5 | * © 2010 Axel Wagner and contributors (see also: LICENSE) 6 | * 7 | * ipc.c: Communicating with i3 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | #include 15 | 16 | /* 17 | * Initiate a connection to i3. 18 | * socket_path must be a valid path to the ipc_socket of i3 19 | * 20 | */ 21 | void init_connection(const char *socket_path); 22 | 23 | /* 24 | * Destroy the connection to i3. 25 | * 26 | */ 27 | void destroy_connection(void); 28 | 29 | /* 30 | * Sends a message to i3. 31 | * type must be a valid I3_IPC_MESSAGE_TYPE (see i3/ipc.h for further information) 32 | * 33 | */ 34 | int i3_send_msg(uint32_t type, const char *payload); 35 | 36 | /* 37 | * Subscribe to all the i3-events, we need 38 | * 39 | */ 40 | void subscribe_events(void); 41 | -------------------------------------------------------------------------------- /i3bar/include/mode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3bar - an xcb-based status- and ws-bar for i3 5 | * © 2010 Axel Wagner and contributors (see also: LICENSE) 6 | * 7 | * mode.c: Handle "mode" event and show current binding mode in the bar 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | #include 15 | 16 | #include "common.h" 17 | 18 | /* Name of current binding mode and its render width */ 19 | struct mode { 20 | i3String *name; 21 | int name_width; 22 | }; 23 | 24 | typedef struct mode mode; 25 | 26 | /* 27 | * Start parsing the received JSON string 28 | * 29 | */ 30 | void parse_mode_json(char *json); 31 | -------------------------------------------------------------------------------- /i3bar/include/parse_json_header.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3bar - an xcb-based status- and ws-bar for i3 5 | * © 2010 Axel Wagner and contributors (see also: LICENSE) 6 | * 7 | * parse_json_header.c: Parse the JSON protocol header to determine 8 | * protocol version and features. 9 | * 10 | */ 11 | #pragma once 12 | 13 | #include 14 | 15 | #include 16 | 17 | /** 18 | * Parse the JSON protocol header to determine protocol version and features. 19 | * In case the buffer does not contain a valid header (invalid JSON, or no 20 | * version field found), the 'correct' field of the returned header is set to 21 | * false. The amount of bytes consumed by parsing the header is returned in 22 | * *consumed (if non-NULL). 23 | * 24 | */ 25 | void parse_json_header(i3bar_child *child, const unsigned char *buffer, int length, unsigned int *consumed); 26 | -------------------------------------------------------------------------------- /i3bar/include/trayclients.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3bar - an xcb-based status- and ws-bar for i3 5 | * © 2010 Axel Wagner and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #pragma once 9 | 10 | #include "common.h" 11 | 12 | typedef struct trayclient trayclient; 13 | 14 | TAILQ_HEAD(tc_head, trayclient); 15 | 16 | struct trayclient { 17 | xcb_window_t win; /* The window ID of the tray client */ 18 | bool mapped; /* Whether this window is mapped */ 19 | int xe_version; /* The XEMBED version supported by the client */ 20 | 21 | char *class_class; 22 | char *class_instance; 23 | 24 | TAILQ_ENTRY(trayclient) tailq; /* Pointer for the TAILQ-Macro */ 25 | }; 26 | -------------------------------------------------------------------------------- /i3bar/include/workspaces.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3bar - an xcb-based status- and ws-bar for i3 5 | * © 2010 Axel Wagner and contributors (see also: LICENSE) 6 | * 7 | * workspaces.c: Maintaining the workspace lists 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include "common.h" 13 | 14 | #include 15 | 16 | typedef struct i3_ws i3_ws; 17 | 18 | TAILQ_HEAD(ws_head, i3_ws); 19 | 20 | /* 21 | * Start parsing the received JSON string 22 | * 23 | */ 24 | void parse_workspaces_json(char *json); 25 | 26 | /* 27 | * free() all workspace data structures 28 | * 29 | */ 30 | void free_workspaces(void); 31 | 32 | struct i3_ws { 33 | uintptr_t id; /* Workspace ID - C pointer to a workspace container */ 34 | int num; /* The internal number of the ws */ 35 | char *canonical_name; /* The true name of the ws according to the ipc */ 36 | i3String *name; /* The name of the ws that is displayed on the bar */ 37 | int name_width; /* The rendered width of the name */ 38 | bool visible; /* If the ws is currently visible on an output */ 39 | bool focused; /* If the ws is currently focused */ 40 | bool urgent; /* If the urgent hint of the ws is set */ 41 | rect rect; /* The rect of the ws (not used (yet)) */ 42 | struct i3_output *output; /* The current output of the ws */ 43 | 44 | TAILQ_ENTRY(i3_ws) tailq; /* Pointer for the TAILQ-Macro */ 45 | }; 46 | -------------------------------------------------------------------------------- /i3bar/include/xcb_atoms.def: -------------------------------------------------------------------------------- 1 | ATOM_DO(_NET_WM_WINDOW_TYPE) 2 | ATOM_DO(_NET_WM_WINDOW_TYPE_DOCK) 3 | ATOM_DO(_NET_WM_STRUT_PARTIAL) 4 | ATOM_DO(I3_SOCKET_PATH) 5 | ATOM_DO(MANAGER) 6 | ATOM_DO(_NET_SYSTEM_TRAY_ORIENTATION) 7 | ATOM_DO(_NET_SYSTEM_TRAY_VISUAL) 8 | ATOM_DO(_NET_SYSTEM_TRAY_OPCODE) 9 | ATOM_DO(_NET_SYSTEM_TRAY_COLORS) 10 | ATOM_DO(_XEMBED_INFO) 11 | ATOM_DO(_XEMBED) 12 | ATOM_DO(I3_SYNC) 13 | #undef ATOM_DO 14 | -------------------------------------------------------------------------------- /include/assignments.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * assignments.c: Assignments for specific windows (for_window). 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * Checks the list of assignments for the given window and runs all matching 16 | * ones (unless they have already been run for this specific window). 17 | * 18 | */ 19 | void run_assignments(i3Window *window); 20 | 21 | /** 22 | * Returns the first matching assignment for the given window. 23 | * 24 | */ 25 | Assignment *assignment_for(i3Window *window, int type); 26 | -------------------------------------------------------------------------------- /include/click.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * click.c: Button press (mouse click) events. 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * The button press X callback. This function determines whether the floating 16 | * modifier is pressed and where the user clicked (decoration, border, inside 17 | * the window). 18 | * 19 | * Then, route_click is called on the appropriate con. 20 | * 21 | */ 22 | void handle_button_press(xcb_button_press_event_t *event); 23 | -------------------------------------------------------------------------------- /include/display_version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * display_version.c: displays the running i3 version, runs as part of 8 | * i3 --moreversion. 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * Connects to i3 to find out the currently running version. Useful since it 16 | * might be different from the version compiled into this binary (maybe the 17 | * user didn’t correctly install i3 or forgot to restart it). 18 | * 19 | * The output looks like this: 20 | * Running i3 version: 4.2-202-gb8e782c (2012-08-12, branch "next") (pid 14804) 21 | * 22 | * The i3 binary you just called: /home/michael/i3/i3 23 | * The i3 binary you are running: /home/michael/i3/i3 24 | * 25 | */ 26 | void display_running_version(void); 27 | -------------------------------------------------------------------------------- /include/fake_outputs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * Faking outputs is useful in pathological situations (like network X servers 8 | * which don’t support multi-monitor in a useful way) and for our testsuite. 9 | * 10 | */ 11 | #pragma once 12 | 13 | #include 14 | 15 | /** 16 | * Creates outputs according to the given specification. 17 | * The specification must be in the format wxh+x+y, for example 1024x768+0+0, 18 | * with multiple outputs separated by commas: 19 | * 1900x1200+0+0,1280x1024+1900+0 20 | * 21 | */ 22 | void fake_outputs_init(const char *output_spec); 23 | -------------------------------------------------------------------------------- /include/handlers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * handlers.c: Small handlers for various events (keypresses, focus changes, 8 | * …). 9 | * 10 | */ 11 | #pragma once 12 | 13 | #include 14 | 15 | #include 16 | 17 | extern int randr_base; 18 | extern int xkb_base; 19 | extern int shape_base; 20 | 21 | /** 22 | * Adds the given sequence to the list of events which are ignored. 23 | * If this ignore should only affect a specific response_type, pass 24 | * response_type, otherwise, pass -1. 25 | * 26 | * Every ignored sequence number gets garbage collected after 5 seconds. 27 | * 28 | */ 29 | void add_ignore_event(const int sequence, const int response_type); 30 | 31 | /** 32 | * Checks if the given sequence is ignored and returns true if so. 33 | * 34 | */ 35 | bool event_is_ignored(const int sequence, const int response_type); 36 | 37 | /** 38 | * Takes an xcb_generic_event_t and calls the appropriate handler, based on the 39 | * event type. 40 | * 41 | */ 42 | void handle_event(int type, xcb_generic_event_t *event); 43 | 44 | /** 45 | * Sets the appropriate atoms for the property handlers after the atoms were 46 | * received from X11 47 | * 48 | */ 49 | void property_handlers_init(void); 50 | -------------------------------------------------------------------------------- /include/i3-atoms_NET_SUPPORTED.xmacro.h: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | #define I3_NET_SUPPORTED_ATOMS_XMACRO \ 3 | xmacro(_NET_SUPPORTED) \ 4 | xmacro(_NET_SUPPORTING_WM_CHECK) \ 5 | xmacro(_NET_WM_NAME) \ 6 | xmacro(_NET_WM_VISIBLE_NAME) \ 7 | xmacro(_NET_WM_MOVERESIZE) \ 8 | xmacro(_NET_WM_STATE_STICKY) \ 9 | xmacro(_NET_WM_STATE_FULLSCREEN) \ 10 | xmacro(_NET_WM_STATE_DEMANDS_ATTENTION) \ 11 | xmacro(_NET_WM_STATE_MODAL) \ 12 | xmacro(_NET_WM_STATE_HIDDEN) \ 13 | xmacro(_NET_WM_STATE_FOCUSED) \ 14 | xmacro(_NET_WM_STATE) \ 15 | xmacro(_NET_WM_WINDOW_TYPE) \ 16 | xmacro(_NET_WM_WINDOW_TYPE_NORMAL) \ 17 | xmacro(_NET_WM_WINDOW_TYPE_DOCK) \ 18 | xmacro(_NET_WM_WINDOW_TYPE_DIALOG) \ 19 | xmacro(_NET_WM_WINDOW_TYPE_UTILITY) \ 20 | xmacro(_NET_WM_WINDOW_TYPE_TOOLBAR) \ 21 | xmacro(_NET_WM_WINDOW_TYPE_SPLASH) \ 22 | xmacro(_NET_WM_WINDOW_TYPE_MENU) \ 23 | xmacro(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU) \ 24 | xmacro(_NET_WM_WINDOW_TYPE_POPUP_MENU) \ 25 | xmacro(_NET_WM_WINDOW_TYPE_TOOLTIP) \ 26 | xmacro(_NET_WM_WINDOW_TYPE_NOTIFICATION) \ 27 | xmacro(_NET_WM_DESKTOP) \ 28 | xmacro(_NET_WM_STRUT_PARTIAL) \ 29 | xmacro(_NET_CLIENT_LIST) \ 30 | xmacro(_NET_CLIENT_LIST_STACKING) \ 31 | xmacro(_NET_CURRENT_DESKTOP) \ 32 | xmacro(_NET_NUMBER_OF_DESKTOPS) \ 33 | xmacro(_NET_DESKTOP_NAMES) \ 34 | xmacro(_NET_DESKTOP_VIEWPORT) \ 35 | xmacro(_NET_ACTIVE_WINDOW) \ 36 | xmacro(_NET_CLOSE_WINDOW) \ 37 | xmacro(_NET_MOVERESIZE_WINDOW) 38 | -------------------------------------------------------------------------------- /include/i3-atoms_rest.xmacro.h: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | #define I3_REST_ATOMS_XMACRO \ 3 | xmacro(_NET_WM_USER_TIME) \ 4 | xmacro(_NET_STARTUP_ID) \ 5 | xmacro(_NET_WORKAREA) \ 6 | xmacro(_NET_WM_ICON) \ 7 | xmacro(WM_PROTOCOLS) \ 8 | xmacro(WM_DELETE_WINDOW) \ 9 | xmacro(UTF8_STRING) \ 10 | xmacro(WM_STATE) \ 11 | xmacro(WM_CLIENT_LEADER) \ 12 | xmacro(WM_TAKE_FOCUS) \ 13 | xmacro(WM_WINDOW_ROLE) \ 14 | xmacro(I3_SOCKET_PATH) \ 15 | xmacro(I3_CONFIG_PATH) \ 16 | xmacro(I3_SYNC) \ 17 | xmacro(I3_SHMLOG_PATH) \ 18 | xmacro(I3_PID) \ 19 | xmacro(I3_LOG_STREAM_SOCKET_PATH) \ 20 | xmacro(I3_FLOATING_WINDOW) \ 21 | xmacro(_NET_REQUEST_FRAME_EXTENTS) \ 22 | xmacro(_NET_FRAME_EXTENTS) \ 23 | xmacro(_MOTIF_WM_HINTS) \ 24 | xmacro(WM_CHANGE_STATE) \ 25 | xmacro(MANAGER) 26 | -------------------------------------------------------------------------------- /include/key_press.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * key_press.c: key press handler 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * There was a key press. We compare this key code with our bindings table and pass 16 | * the bound action to parse_command(). 17 | * 18 | */ 19 | void handle_key_press(xcb_key_press_event_t *event); 20 | 21 | /** 22 | * Kills the commanderror i3-nagbar process, if any. 23 | * 24 | * Called when reloading/restarting, since the user probably fixed their wrong 25 | * keybindings. 26 | * 27 | * If wait_for_it is set (restarting), this function will waitpid(), otherwise, 28 | * ev is assumed to handle it (reloading). 29 | * 30 | */ 31 | void kill_commanderror_nagbar(bool wait_for_it); 32 | -------------------------------------------------------------------------------- /include/load_layout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * load_layout.c: Restore (parts of) the layout, for example after an inplace 8 | * restart. 9 | * 10 | */ 11 | #pragma once 12 | 13 | #include 14 | 15 | typedef enum { 16 | // We could not determine the content of the JSON file. This typically 17 | // means it’s unreadable or contains garbage. 18 | JSON_CONTENT_UNKNOWN = 0, 19 | 20 | // The JSON file contains a “normal” container, i.e. a container to be 21 | // appended to an existing workspace (or split container!). 22 | JSON_CONTENT_CON = 1, 23 | 24 | // The JSON file contains a workspace container, which needs to be appended 25 | // to the output (next to the other workspaces) with special care to avoid 26 | // naming conflicts and ensuring that the workspace _has_ a name. 27 | JSON_CONTENT_WORKSPACE = 2, 28 | } json_content_t; 29 | 30 | /* Parses the given JSON file until it encounters the first “type” property to 31 | * determine whether the file contains workspaces or regular containers, which 32 | * is important to know when deciding where (and how) to append the contents. 33 | * */ 34 | json_content_t json_determine_content(const char *buf, const size_t len); 35 | 36 | /** 37 | * Returns true if the provided JSON could be parsed by yajl. 38 | * 39 | */ 40 | bool json_validate(const char *buf, const size_t len); 41 | 42 | void tree_append_json(Con *con, const char *buf, const size_t len, char **errormsg); 43 | -------------------------------------------------------------------------------- /include/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * main.c: Initialization, main loop 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * Enable or disable the main X11 event handling function. 16 | * This is used by drag_pointer() which has its own, modal event handler, which 17 | * takes precedence over the normal event handler. 18 | * 19 | */ 20 | void main_set_x11_cb(bool enable); 21 | -------------------------------------------------------------------------------- /include/manage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * manage.c: Initially managing new windows (or existing ones on restart). 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "data.h" 15 | 16 | /** 17 | * Go through all existing windows (if the window manager is restarted) and 18 | * manage them 19 | * 20 | */ 21 | void manage_existing_windows(xcb_window_t root); 22 | 23 | /** 24 | * Restores the geometry of each window by reparenting it to the root window 25 | * at the position of its frame. 26 | * 27 | * This is to be called *only* before exiting/restarting i3 because of evil 28 | * side-effects which are to be expected when continuing to run i3. 29 | * 30 | */ 31 | void restore_geometry(void); 32 | 33 | /** 34 | * Do some sanity checks and then reparent the window. 35 | * 36 | */ 37 | void manage_window(xcb_window_t window, 38 | xcb_get_window_attributes_cookie_t cookie, 39 | bool needs_to_be_mapped); 40 | 41 | /** 42 | * Remanages a window: performs a swallow check and runs assignments. 43 | * Returns con for the window regardless if it updated. 44 | * 45 | */ 46 | Con *remanage_window(Con *con); 47 | -------------------------------------------------------------------------------- /include/move.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * move.c: Moving containers into some direction. 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * Moves the given container in the given direction 16 | * 17 | */ 18 | void tree_move(Con *con, direction_t direction); 19 | 20 | /** 21 | * This function detaches 'con' from its parent and inserts it either before or 22 | * after 'target'. 23 | * 24 | */ 25 | void insert_con_into(Con *con, Con *target, position_t position); 26 | -------------------------------------------------------------------------------- /include/output.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * output.c: Output (monitor) related functions. 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * Returns the output container below the given output container. 16 | * 17 | */ 18 | Con *output_get_content(Con *output); 19 | 20 | /** 21 | * Returns an 'output' corresponding to one of left/right/down/up or a specific 22 | * output name. 23 | * 24 | */ 25 | Output *get_output_from_string(Output *current_output, const char *output_str); 26 | 27 | /** 28 | * Retrieves the primary name of an output. 29 | * 30 | */ 31 | char *output_primary_name(Output *output); 32 | 33 | /** 34 | * Returns the output for the given con. 35 | * 36 | */ 37 | Output *get_output_for_con(Con *con); 38 | 39 | /** 40 | * Iterates over all outputs and pushes sticky windows to the currently visible 41 | * workspace on that output. 42 | * 43 | * old_focus is used to determine if a sticky window is going to be focused. 44 | * old_focus might be different than the currently focused container because the 45 | * caller might need to temporarily change the focus and then call 46 | * output_push_sticky_windows. For example, workspace_show needs to set focus to 47 | * one of its descendants first, then call output_push_sticky_windows that 48 | * should focus a sticky window if it was the focused in the previous workspace. 49 | * 50 | */ 51 | void output_push_sticky_windows(Con *old_focus); 52 | -------------------------------------------------------------------------------- /include/regex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * regex.c: Interface to libPCRE (perl compatible regular expressions). 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * Creates a new 'regex' struct containing the given pattern and a PCRE 16 | * compiled regular expression. Also, calls pcre_study because this regex will 17 | * most likely be used often (like for every new window and on every relevant 18 | * property change of existing windows). 19 | * 20 | * Returns NULL if the pattern could not be compiled into a regular expression 21 | * (and ELOGs an appropriate error message). 22 | * 23 | */ 24 | struct regex *regex_new(const char *pattern); 25 | 26 | /** 27 | * Frees the given regular expression. It must not be used afterwards! 28 | * 29 | */ 30 | void regex_free(struct regex *regex); 31 | 32 | /** 33 | * Checks if the given regular expression matches the given input and returns 34 | * true if it does. In either case, it logs the outcome using LOG(), so it will 35 | * be visible without debug logging. 36 | * 37 | */ 38 | bool regex_matches(struct regex *regex, const char *input); 39 | -------------------------------------------------------------------------------- /include/render.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * render.c: Renders (determines position/sizes) the layout tree, updating the 8 | * various rects. Needs to be pushed to X11 (see x.c) to be visible. 9 | * 10 | */ 11 | #pragma once 12 | 13 | #include 14 | 15 | /** 16 | * This is used to keep a state to pass around when rendering a con in render_con(). 17 | * 18 | */ 19 | typedef struct render_params { 20 | /* A copy of the coordinates of the container which is being rendered. */ 21 | int x; 22 | int y; 23 | 24 | /* The computed height for decorations. */ 25 | int deco_height; 26 | /* Container rect, subtract container border. This is the actually usable space 27 | * inside this container for clients. */ 28 | Rect rect; 29 | /* The number of children of the container which is being rendered. */ 30 | int children; 31 | /* A precalculated list of sizes of each child. */ 32 | int *sizes; 33 | } render_params; 34 | 35 | /** 36 | * "Renders" the given container (and its children), meaning that all rects are 37 | * updated correctly. Note that this function does not call any xcb_* 38 | * functions, so the changes are completely done in memory only (and 39 | * side-effect free). As soon as you call x_push_changes(), the changes will be 40 | * updated in X11. 41 | * 42 | */ 43 | void render_con(Con *con, bool already_inset); 44 | 45 | /** 46 | * Returns the height for the decorations 47 | * 48 | */ 49 | int render_deco_height(void); 50 | -------------------------------------------------------------------------------- /include/resize.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * resize.c: Interactive resizing. 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | bool resize_find_tiling_participants(Con **current, Con **other, direction_t direction, bool both_sides); 15 | 16 | void resize_graphical_handler(Con *first, Con *second, orientation_t orientation, 17 | const xcb_button_press_event_t *event, 18 | bool use_threshold); 19 | 20 | /** 21 | * Resize the two given containers using the given amount of pixels or 22 | * percentage points. One of the two needs to be 0. A positive amount means 23 | * growing the first container while a negative means shrinking it. 24 | * Returns false when the resize would result in one of the two containers 25 | * having less than 1 pixel of size. 26 | * 27 | */ 28 | bool resize_neighboring_cons(Con *first, Con *second, int px, int ppt); 29 | 30 | /** 31 | * Calculate the minimum percent needed for the given container to be at least 1 32 | * pixel. 33 | * 34 | */ 35 | double percent_for_1px(Con *con); 36 | -------------------------------------------------------------------------------- /include/restore_layout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * restore_layout.c: Everything for restored containers that is not pure state 8 | * parsing (which can be found in load_layout.c). 9 | * 10 | */ 11 | #pragma once 12 | 13 | #include 14 | 15 | /** 16 | * Opens a separate connection to X11 for placeholder windows when restoring 17 | * layouts. This is done as a safety measure (users can xkill a placeholder 18 | * window without killing their window manager) and for better isolation, both 19 | * on the wire to X11 and thus also in the code. 20 | * 21 | */ 22 | void restore_connect(void); 23 | 24 | /** 25 | * Open placeholder windows for all children of parent. The placeholder window 26 | * will vanish as soon as a real window is swallowed by the container. Until 27 | * then, it exposes the criteria that must be fulfilled for a window to be 28 | * swallowed by this container. 29 | * 30 | */ 31 | void restore_open_placeholder_windows(Con *con); 32 | 33 | /** 34 | * Kill the placeholder window, if placeholder refers to a placeholder window. 35 | * This function is called when manage.c puts a window into an existing 36 | * container. In order not to leak resources, we need to destroy the window and 37 | * all associated X11 objects (pixmap/gc). 38 | * 39 | */ 40 | bool restore_kill_placeholder(xcb_window_t placeholder); 41 | -------------------------------------------------------------------------------- /include/scratchpad.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * scratchpad.c: Scratchpad functions (TODO: more description) 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | /** 15 | * Moves the specified window to the __i3_scratch workspace, making it floating 16 | * and setting the appropriate scratchpad_state. 17 | * 18 | * Gets called upon the command 'move scratchpad'. 19 | * 20 | */ 21 | void scratchpad_move(Con *con); 22 | 23 | /** 24 | * Either shows the top-most scratchpad window (con == NULL) or shows the 25 | * specified con (if it is scratchpad window). 26 | * 27 | * When called with con == NULL and the currently focused window is a 28 | * scratchpad window, this serves as a shortcut to hide it again (so the user 29 | * can press the same key to quickly look something up). 30 | * 31 | */ 32 | bool scratchpad_show(Con *con); 33 | 34 | /** 35 | * When starting i3 initially (and after each change to the connected outputs), 36 | * this function fixes the resolution of the __i3 pseudo-output. When that 37 | * resolution is not set to a function which shares a common divisor with every 38 | * active output’s resolution, floating point calculation errors will lead to 39 | * the scratchpad window moving when shown repeatedly. 40 | * 41 | */ 42 | void scratchpad_fix_resolution(void); 43 | -------------------------------------------------------------------------------- /include/shmlog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * The format of the shmlog data structure which i3 development versions use by 8 | * default (ringbuffer for storing the debug log). 9 | * 10 | */ 11 | #pragma once 12 | 13 | #include 14 | 15 | /* Default shmlog size if not set by user. */ 16 | extern const int default_shmlog_size; 17 | 18 | /** 19 | * Header of the shmlog file. Used by i3/src/log.c and i3/i3-dump-log/main.c. 20 | * 21 | */ 22 | typedef struct i3_shmlog_header { 23 | /* Byte offset where the next line will be written to. */ 24 | uint32_t offset_next_write; 25 | 26 | /* Byte offset where the last wrap occurred. */ 27 | uint32_t offset_last_wrap; 28 | 29 | /* The size of the logfile in bytes. Since the size is limited to 25 MiB 30 | * an uint32_t is sufficient. */ 31 | uint32_t size; 32 | 33 | /* wrap counter. We need it to reliably signal to clients that we just 34 | * wrapped (clients cannot use offset_last_wrap because that might 35 | * coincidentally be exactly the same as previously). Overflows can happen 36 | * and don’t matter — clients use an equality check (==). */ 37 | uint32_t wrap_count; 38 | } i3_shmlog_header; 39 | -------------------------------------------------------------------------------- /include/sighandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #pragma once 9 | 10 | #include 11 | 12 | /** 13 | * Configured a signal handler to gracefully handle crashes and allow the user 14 | * to generate a backtrace and rescue their session. 15 | * 16 | */ 17 | void setup_signal_handler(void); 18 | -------------------------------------------------------------------------------- /include/sync.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * sync.c: i3 sync protocol: https://i3wm.org/docs/testsuite.html#i3_sync 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | void sync_respond(xcb_window_t window, uint32_t rnd); 15 | -------------------------------------------------------------------------------- /include/tiling_drag.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * tiling_drag.h: Reposition tiled windows by dragging. 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include "all.h" 13 | 14 | /** 15 | * Tiling drag initiation modes. 16 | */ 17 | typedef enum { 18 | TILING_DRAG_OFF = 0, 19 | TILING_DRAG_MODIFIER = 1, 20 | TILING_DRAG_TITLEBAR = 2, 21 | TILING_DRAG_MODIFIER_OR_TITLEBAR = 3 22 | } tiling_drag_t; 23 | 24 | /** 25 | * Returns whether there currently are any drop targets. 26 | * Used to only initiate a drag when there is something to drop onto. 27 | * 28 | */ 29 | bool has_drop_targets(void); 30 | 31 | /** 32 | * Initiates a mouse drag operation on a tiled window. 33 | * 34 | */ 35 | void tiling_drag(Con *con, xcb_button_press_event_t *event, bool use_threshold); 36 | -------------------------------------------------------------------------------- /include/xcursor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * xcursor.c: libXcursor support for themed cursors. 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | #include 15 | 16 | enum xcursor_cursor_t { 17 | XCURSOR_CURSOR_POINTER = 0, 18 | XCURSOR_CURSOR_RESIZE_HORIZONTAL, 19 | XCURSOR_CURSOR_RESIZE_VERTICAL, 20 | XCURSOR_CURSOR_TOP_LEFT_CORNER, 21 | XCURSOR_CURSOR_TOP_RIGHT_CORNER, 22 | XCURSOR_CURSOR_BOTTOM_LEFT_CORNER, 23 | XCURSOR_CURSOR_BOTTOM_RIGHT_CORNER, 24 | XCURSOR_CURSOR_WATCH, 25 | XCURSOR_CURSOR_MOVE, 26 | XCURSOR_CURSOR_MAX 27 | }; 28 | 29 | void xcursor_load_cursors(void); 30 | xcb_cursor_t xcursor_get_cursor(enum xcursor_cursor_t c); 31 | 32 | /** 33 | * Sets the cursor of the root window to the 'pointer' cursor. 34 | * 35 | * This function is called when i3 is initialized, because with some login 36 | * managers, the root window will not have a cursor otherwise. 37 | * 38 | * We have a separate xcursor function to use the same X11 connection as the 39 | * xcursor_load_cursors() function. If we mix the Xlib and the XCB connection, 40 | * races might occur (even though we flush the Xlib connection). 41 | * 42 | */ 43 | void xcursor_set_root_cursor(int cursor_id); 44 | -------------------------------------------------------------------------------- /include/xinerama.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * This is LEGACY code (we support RandR, which can do much more than 8 | * Xinerama), but necessary for the poor users of the nVidia binary 9 | * driver which does not support RandR in 2011 *sigh*. 10 | * 11 | */ 12 | #pragma once 13 | 14 | #include 15 | 16 | /** 17 | * We have just established a connection to the X server and need the initial 18 | * Xinerama information to setup workspaces for each screen. 19 | * 20 | */ 21 | void xinerama_init(void); 22 | -------------------------------------------------------------------------------- /include/yajl_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * yajl_utils.h 8 | * 9 | */ 10 | #pragma once 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | /* Shorter names for all those yajl_gen_* functions */ 19 | #define y(x, ...) yajl_gen_##x(gen, ##__VA_ARGS__) 20 | #define ystr(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str)) 21 | 22 | #define ygenalloc() yajl_gen_alloc(NULL) 23 | #define yalloc(callbacks, client) yajl_alloc(callbacks, NULL, client) 24 | typedef size_t ylength; 25 | -------------------------------------------------------------------------------- /libi3/README: -------------------------------------------------------------------------------- 1 | Introduction 2 | ============ 3 | 4 | libi3 is an *INTERNAL* library which contains functions that i3 and related 5 | tools (i3-msg, i3-input, i3-nagbar, i3-config-wizard, i3bar) use. 6 | 7 | It is NOT to be used by other programs. 8 | 9 | Structure 10 | ========= 11 | 12 | Every function gets its own .c file, which in turn gets compiled into an .o 13 | object file. Afterwards, all .o files are archived into one static library 14 | (libi3.a). This library will be linked into all i3 binaries. The linker is able 15 | to eliminate unused .o files when linking, so only the functions which you 16 | actually use will be included in the corresponding binary. 17 | -------------------------------------------------------------------------------- /libi3/boolstr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | /* 15 | * Reports whether str represents the enabled state (1, yes, true, …). 16 | * 17 | */ 18 | bool boolstr(const char *str) { 19 | return (strcasecmp(str, "1") == 0 || 20 | strcasecmp(str, "yes") == 0 || 21 | strcasecmp(str, "true") == 0 || 22 | strcasecmp(str, "on") == 0 || 23 | strcasecmp(str, "enable") == 0 || 24 | strcasecmp(str, "active") == 0); 25 | } 26 | -------------------------------------------------------------------------------- /libi3/get_visualtype.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | /* 11 | * Returns the visual type associated with the given screen. 12 | * 13 | */ 14 | xcb_visualtype_t *get_visualtype(xcb_screen_t *screen) { 15 | xcb_depth_iterator_t depth_iter; 16 | for (depth_iter = xcb_screen_allowed_depths_iterator(screen); 17 | depth_iter.rem; 18 | xcb_depth_next(&depth_iter)) { 19 | xcb_visualtype_iterator_t visual_iter; 20 | for (visual_iter = xcb_depth_visuals_iterator(depth_iter.data); 21 | visual_iter.rem; 22 | xcb_visualtype_next(&visual_iter)) { 23 | if (screen->root_visual == visual_iter.data->visual_id) 24 | return visual_iter.data; 25 | } 26 | } 27 | return NULL; 28 | } 29 | -------------------------------------------------------------------------------- /libi3/ipc_send_message.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | #include 11 | #include 12 | 13 | /* 14 | * Formats a message (payload) of the given size and type and sends it to i3 via 15 | * the given socket file descriptor. 16 | * 17 | * Returns -1 when write() fails, errno will remain. 18 | * Returns 0 on success. 19 | * 20 | */ 21 | int ipc_send_message(int sockfd, const uint32_t message_size, 22 | const uint32_t message_type, const uint8_t *payload) { 23 | const i3_ipc_header_t header = { 24 | /* We don’t use I3_IPC_MAGIC because it’s a 0-terminated C string. */ 25 | .magic = {'i', '3', '-', 'i', 'p', 'c'}, 26 | .size = message_size, 27 | .type = message_type}; 28 | 29 | if (writeall(sockfd, ((void *)&header), sizeof(i3_ipc_header_t)) == -1) 30 | return -1; 31 | 32 | if (writeall(sockfd, payload, message_size) == -1) 33 | return -1; 34 | 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /libi3/is_debug_build.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | #include 11 | 12 | /* 13 | * Returns true if this version of i3 is a debug build (anything which is not a 14 | * release version), based on the git version number. 15 | * 16 | */ 17 | bool is_debug_build(void) { 18 | /* i3_version contains either something like this: 19 | * "4.0.2 (2011-11-11)" (release version) 20 | * or: "4.0.2-123-gC0FFEE" (debug version) 21 | * 22 | * So we check for the offset of the first opening round bracket to 23 | * determine whether this is a git version or a release version. */ 24 | if (strchr(I3_VERSION, '(') == NULL) { 25 | return true; // e.g. 4.0.2-123-gC0FFEE 26 | } 27 | /* In practice, debug versions do not contain parentheses at all, 28 | * but leave the logic as it was before so that we can re-add 29 | * parentheses if we chose to. */ 30 | return ((strchr(I3_VERSION, '(') - I3_VERSION) > 10); 31 | } 32 | -------------------------------------------------------------------------------- /libi3/mkdirp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifndef HAVE_MKDIRP 16 | /* 17 | * Emulates mkdir -p (creates any missing folders) 18 | * 19 | */ 20 | int mkdirp(const char *path, mode_t mode) { 21 | if (mkdir(path, mode) == 0) 22 | return 0; 23 | if (errno == EEXIST) { 24 | struct stat st; 25 | /* Check that the named file actually is a directory. */ 26 | if (stat(path, &st)) { 27 | ELOG("stat(%s) failed: %s\n", path, strerror(errno)); 28 | return -1; 29 | } 30 | if (!S_ISDIR(st.st_mode)) { 31 | ELOG("mkdir(%s) failed: %s\n", path, strerror(ENOTDIR)); 32 | return -1; 33 | } 34 | return 0; 35 | } else if (errno != ENOENT) { 36 | ELOG("mkdir(%s) failed: %s\n", path, strerror(errno)); 37 | return -1; 38 | } 39 | char *copy = sstrdup(path); 40 | /* strip trailing slashes, if any */ 41 | while (copy[strlen(copy) - 1] == '/') 42 | copy[strlen(copy) - 1] = '\0'; 43 | 44 | char *sep = strrchr(copy, '/'); 45 | if (sep == NULL) { 46 | free(copy); 47 | return -1; 48 | } 49 | *sep = '\0'; 50 | int result = -1; 51 | if (mkdirp(copy, mode) == 0) 52 | result = mkdirp(path, mode); 53 | free(copy); 54 | 55 | return result; 56 | } 57 | #endif 58 | -------------------------------------------------------------------------------- /libi3/nonblock.c: -------------------------------------------------------------------------------- 1 | #include "libi3.h" 2 | 3 | #include 4 | #include 5 | 6 | /* 7 | * Puts the given socket file descriptor into non-blocking mode or dies if 8 | * setting O_NONBLOCK failed. Non-blocking sockets are a good idea for our 9 | * IPC model because we should by no means block the window manager. 10 | * 11 | */ 12 | void set_nonblock(int sockfd) { 13 | int flags = fcntl(sockfd, F_GETFL, 0); 14 | if (flags & O_NONBLOCK) { 15 | return; 16 | } 17 | flags |= O_NONBLOCK; 18 | if (fcntl(sockfd, F_SETFL, flags) < 0) { 19 | err(-1, "Could not set O_NONBLOCK"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /libi3/path_exists.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | /* 15 | * Checks if the given path exists by calling stat(). 16 | * 17 | */ 18 | bool path_exists(const char *path) { 19 | struct stat buf; 20 | return (stat(path, &buf) == 0); 21 | } 22 | -------------------------------------------------------------------------------- /libi3/resolve_tilde.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /* 16 | * This function resolves ~ in pathnames. 17 | * It may resolve wildcards in the first part of the path, but if no match 18 | * or multiple matches are found, it just returns a copy of path as given. 19 | * 20 | */ 21 | char *resolve_tilde(const char *path) { 22 | static glob_t globbuf; 23 | char *head, *tail, *result; 24 | 25 | tail = strchr(path, '/'); 26 | head = sstrndup(path, tail ? (size_t)(tail - path) : strlen(path)); 27 | 28 | int res = glob(head, GLOB_TILDE, NULL, &globbuf); 29 | free(head); 30 | /* no match, or many wildcard matches are bad */ 31 | if (res == GLOB_NOMATCH || globbuf.gl_pathc != 1) 32 | result = sstrdup(path); 33 | else if (res != 0) { 34 | err(EXIT_FAILURE, "glob() failed"); 35 | } else { 36 | head = globbuf.gl_pathv[0]; 37 | result = scalloc(strlen(head) + (tail ? strlen(tail) : 0) + 1, 1); 38 | strcpy(result, head); 39 | if (tail) { 40 | strcat(result, tail); 41 | } 42 | } 43 | globfree(&globbuf); 44 | 45 | return result; 46 | } 47 | -------------------------------------------------------------------------------- /libi3/screenshot_wallpaper.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | void set_screenshot_as_wallpaper(xcb_connection_t *conn, xcb_screen_t *screen) { 11 | uint16_t width = screen->width_in_pixels; 12 | uint16_t height = screen->height_in_pixels; 13 | xcb_pixmap_t pixmap = xcb_generate_id(conn); 14 | xcb_gcontext_t gc = xcb_generate_id(conn); 15 | 16 | xcb_create_pixmap(conn, screen->root_depth, pixmap, screen->root, width, height); 17 | 18 | xcb_create_gc(conn, gc, screen->root, 19 | XCB_GC_FUNCTION | XCB_GC_PLANE_MASK | XCB_GC_FILL_STYLE | XCB_GC_SUBWINDOW_MODE, 20 | (uint32_t[]){XCB_GX_COPY, ~0, XCB_FILL_STYLE_SOLID, XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS}); 21 | 22 | xcb_copy_area(conn, screen->root, pixmap, gc, 0, 0, 0, 0, width, height); 23 | xcb_change_window_attributes(conn, screen->root, XCB_CW_BACK_PIXMAP, (uint32_t[]){pixmap}); 24 | xcb_free_gc(conn, gc); 25 | xcb_free_pixmap(conn, pixmap); 26 | xcb_flush(conn); 27 | } 28 | -------------------------------------------------------------------------------- /libi3/strndup.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | */ 8 | #include "libi3.h" 9 | 10 | #include 11 | 12 | #ifndef HAVE_STRNDUP 13 | /* 14 | * Taken from FreeBSD 15 | * Returns a pointer to a new string which is a duplicate of the 16 | * string, but only copies at most n characters. 17 | * 18 | */ 19 | char *strndup(const char *str, size_t n) { 20 | size_t len; 21 | char *copy; 22 | 23 | for (len = 0; len < n && str[len]; len++) 24 | continue; 25 | 26 | copy = smalloc(len + 1); 27 | memcpy(copy, str, len); 28 | copy[len] = '\0'; 29 | return (copy); 30 | } 31 | #endif 32 | -------------------------------------------------------------------------------- /man/asciidoc.conf.in: -------------------------------------------------------------------------------- 1 | ifdef::doctype-manpage[] 2 | ifdef::backend-docbook[] 3 | [header] 4 | template::[header-declarations] 5 | 6 | 7 | {mantitle} 8 | {manvolnum} 9 | i3 10 | @PACKAGE_VERSION@ 11 | i3 Manual 12 | 13 | 14 | {manname} 15 | {manpurpose} 16 | 17 | endif::backend-docbook[] 18 | endif::doctype-manpage[] 19 | -------------------------------------------------------------------------------- /man/i3-dump-log.man: -------------------------------------------------------------------------------- 1 | i3-dump-log(1) 2 | ============== 3 | Michael Stapelberg 4 | v4.6, September 2013 5 | 6 | == NAME 7 | 8 | i3-dump-log - dumps the i3 SHM log 9 | 10 | == SYNOPSIS 11 | 12 | i3-dump-log [-s ] [-f] 13 | 14 | == DESCRIPTION 15 | 16 | Debug versions of i3 automatically use 1% of your RAM (but 25 MiB max) to store 17 | full debug log output. This is extremely helpful for bugreports and 18 | figuring out what is going on, without permanently logging to a file. 19 | 20 | With i3-dump-log, you can dump the SHM log to stdout. 21 | 22 | The -f flag works like tail -f, i.e. the process does not terminate after 23 | dumping the log, but prints new lines as they appear. 24 | 25 | == EXAMPLE 26 | 27 | i3-dump-log | gzip -9 > /tmp/i3-log.gz 28 | 29 | == SEE ALSO 30 | 31 | i3(1) 32 | 33 | == AUTHOR 34 | 35 | Michael Stapelberg and contributors 36 | -------------------------------------------------------------------------------- /man/i3-migrate-config-to-v4.man: -------------------------------------------------------------------------------- 1 | i3-migrate-config-to-v4(1) 2 | ========================== 3 | Michael Stapelberg 4 | v4.0, July 2011 5 | 6 | == NAME 7 | 8 | i3-migrate-config-to-v4 - migrates your i3 config file 9 | 10 | == SYNOPSIS 11 | 12 | ------------------------------------------------------- 13 | mv ~/.i3/config ~/.i3/old.config 14 | i3-migrate-config-to-v4 ~/.i3/old.config > ~/.i3/config 15 | ------------------------------------------------------- 16 | 17 | == DESCRIPTION 18 | 19 | i3-migrate-config-to-v4 is a Perl script which migrates your old (< version 4) 20 | configuration files to a version 4 config file. The most significant changes 21 | are the new commands (see the release notes). 22 | 23 | This script will automatically be run by i3 when it detects an old config file. 24 | Please migrate your config file as soon as possible. We plan to include this 25 | script in all i3 release until 2012-08-01. Afterwards, old config files will no 26 | longer be supported. 27 | 28 | == SEE ALSO 29 | 30 | i3(1) 31 | 32 | == AUTHOR 33 | 34 | Michael Stapelberg and contributors 35 | -------------------------------------------------------------------------------- /man/i3-sensible-editor.man: -------------------------------------------------------------------------------- 1 | i3-sensible-editor(1) 2 | ===================== 3 | Michael Stapelberg 4 | v4.1, November 2011 5 | 6 | == NAME 7 | 8 | i3-sensible-editor - launches $EDITOR with fallbacks 9 | 10 | == SYNOPSIS 11 | 12 | i3-sensible-editor [arguments] 13 | 14 | == DESCRIPTION 15 | 16 | i3-sensible-editor is used by i3-nagbar(1) when you click on the edit button. 17 | 18 | It tries to start one of the following (in that order): 19 | 20 | * $VISUAL 21 | * $EDITOR 22 | * nano 23 | * nvim 24 | * vim 25 | * vi 26 | * emacs 27 | * pico 28 | * qe 29 | * mg 30 | * jed 31 | * gedit 32 | * mcedit 33 | * gvim 34 | 35 | Please don’t complain about the order: If the user has any preference, they will 36 | have $VISUAL or $EDITOR set. 37 | 38 | == SEE ALSO 39 | 40 | i3(1) 41 | 42 | == AUTHOR 43 | 44 | Michael Stapelberg and contributors 45 | -------------------------------------------------------------------------------- /man/i3-sensible-pager.man: -------------------------------------------------------------------------------- 1 | i3-sensible-pager(1) 2 | ==================== 3 | Michael Stapelberg 4 | v4.1, November 2011 5 | 6 | == NAME 7 | 8 | i3-sensible-pager - launches $PAGER with fallbacks 9 | 10 | == SYNOPSIS 11 | 12 | i3-sensible-pager [arguments] 13 | 14 | == DESCRIPTION 15 | 16 | i3-sensible-pager is used by i3-nagbar(1) when you click on the view button. 17 | 18 | It tries to start one of the following (in that order): 19 | 20 | * $PAGER 21 | * less 22 | * most 23 | * w3m 24 | * i3-sensible-editor(1) 25 | 26 | Please don’t complain about the order: If the user has any preference, they will 27 | have $PAGER set. 28 | 29 | == SEE ALSO 30 | 31 | i3(1) 32 | 33 | == AUTHOR 34 | 35 | Michael Stapelberg and contributors 36 | -------------------------------------------------------------------------------- /man/i3-sensible-terminal.man: -------------------------------------------------------------------------------- 1 | i3-sensible-terminal(1) 2 | ======================= 3 | Michael Stapelberg 4 | v4.2, August 2012 5 | 6 | == NAME 7 | 8 | i3-sensible-terminal - launches $TERMINAL with fallbacks 9 | 10 | == SYNOPSIS 11 | 12 | i3-sensible-terminal [arguments] 13 | 14 | == DESCRIPTION 15 | 16 | i3-sensible-terminal is invoked in the i3 default config to start a terminal. 17 | This wrapper script is necessary since there is no distribution-independent 18 | terminal launcher (but for example Debian has x-terminal-emulator). 19 | Distribution packagers are responsible for shipping this script in a way which 20 | is appropriate for the distribution. 21 | 22 | It tries to start one of the following (in that order): 23 | 24 | * $TERMINAL (this is a non-standard variable) 25 | * x-terminal-emulator (only present on Debian and derivatives) 26 | * mate-terminal 27 | * gnome-terminal 28 | * terminator 29 | * xfce4-terminal 30 | * urxvt 31 | * rxvt 32 | * termit 33 | * Eterm 34 | * aterm 35 | * uxterm 36 | * xterm 37 | * roxterm 38 | * termite 39 | * lxterminal 40 | * terminology 41 | * st 42 | * qterminal 43 | * lilyterm 44 | * tilix 45 | * terminix 46 | * konsole 47 | * kitty 48 | * guake 49 | * tilda 50 | * alacritty 51 | * hyper 52 | 53 | Please don’t complain about the order: If the user has any preference, they will 54 | have $TERMINAL set or modified their i3 configuration file. 55 | 56 | == SEE ALSO 57 | 58 | i3(1) 59 | 60 | == AUTHOR 61 | 62 | Michael Stapelberg and contributors 63 | -------------------------------------------------------------------------------- /meson/meson-dist-script: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -eu 4 | 5 | cd "${MESON_DIST_ROOT}" 6 | 7 | # Delete everything we do not want to have in the release tarballs: 8 | rm -rf \ 9 | contrib/banner.svg \ 10 | contrib/show-download-count.sh \ 11 | contrib/sticker-7x5cm-stickma.tif.lzma \ 12 | contrib/sticker_stickma_black.svg \ 13 | debian/ \ 14 | docs/GPN-2009-06-27/ \ 15 | docs/NoName-2009-03-12/ \ 16 | docs/slides-2012-01-25/ \ 17 | docs/slides-2012-03-16/ \ 18 | testcases/.gitignore \ 19 | travis/ \ 20 | .clang-format \ 21 | .editorconfig \ 22 | i3bar/.gitignore \ 23 | .travis.yml \ 24 | logo.svg \ 25 | README.md \ 26 | RELEASE-NOTES-next \ 27 | release.sh 28 | 29 | mkdir build 30 | cd build 31 | meson .. -Dprefix=/usr -Ddocs=true -Dmans=true 32 | ninja 33 | cp *.1 ../man/ 34 | cp *.html ../docs/ 35 | cd .. 36 | rm -rf build 37 | -------------------------------------------------------------------------------- /meson/meson-install-i3-with-shmlog: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ln -sf "i3" "${MESON_INSTALL_DESTDIR_PREFIX}/$1/i3-with-shmlog" 3 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | # -*- mode: meson -*- 2 | 3 | option('docs', type: 'boolean', value: false, 4 | description: 'Build documentation from source (release tarballs contain a generated copy)') 5 | 6 | option('mans', type: 'boolean', value: false, 7 | description: 'Build manpages from source (release tarballs contain a generated copy)') 8 | 9 | option('docdir', type: 'string', value: '', 10 | description: 'documentation directory (default: $datadir/docs/i3)') 11 | -------------------------------------------------------------------------------- /parser-specs/highlighting.vim: -------------------------------------------------------------------------------- 1 | set filetype=i3cmd 2 | syntax case match 3 | syntax clear 4 | 5 | syntax keyword i3specStatement state call 6 | highlight link i3specStatement Statement 7 | 8 | syntax match i3specComment /#.*/ 9 | highlight link i3specComment Comment 10 | 11 | syntax region i3specLiteral start=/'/ end=/'/ 12 | syntax keyword i3specToken string word number end 13 | highlight link i3specLiteral String 14 | highlight link i3specToken String 15 | 16 | syntax match i3specState /[A-Z_]\{3,}/ 17 | highlight link i3specState PreProc 18 | 19 | syntax match i3specSpecial /[->]/ 20 | highlight link i3specSpecial Special 21 | -------------------------------------------------------------------------------- /release-notes/bugfixes/0-example: -------------------------------------------------------------------------------- 1 | fix crash with "layout default" 2 | -------------------------------------------------------------------------------- /release-notes/bugfixes/1-motifs: -------------------------------------------------------------------------------- 1 | motif hints: respect maximum border style configuration set by user 2 | -------------------------------------------------------------------------------- /release-notes/bugfixes/2-focus-click: -------------------------------------------------------------------------------- 1 | tiling drag: allow click immediately, to focus on decoration click 2 | -------------------------------------------------------------------------------- /release-notes/bugfixes/3-drag-cursor: -------------------------------------------------------------------------------- 1 | fix tiling drag cursor: should be “move”, accidentally was “top right corner” 2 | -------------------------------------------------------------------------------- /release-notes/bugfixes/4-drop-scratchpad: -------------------------------------------------------------------------------- 1 | tiling drag: ignore scratchpad windows when locating drop targets 2 | -------------------------------------------------------------------------------- /release-notes/changes/0-example: -------------------------------------------------------------------------------- 1 | Acquire the WM_Sn selection when starting as required by ICCCM 2 | -------------------------------------------------------------------------------- /release-notes/changes/1-tiling-drag: -------------------------------------------------------------------------------- 1 | tiling drag is now configurable, and defaults to “modifier” for existing configs 2 | -------------------------------------------------------------------------------- /release-notes/changes/2-tiling-drag-targets: -------------------------------------------------------------------------------- 1 | tiling drag: only initiate when there are drop targets 2 | -------------------------------------------------------------------------------- /share/applications/i3.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=i3 4 | NoDisplay=true 5 | GenericName=A dynamic tiling window manager 6 | Comment=improved dynamic tiling window manager 7 | Exec=i3 8 | X-GNOME-WMName=i3 9 | X-GNOME-Autostart-Phase=WindowManager 10 | X-GNOME-Provides=windowmanager 11 | X-GNOME-Autostart-Notify=false 12 | -------------------------------------------------------------------------------- /share/xsessions/i3-with-shmlog.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=i3 (with debug log) 3 | Comment=improved dynamic tiling window manager 4 | Exec=i3-with-shmlog 5 | Type=Application 6 | Keywords=tiling;wm;windowmanager;window;manager; 7 | -------------------------------------------------------------------------------- /share/xsessions/i3.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=i3 3 | Comment=improved dynamic tiling window manager 4 | Exec=i3 5 | TryExec=i3 6 | Type=Application 7 | X-LightDM-DesktopName=i3 8 | DesktopNames=i3 9 | Keywords=tiling;wm;windowmanager;window;manager; 10 | -------------------------------------------------------------------------------- /src/key_press.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * key_press.c: key press handler 8 | * 9 | */ 10 | #include "all.h" 11 | 12 | /* 13 | * There was a KeyPress or KeyRelease (both events have the same fields). We 14 | * compare this key code with our bindings table and pass the bound action to 15 | * parse_command(). 16 | * 17 | */ 18 | void handle_key_press(xcb_key_press_event_t *event) { 19 | const bool key_release = (event->response_type == XCB_KEY_RELEASE); 20 | 21 | last_timestamp = event->time; 22 | 23 | DLOG("%s %d, state raw = 0x%x\n", (key_release ? "KeyRelease" : "KeyPress"), event->detail, event->state); 24 | 25 | Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event); 26 | 27 | /* if we couldn't find a binding, we are done */ 28 | if (bind == NULL) 29 | return; 30 | 31 | CommandResult *result = run_binding(bind, NULL); 32 | command_result_free(result); 33 | } 34 | -------------------------------------------------------------------------------- /src/sync.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * sync.c: i3 sync protocol: https://i3wm.org/docs/testsuite.html#i3_sync 8 | * 9 | */ 10 | #include "all.h" 11 | 12 | void sync_respond(xcb_window_t window, uint32_t rnd) { 13 | DLOG("[i3 sync protocol] Sending random value %d back to X11 window 0x%08x\n", rnd, window); 14 | 15 | void *reply = scalloc(32, 1); 16 | xcb_client_message_event_t *ev = reply; 17 | 18 | ev->response_type = XCB_CLIENT_MESSAGE; 19 | ev->window = window; 20 | ev->type = A_I3_SYNC; 21 | ev->format = 32; 22 | ev->data.data32[0] = window; 23 | ev->data.data32[1] = rnd; 24 | 25 | xcb_send_event(conn, false, window, XCB_EVENT_MASK_NO_EVENT, (char *)ev); 26 | xcb_flush(conn); 27 | free(reply); 28 | } 29 | -------------------------------------------------------------------------------- /src/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * vim:ts=4:sw=4:expandtab 3 | * 4 | * i3 - an improved dynamic tiling window manager 5 | * © 2009 Michael Stapelberg and contributors (see also: LICENSE) 6 | * 7 | * Stores the latest Git commit identifier so that it can be linked into i3 8 | * and used dynamically without recompiling every object file. 9 | * 10 | */ 11 | #include 12 | 13 | const char *i3_version = I3_VERSION; 14 | -------------------------------------------------------------------------------- /testcases/.gitignore: -------------------------------------------------------------------------------- 1 | testsuite-* 2 | latest 3 | Makefile 4 | Makefile.old 5 | .last_run_timings.json 6 | _Inline 7 | inc 8 | META.yml 9 | i3-cfg-for-* 10 | - 11 | -------------------------------------------------------------------------------- /testcases/Makefile.PL: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # vim:ts=4:sw=4:expandtab 3 | use strict; use warnings; 4 | use ExtUtils::MakeMaker; 5 | 6 | WriteMakefile( 7 | NAME => 'i3-testsuite', 8 | MIN_PERL_VERSION => '5.010000', # 5.10.0 9 | PREREQ_PM => { 10 | 'AnyEvent' => 0, 11 | 'X11::XCB' => '0.12', 12 | 'Inline' => 0, 13 | 'Inline::C' => 0, 14 | 'ExtUtils::PkgConfig' => 0, 15 | 'Test::More' => '0.94', 16 | 'IPC::Run' => 0, 17 | }, 18 | PM => {}, # do not install any files from this directory 19 | clean => { 20 | FILES => 'testsuite-* latest i3-cfg-for-*', 21 | }, 22 | # This is a pure-Perl distribution: 23 | linkext => { 24 | LINKTYPE => '', 25 | }, 26 | ); 27 | 28 | package MY; 29 | sub test { } # do not run the tests while installing 30 | 31 | # do not rename the Makefile 32 | sub clean { 33 | my $section = shift->SUPER::clean(@_); 34 | $section =~ s/^\t\Q$_\E\n$//m for 35 | '- $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)'; 36 | $section; 37 | } 38 | -------------------------------------------------------------------------------- /testcases/lib/i3test/Util.pm: -------------------------------------------------------------------------------- 1 | package i3test::Util; 2 | # vim:ts=4:sw=4:expandtab 3 | 4 | use strict; 5 | use warnings; 6 | use v5.10; 7 | 8 | use X11::XCB qw(GET_PROPERTY_TYPE_ANY); 9 | use X11::XCB::Connection; 10 | 11 | use Exporter qw(import); 12 | our @EXPORT = qw( 13 | slurp 14 | get_socket_path 15 | ); 16 | 17 | =encoding utf-8 18 | 19 | =head1 NAME 20 | 21 | i3test::Util - General utility functions 22 | 23 | =cut 24 | 25 | =head1 EXPORT 26 | 27 | =cut 28 | 29 | =head2 slurp($fn) 30 | 31 | Reads the entire file specified in the arguments and returns the content. 32 | 33 | =cut 34 | sub slurp { 35 | my ($file) = @_; 36 | my $content = do { 37 | local $/ = undef; 38 | open my $fh, "<", $file or die "could not open $file: $!"; 39 | <$fh>; 40 | }; 41 | 42 | return $content; 43 | } 44 | 45 | =head2 get_socket_path([X11::XCB::Connection]) 46 | 47 | Gets the socket path from the C atom stored on the X11 root 48 | window. 49 | 50 | =cut 51 | sub get_socket_path { 52 | my ($x) = @_; 53 | $x //= X11::XCB::Connection->new(); 54 | my $atom = $x->atom(name => 'I3_SOCKET_PATH'); 55 | my $cookie = $x->get_property(0, $x->get_root_window(), $atom->id, GET_PROPERTY_TYPE_ANY, 0, 256); 56 | my $reply = $x->get_property_reply($cookie->{sequence}); 57 | my $socketpath = $reply->{value}; 58 | if ($socketpath eq "/tmp/nested-$ENV{DISPLAY}") { 59 | $socketpath .= '-activation'; 60 | } 61 | return $socketpath; 62 | } 63 | 64 | =head1 AUTHOR 65 | 66 | Michael Stapelberg 67 | 68 | =cut 69 | 70 | 1 71 | -------------------------------------------------------------------------------- /testcases/t/000-load-deps.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | 4 | use Test::More; 5 | 6 | BEGIN { 7 | my @deps = qw( 8 | X11::XCB::Connection 9 | X11::XCB::Window 10 | AnyEvent 11 | IPC::Run 12 | ExtUtils::PkgConfig 13 | Inline 14 | ); 15 | for my $dep (@deps) { 16 | use_ok($dep) or BAIL_OUT(qq|The Perl module "$dep" could not be loaded. Please see https://build.i3wm.org/docs/testsuite.html#_installing_the_dependencies|); 17 | } 18 | } 19 | 20 | done_testing; 21 | -------------------------------------------------------------------------------- /testcases/t/001-tile.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | 17 | use i3test; 18 | 19 | my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30); 20 | 21 | my $window = open_window(rect => $original_rect, dont_map => 1); 22 | isa_ok($window, 'X11::XCB::Window'); 23 | 24 | is_deeply($window->rect, $original_rect, "rect unmodified before mapping"); 25 | 26 | $window->map; 27 | wait_for_map $window; 28 | 29 | my $new_rect = $window->rect; 30 | ok(!eq_hash($new_rect, $original_rect), "Window got repositioned"); 31 | 32 | done_testing; 33 | -------------------------------------------------------------------------------- /testcases/t/002-i3-sync.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # checks if i3 supports I3_SYNC 18 | # 19 | use i3test; 20 | 21 | my $result = sync_with_i3; 22 | ok($result, 'syncing was successful'); 23 | 24 | done_testing; 25 | -------------------------------------------------------------------------------- /testcases/t/003-ipc.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | 17 | use i3test; 18 | 19 | fresh_workspace; 20 | 21 | ##################################################################### 22 | # Ensure IPC works by switching workspaces 23 | ##################################################################### 24 | 25 | # Create a window so we can get a focus different from NULL 26 | my $window = open_window; 27 | 28 | my $focus = $x->input_focus; 29 | 30 | # Switch to another workspace 31 | fresh_workspace; 32 | 33 | sync_with_i3; 34 | my $new_focus = $x->input_focus; 35 | isnt($focus, $new_focus, "Focus changed"); 36 | 37 | done_testing; 38 | -------------------------------------------------------------------------------- /testcases/t/004-unmanaged.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | 17 | use i3test; 18 | 19 | my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30); 20 | 21 | my $window = open_window( 22 | rect => $original_rect, 23 | override_redirect => 1, 24 | dont_map => 1, 25 | ); 26 | 27 | isa_ok($window, 'X11::XCB::Window'); 28 | 29 | is_deeply($window->rect, $original_rect, "rect unmodified before mapping"); 30 | 31 | $window->map; 32 | 33 | my $new_rect = $window->rect; 34 | isa_ok($new_rect, 'X11::XCB::Rect'); 35 | 36 | is_deeply($new_rect, $original_rect, "window untouched"); 37 | 38 | done_testing; 39 | -------------------------------------------------------------------------------- /testcases/t/104-focus-stack.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Checks if the focus is correctly restored, when creating a floating client 18 | # over an unfocused tiling client and destroying the floating one again. 19 | 20 | use i3test; 21 | 22 | fresh_workspace; 23 | 24 | cmd 'split h'; 25 | my $tiled_left = open_window; 26 | my $tiled_right = open_window; 27 | 28 | # Get input focus before creating the floating window 29 | my $focus = $x->input_focus; 30 | 31 | # Create a floating window which is smaller than the minimum enforced size of i3 32 | my $window = open_floating_window; 33 | 34 | is($x->input_focus, $window->id, 'floating window focused'); 35 | 36 | $window->unmap; 37 | 38 | wait_for_unmap $window; 39 | 40 | is($x->input_focus, $focus, 'Focus correctly restored'); 41 | 42 | done_testing; 43 | -------------------------------------------------------------------------------- /testcases/t/126-regress-close.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: closing of floating clients did crash i3 when closing the 18 | # container which contained this client. 19 | # 20 | use i3test; 21 | 22 | fresh_workspace; 23 | 24 | cmd 'open'; 25 | cmd 'mode toggle'; 26 | cmd 'kill'; 27 | cmd 'kill'; 28 | 29 | does_i3_live; 30 | 31 | done_testing; 32 | -------------------------------------------------------------------------------- /testcases/t/127-regress-floating-parent.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: make a container floating, kill its parent, make it tiling again 18 | # 19 | use i3test; 20 | 21 | my $tmp = fresh_workspace; 22 | 23 | cmd 'open'; 24 | my $left = get_focused($tmp); 25 | cmd 'open'; 26 | my $old = get_focused($tmp); 27 | cmd 'split v'; 28 | cmd 'open'; 29 | my $floating = get_focused($tmp); 30 | diag("focused floating: " . get_focused($tmp)); 31 | cmd 'mode toggle'; 32 | sync_with_i3; 33 | 34 | # kill old container 35 | cmd qq|[con_id="$old"] focus|; 36 | is(get_focused($tmp), $old, 'old container focused'); 37 | cmd 'kill'; 38 | 39 | # kill left container 40 | cmd qq|[con_id="$left"] focus|; 41 | is(get_focused($tmp), $left, 'old container focused'); 42 | cmd 'kill'; 43 | 44 | # focus floating window, make it tiling again 45 | cmd qq|[con_id="$floating"] focus|; 46 | is(get_focused($tmp), $floating, 'floating window focused'); 47 | 48 | sync_with_i3; 49 | cmd 'mode toggle'; 50 | 51 | does_i3_live; 52 | 53 | done_testing; 54 | -------------------------------------------------------------------------------- /testcases/t/134-invalid-command.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # 5 | # Please read the following documents before working on tests: 6 | # • https://build.i3wm.org/docs/testsuite.html 7 | # (or docs/testsuite) 8 | # 9 | # • https://build.i3wm.org/docs/lib-i3test.html 10 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 11 | # 12 | # • https://build.i3wm.org/docs/ipc.html 13 | # (or docs/ipc) 14 | # 15 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 16 | # (unless you are already familiar with Perl) 17 | # 18 | # 19 | use i3test; 20 | 21 | cmd 'blargh!'; 22 | 23 | does_i3_live; 24 | 25 | done_testing; 26 | -------------------------------------------------------------------------------- /testcases/t/137-floating-unmap.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test: Floating windows were not correctly unmapped when switching 18 | # to a different workspace. 19 | 20 | use i3test; 21 | 22 | my $i3 = i3(get_socket_path()); 23 | 24 | my $tmp = fresh_workspace; 25 | 26 | ############################################################################# 27 | # 1: open a floating window, get it mapped 28 | ############################################################################# 29 | 30 | # Create a floating window which is smaller than the minimum enforced size of i3 31 | my $window = open_floating_window; 32 | ok($window->mapped, 'Window is mapped'); 33 | 34 | # switch to a different workspace, see if the window is still mapped? 35 | 36 | my $otmp = fresh_workspace; 37 | 38 | sync_with_i3; 39 | 40 | ok(!$window->mapped, 'Window is not mapped after switching ws'); 41 | 42 | cmd "nop testcase done"; 43 | 44 | done_testing; 45 | -------------------------------------------------------------------------------- /testcases/t/140-focus-lost.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: Check if the focus stays the same when switching the layout 18 | # bug introduced by 77d0d42ed2d7ac8cafe267c92b35a81c1b9491eb 19 | use i3test; 20 | 21 | my $i3 = i3(get_socket_path()); 22 | 23 | sub check_order { 24 | my ($msg) = @_; 25 | 26 | my @ws = @{$i3->get_workspaces->recv}; 27 | my @nums = map { $_->{num} } grep { defined($_->{num}) } @ws; 28 | my @sorted = sort @nums; 29 | 30 | is_deeply(\@nums, \@sorted, $msg); 31 | } 32 | 33 | my $tmp = fresh_workspace; 34 | 35 | my $left = open_window; 36 | my $mid = open_window; 37 | my $right = open_window; 38 | 39 | diag("left = " . $left->id . ", mid = " . $mid->id . ", right = " . $right->id); 40 | 41 | is($x->input_focus, $right->id, 'Right window focused'); 42 | 43 | cmd 'focus left'; 44 | 45 | is($x->input_focus, $mid->id, 'Mid window focused'); 46 | 47 | cmd 'layout stacked'; 48 | 49 | is($x->input_focus, $mid->id, 'Mid window focused'); 50 | 51 | done_testing; 52 | -------------------------------------------------------------------------------- /testcases/t/142-regress-move-floating.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: move a floating window to a different workspace crashes i3 18 | # 19 | use i3test; 20 | 21 | my $tmp = fresh_workspace; 22 | my $otmp = get_unused_workspace(); 23 | 24 | cmd 'open'; 25 | cmd 'mode toggle'; 26 | cmd "move workspace $otmp"; 27 | 28 | does_i3_live; 29 | 30 | done_testing; 31 | -------------------------------------------------------------------------------- /testcases/t/143-regress-floating-restart.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: floating windows are tiling after restarting, closing them crashes i3 18 | # 19 | use i3test; 20 | 21 | my $tmp = fresh_workspace; 22 | 23 | cmd 'open'; 24 | cmd 'floating toggle'; 25 | 26 | my $ws = get_ws($tmp); 27 | is(scalar @{$ws->{nodes}}, 0, 'no tiling nodes'); 28 | is(scalar @{$ws->{floating_nodes}}, 1, 'precisely one floating node'); 29 | 30 | cmd 'restart'; 31 | 32 | diag('Checking if i3 still lives'); 33 | 34 | does_i3_live; 35 | 36 | $ws = get_ws($tmp); 37 | is(scalar @{$ws->{nodes}}, 0, 'no tiling nodes'); 38 | is(scalar @{$ws->{floating_nodes}}, 1, 'precisely one floating node'); 39 | 40 | done_testing; 41 | -------------------------------------------------------------------------------- /testcases/t/144-regress-floating-resize.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: when resizing two containers on a workspace, opening a floating 18 | # client, then closing it again, i3 will re-distribute the space on the 19 | # workspace as if a tiling container was closed, leading to the containers 20 | # taking much more space than they possibly could. 21 | # 22 | use i3test; 23 | use List::Util qw(sum); 24 | 25 | my $tmp = fresh_workspace; 26 | 27 | my $first = open_window; 28 | my $second = open_window; 29 | 30 | my ($nodes, $focus) = get_ws_content($tmp); 31 | my $old_sum = sum map { $_->{rect}->{width} } @{$nodes}; 32 | 33 | cmd 'resize grow left 10 px or 25 ppt'; 34 | cmd 'split v'; 35 | 36 | sync_with_i3; 37 | 38 | my $third = open_window; 39 | 40 | cmd 'mode toggle'; 41 | sync_with_i3; 42 | 43 | cmd 'kill'; 44 | sync_with_i3; 45 | 46 | ($nodes, $focus) = get_ws_content($tmp); 47 | my $new_sum = sum map { $_->{rect}->{width} } @{$nodes}; 48 | 49 | is($old_sum, $new_sum, 'combined container width is still equal'); 50 | 51 | done_testing; 52 | -------------------------------------------------------------------------------- /testcases/t/146-floating-reinsert.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | use i3test; 18 | 19 | my $tmp = fresh_workspace; 20 | 21 | my $left = open_window; 22 | my $mid = open_window; 23 | 24 | cmd 'split v'; 25 | my $bottom = open_window; 26 | 27 | my ($nodes, $focus) = get_ws_content($tmp); 28 | 29 | ############################################################################# 30 | # 1: open a floating window, get it mapped 31 | ############################################################################# 32 | 33 | # Create a floating window 34 | my $window = open_floating_window; 35 | ok($window->mapped, 'Window is mapped'); 36 | 37 | ($nodes, $focus) = get_ws_content($tmp); 38 | is(@{$nodes->[1]->{nodes}}, 2, 'two windows in split con'); 39 | 40 | ############################################################################# 41 | # 2: make it tiling, see where it ends up 42 | ############################################################################# 43 | 44 | cmd 'floating toggle'; 45 | 46 | ($nodes, $focus) = get_ws_content($tmp); 47 | 48 | is(@{$nodes->[1]->{nodes}}, 3, 'three windows in split con after floating toggle'); 49 | 50 | done_testing; 51 | -------------------------------------------------------------------------------- /testcases/t/147-regress-floatingmove.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test for moving a con outside of a floating con when there are no 18 | # tiling cons on a workspace 19 | # 20 | use i3test; 21 | 22 | sub sync_cmd { 23 | cmd @_; 24 | sync_with_i3; 25 | } 26 | 27 | my $tmp = fresh_workspace; 28 | 29 | my $left = open_window; 30 | my $mid = open_window; 31 | my $right = open_window; 32 | 33 | # go to workspace level 34 | sync_cmd 'focus parent'; 35 | 36 | # make it floating 37 | sync_cmd 'mode toggle'; 38 | 39 | # move the con outside the floating con 40 | sync_cmd 'move up'; 41 | 42 | does_i3_live; 43 | 44 | # move another con outside 45 | sync_cmd '[id="' . $mid->id . '"] focus'; 46 | sync_cmd 'move up'; 47 | 48 | does_i3_live; 49 | 50 | done_testing; 51 | -------------------------------------------------------------------------------- /testcases/t/148-regress-floatingmovews.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test for correct focus behaviour when moving a floating con to 18 | # another workspace. 19 | # 20 | use i3test; 21 | 22 | my $tmp = fresh_workspace; 23 | 24 | # open a tiling window on the first workspace 25 | open_window; 26 | my $first = get_focused($tmp); 27 | 28 | # on a different ws, open a floating window 29 | my $otmp = fresh_workspace; 30 | open_window; 31 | my $float = get_focused($otmp); 32 | cmd 'mode toggle'; 33 | sync_with_i3; 34 | 35 | # move the floating con to first workspace 36 | cmd "move workspace $tmp"; 37 | sync_with_i3; 38 | 39 | # switch to the first ws and check focus 40 | is(get_focused($tmp), $float, 'floating client correctly focused'); 41 | 42 | done_testing; 43 | -------------------------------------------------------------------------------- /testcases/t/151-regress-float-size.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test for setting a window to floating, tiling and opening a new window 18 | # 19 | use i3test; 20 | 21 | fresh_workspace; 22 | 23 | cmd 'open'; 24 | cmd 'mode toggle'; 25 | cmd 'mode toggle'; 26 | cmd 'open'; 27 | 28 | does_i3_live; 29 | 30 | done_testing; 31 | -------------------------------------------------------------------------------- /testcases/t/152-regress-level-up.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test for using level-up to get to the 'content'-container and 18 | # toggle floating 19 | # 20 | use i3test; 21 | 22 | fresh_workspace; 23 | 24 | cmd 'open'; 25 | cmd 'focus parent'; 26 | cmd 'focus parent'; 27 | cmd 'mode toggle'; 28 | 29 | does_i3_live; 30 | 31 | done_testing; 32 | -------------------------------------------------------------------------------- /testcases/t/161-regress-borders-restart.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test to check if borders are correctly restored after an inplace 18 | # restart. 19 | # found in eb8ad348b28e243cba1972e802ca8ee636472fc9 20 | # 21 | use List::Util qw(first); 22 | use i3test; 23 | 24 | my $i3 = i3(get_socket_path()); 25 | my $tmp = fresh_workspace; 26 | my $window = open_window; 27 | 28 | sub get_border_style { 29 | my @content = @{get_ws_content($tmp)}; 30 | my $wininfo = first { $_->{window} == $window->id } @content; 31 | 32 | return $wininfo->{border}; 33 | } 34 | 35 | is(get_border_style(), 'normal', 'border style normal'); 36 | 37 | cmd 'border 1pixel'; 38 | 39 | is(get_border_style(), 'pixel', 'border style 1pixel after changing'); 40 | 41 | # perform an inplace-restart 42 | cmd 'restart'; 43 | 44 | does_i3_live; 45 | 46 | is(get_border_style(), 'pixel', 'border style still 1pixel after restart'); 47 | 48 | done_testing; 49 | -------------------------------------------------------------------------------- /testcases/t/163-wm-state.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests if WM_STATE is WM_STATE_NORMAL when mapped and WM_STATE_WITHDRAWN when 18 | # unmapped. 19 | # 20 | use i3test; 21 | use X11::XCB qw(ICCCM_WM_STATE_NORMAL ICCCM_WM_STATE_WITHDRAWN); 22 | 23 | my $window = open_window; 24 | 25 | is($window->state, ICCCM_WM_STATE_NORMAL, 'WM_STATE normal'); 26 | 27 | $window->unmap; 28 | 29 | wait_for_unmap $window; 30 | 31 | is($window->state, ICCCM_WM_STATE_WITHDRAWN, 'WM_STATE withdrawn'); 32 | 33 | done_testing; 34 | -------------------------------------------------------------------------------- /testcases/t/168-regress-fullscreen-restart.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that i3 survives inplace restarts with fullscreen containers 18 | # 19 | use i3test; 20 | 21 | fresh_workspace; 22 | 23 | open_window; 24 | open_window; 25 | 26 | cmd 'layout stacking'; 27 | sync_with_i3; 28 | 29 | cmd 'fullscreen'; 30 | sync_with_i3; 31 | 32 | cmd 'restart'; 33 | 34 | does_i3_live; 35 | 36 | done_testing; 37 | -------------------------------------------------------------------------------- /testcases/t/173-get-marks.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # checks if the IPC message type get_marks works correctly 18 | # 19 | use i3test; 20 | 21 | sub get_marks { 22 | return i3(get_socket_path())->get_marks->recv; 23 | } 24 | 25 | ############################################################## 26 | # 1: check that get_marks returns no marks yet 27 | ############################################################## 28 | 29 | my $tmp = fresh_workspace; 30 | 31 | my $marks = get_marks(); 32 | is_deeply($marks, [], 'no marks set so far'); 33 | 34 | ############################################################## 35 | # 2: check that setting a mark is reflected in the get_marks reply 36 | ############################################################## 37 | 38 | cmd 'open'; 39 | cmd 'mark foo'; 40 | 41 | is_deeply(get_marks(), [ 'foo' ], 'mark foo set'); 42 | 43 | ############################################################## 44 | # 3: check that the mark is gone after killing the container 45 | ############################################################## 46 | 47 | cmd 'kill'; 48 | 49 | is_deeply(get_marks(), [ ], 'mark gone'); 50 | 51 | done_testing; 52 | -------------------------------------------------------------------------------- /testcases/t/178-regress-workspace-open.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests if empty workspaces are closed when the last child 18 | # exits, as long as they're not empty. 19 | # 20 | use i3test; 21 | 22 | my $i3 = i3(get_socket_path()); 23 | 24 | # Get a workspace and open a container 25 | my $ws = fresh_workspace; 26 | my $con = open_empty_con($i3); 27 | 28 | # Go to a second workspace, kill the container 29 | fresh_workspace; 30 | cmd "[con_id=\"$con\"] kill"; 31 | 32 | # The first workspace should have been closed 33 | ok(!workspace_exists($ws), 'workspace closed'); 34 | 35 | done_testing; 36 | -------------------------------------------------------------------------------- /testcases/t/179-regress-multiple-ws.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # The command "move workspace prev; workspace prev" will lead to an error. 18 | # This regression is present in 7f9b65f6a752e454c492447be4e21e2ee8faf8fd 19 | use i3test; 20 | 21 | my $i3 = i3(get_socket_path()); 22 | 23 | # Open one workspace to move the con to 24 | my $old = fresh_workspace; 25 | my $keep_open_con = open_empty_con($i3); 26 | 27 | # Get a workspace and open a container 28 | my $tmp = fresh_workspace; 29 | my $con = open_empty_con($i3); 30 | 31 | is_num_children($tmp, 1, 'one container'); 32 | is_num_children($old, 1, 'one container on old ws'); 33 | 34 | cmd 'move workspace prev; workspace prev'; 35 | 36 | is_num_children($old, 2, 'container moved away'); 37 | 38 | done_testing; 39 | -------------------------------------------------------------------------------- /testcases/t/182-regress-focus-dock.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test: Focusing a dock window should just do nothing, not crash i3. 18 | # See ticket https://bugs.i3wm.org/575 19 | # Wrong behaviour manifested itself up to (including) commit 20 | # 340592a532b5259c3a3f575de5a9639fad4d1459 21 | # 22 | use i3test; 23 | 24 | fresh_workspace; 25 | 26 | my $window = open_window( 27 | window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'), 28 | ); 29 | 30 | cmd '[title="' . $window->name . '"] focus'; 31 | 32 | does_i3_live; 33 | 34 | done_testing; 35 | -------------------------------------------------------------------------------- /testcases/t/184-regress-float-split-resize.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: resizing a floating split container leads to a crash. 18 | # (Ticket #588, present until 4412ccbe5a4fad8a4cd594e6f10f937515a4d37c) 19 | # 20 | use i3test; 21 | 22 | my $tmp = fresh_workspace; 23 | 24 | my $first = open_window; 25 | cmd 'split v'; 26 | my $second = open_window; 27 | 28 | cmd 'focus parent'; 29 | cmd 'floating toggle'; 30 | cmd 'layout stacking'; 31 | 32 | cmd 'resize grow up 10 px or 10 ppt'; 33 | 34 | does_i3_live; 35 | 36 | done_testing; 37 | -------------------------------------------------------------------------------- /testcases/t/186-regress-assign-focus-parent.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test: New windows were not opened in the correct place if they 18 | # matched an assignment. 19 | # Wrong behaviour manifested itself up to (including) commit 20 | # f78caf8c5815ae7a66de9e4b734546fd740cc19d 21 | # 22 | use i3test i3_config => < "testcase"); 34 | is_num_children('targetws', 1, 'precisely one window'); 35 | 36 | open_window(name => "testcase"); 37 | is_num_children('targetws', 2, 'precisely two windows'); 38 | 39 | cmd 'split v'; 40 | 41 | open_window(name => "testcase"); 42 | is_num_children('targetws', 2, 'still two windows'); 43 | 44 | # focus parent. the new window should now be opened right next to the last one. 45 | cmd 'focus parent'; 46 | 47 | open_window(name => "testcase"); 48 | is_num_children('targetws', 3, 'new window opened next to last one'); 49 | 50 | done_testing; 51 | -------------------------------------------------------------------------------- /testcases/t/188-regress-focus-restart.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that i3 survives inplace restarts with fullscreen containers 18 | # 19 | use i3test; 20 | 21 | my $tmp = fresh_workspace; 22 | 23 | open_window(name => 'first'); 24 | open_window(name => 'second'); 25 | 26 | cmd 'focus left'; 27 | 28 | my ($nodes, $focus) = get_ws_content($tmp); 29 | is(scalar @$nodes, 2, 'two tiling nodes on workspace'); 30 | is($nodes->[0]->{name}, 'first', 'first node name ok'); 31 | is($nodes->[1]->{name}, 'second', 'second node name ok'); 32 | is($focus->[0], $nodes->[0]->{id}, 'first node focused'); 33 | is($focus->[1], $nodes->[1]->{id}, 'second node second in focus stack'); 34 | 35 | cmd 'restart'; 36 | 37 | does_i3_live; 38 | 39 | ($nodes, $focus) = get_ws_content($tmp); 40 | is(scalar @$nodes, 2, 'still two tiling nodes on workspace'); 41 | is($nodes->[0]->{name}, 'first', 'first node name ok'); 42 | is($nodes->[1]->{name}, 'second', 'second node name ok'); 43 | is($focus->[0], $nodes->[0]->{id}, 'first node focused'); 44 | is($focus->[1], $nodes->[1]->{id}, 'second node second in focus stack'); 45 | 46 | done_testing; 47 | -------------------------------------------------------------------------------- /testcases/t/190-scratchpad-diff-ws.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test for ticket #676: 'scratchpad show' causes a segfault if the scratchpad 18 | # window is shown on another workspace. 19 | # 20 | use i3test; 21 | 22 | my $i3 = i3(get_socket_path()); 23 | my $tmp = fresh_workspace; 24 | 25 | my $win = open_window; 26 | 27 | my $scratch = open_window(wm_class => 'special'); 28 | cmd '[class="special"] move scratchpad'; 29 | 30 | is_num_children($tmp, 1, 'one window on current ws'); 31 | 32 | my $otmp = fresh_workspace; 33 | cmd 'scratchpad show'; 34 | 35 | cmd "workspace $tmp"; 36 | cmd '[class="special"] scratchpad show'; 37 | 38 | does_i3_live; 39 | 40 | done_testing; 41 | -------------------------------------------------------------------------------- /testcases/t/191-resize-levels.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that you can resize across different levels of containers even when 18 | # they are all of the same orientation. 19 | # (Ticket #754) 20 | use i3test; 21 | 22 | my $tmp = fresh_workspace; 23 | 24 | open_window; 25 | open_window; 26 | cmd 'split v'; 27 | my $middle = open_window; 28 | open_window; 29 | cmd 'focus parent'; 30 | cmd 'split h'; 31 | open_window; 32 | 33 | cmd '[id="' . $middle->id . '"] focus'; 34 | is($x->input_focus, $middle->id, 'middle window focused'); 35 | 36 | cmd 'resize grow left 10px or 25ppt'; 37 | 38 | my ($nodes, $focus) = get_ws_content($tmp); 39 | 40 | cmp_float($nodes->[0]->{percent}, 0.25, 'left container got only 25%'); 41 | cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%'); 42 | 43 | done_testing; 44 | -------------------------------------------------------------------------------- /testcases/t/193-ipc-version.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that we can get the version number of i3 via IPC. 18 | use i3test; 19 | 20 | my $i3 = i3(get_socket_path()); 21 | $i3->connect->recv; 22 | # We explicitly send the version message because AnyEvent::I3’s 'version' sugar 23 | # method has a fallback which tries to parse the version number from i3 24 | # --version for older versions, and we want to avoid using that. 25 | my $version = $i3->message(7, "")->recv; 26 | 27 | # We need to change this when the major version changes (but we need to touch a 28 | # lot of changes then anyways). 29 | is($version->{major}, 4, 'major version is 4'); 30 | 31 | cmp_ok($version->{minor}, '>', 0, 'minor version > 0'); 32 | 33 | is(int($version->{minor}), $version->{minor}, 'minor version is an integer'); 34 | is(int($version->{patch}), $version->{patch}, 'patch version is an integer'); 35 | 36 | done_testing; 37 | -------------------------------------------------------------------------------- /testcases/t/196-randr-output-names.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verify that i3 allows strange RandR output names such as DVI-I_1/digital. 18 | # Ticket: #785 19 | # Bug still in: 4.2-256-ga007283 20 | use i3test i3_autostart => 0; 21 | use File::Temp qw(tempfile); 22 | 23 | my ($fh, $filename) = tempfile(UNLINK => 1); 24 | print $fh <id; 29 | cmd qq|[id="$id"] move scratchpad, scratchpad show|; 30 | 31 | does_i3_live; 32 | 33 | done_testing; 34 | -------------------------------------------------------------------------------- /testcases/t/199-ipc-mode-event.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that the IPC 'mode' event is sent when modes are changed. 18 | use i3test i3_config => <{change} } @events; 36 | is_deeply(\@changes, [ 'm1' ], 'Mode event received'); 37 | 38 | done_testing; 39 | -------------------------------------------------------------------------------- /testcases/t/204-regress-scratchpad-move.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Moves the last window of a workspace to the scratchpad. The workspace will be 18 | # cleaned up and previously, the subsequent focusing of a destroyed container 19 | # would crash i3. 20 | # Ticket: #913 21 | # Bug still in: 4.4-97-gf767ac3 22 | use i3test; 23 | 24 | my $tmp = fresh_workspace; 25 | 26 | # Open a new window which we can identify later on based on its WM_CLASS. 27 | my $scratch = open_window(wm_class => 'special'); 28 | 29 | my $tmp2 = fresh_workspace; 30 | 31 | cmd '[class="special"] move scratchpad'; 32 | 33 | does_i3_live; 34 | 35 | done_testing; 36 | -------------------------------------------------------------------------------- /testcases/t/205-ipc-windows.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | 17 | use i3test; 18 | 19 | my $new = AnyEvent->condvar; 20 | my $focus = AnyEvent->condvar; 21 | 22 | my @events = events_for( 23 | sub { open_window }, 24 | 'window'); 25 | 26 | is(scalar @events, 2, 'Received 2 events'); 27 | is($events[0]->{container}->{focused}, 0, 'Window "new" event received'); 28 | is($events[1]->{container}->{focused}, 1, 'Window "focus" event received'); 29 | 30 | done_testing; 31 | -------------------------------------------------------------------------------- /testcases/t/208-regress-floating-criteria.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test for focus handling when using floating enable/disable with 18 | # criteria for windows on non-visible workspaces. 19 | # Ticket: #1027 20 | # Bug still in: 4.5.1-90-g6582da9 21 | use i3test i3_config => < 'Borderless window', 31 | wm_class => 'special', 32 | dont_map => 1, 33 | ); 34 | $window->map; 35 | 36 | sync_with_i3; 37 | 38 | cmd '[class="^special$"] focus'; 39 | 40 | does_i3_live; 41 | 42 | done_testing; 43 | -------------------------------------------------------------------------------- /testcases/t/218-regress-floating-split.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Make sure floating containers really can't be split. 18 | # Ticket: #1177 19 | # Bug still in: 4.7.2-81-g905440d 20 | use i3test; 21 | 22 | my $ws = fresh_workspace; 23 | my $window = open_floating_window; 24 | cmd "layout stacked"; 25 | cmd "splitv"; 26 | 27 | my $floating_con = get_ws($ws)->{floating_nodes}[0]->{nodes}[0]; 28 | 29 | is(@{$floating_con->{nodes}}, 0, 'floating con is still a leaf'); 30 | 31 | cmd 'floating disable'; 32 | 33 | does_i3_live; 34 | 35 | done_testing; 36 | -------------------------------------------------------------------------------- /testcases/t/220-ipc-window-title.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | 17 | use i3test; 18 | 19 | my $window = open_window(name => 'Window 0'); 20 | 21 | my @events = events_for( 22 | sub { 23 | $window->name('New Window Title'); 24 | sync_with_i3; 25 | }, 26 | 'window'); 27 | 28 | is(scalar @events, 1, 'Received 1 event'); 29 | is($events[0]->{change}, 'title', 'Window title change event received'); 30 | is($events[0]->{container}->{name}, 'New Window Title', 'Window title changed'); 31 | 32 | done_testing; 33 | -------------------------------------------------------------------------------- /testcases/t/222-regress-dock-resize.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that i3 does not crash when a command is issued that would resize a dock 18 | # client. 19 | # Ticket: #1201 20 | # Bug still in: 4.7.2-107-g9b03be6 21 | use i3test i3_config => < 'special', 28 | window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'), 29 | ); 30 | 31 | cmd('[class="special"] resize grow height 160 px or 16 ppt'); 32 | 33 | does_i3_live; 34 | 35 | done_testing; 36 | -------------------------------------------------------------------------------- /testcases/t/224-regress-resize-branch.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that i3 does not crash when resizing a split container 18 | # Ticket: #1220 19 | # Bug still in: 4.7.2-128-g702906d 20 | use i3test; 21 | 22 | open_window; 23 | open_window; 24 | 25 | cmd 'split h'; 26 | 27 | open_window; 28 | 29 | cmd 'focus parent, resize grow left'; 30 | 31 | does_i3_live; 32 | 33 | done_testing; 34 | -------------------------------------------------------------------------------- /testcases/t/225-ipc-window-fullscreen.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests that the ipc window::fullscreen_mode event works properly 18 | # 19 | # Bug still in: 4.7.2-135-g7deb23c 20 | use i3test; 21 | 22 | open_window; 23 | 24 | sub fullscreen_subtest { 25 | my ($want) = @_; 26 | my @events = events_for( 27 | sub { cmd 'fullscreen' }, 28 | 'window'); 29 | 30 | is(scalar @events, 1, 'Received 1 event'); 31 | is($events[0]->{container}->{fullscreen_mode}, $want, "fullscreen_mode now $want"); 32 | } 33 | 34 | subtest 'fullscreen on', \&fullscreen_subtest, 1; 35 | subtest 'fullscreen off', \&fullscreen_subtest, 0; 36 | 37 | done_testing; 38 | -------------------------------------------------------------------------------- /testcases/t/231-ipc-floating-event.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that the window::floating event works correctly. This event should be 18 | # emitted when a window transitions to or from the floating state. 19 | # Bug still in: 4.8-7-gf4a8253 20 | use i3test; 21 | 22 | sub floating_subtest { 23 | my ($win, $cmd, $want) = @_; 24 | 25 | my @events = events_for( 26 | sub { cmd $cmd }, 27 | 'window'); 28 | 29 | my @floating = grep { $_->{change} eq 'floating' } @events; 30 | is(scalar @floating, 1, 'Received 1 floating event'); 31 | is($floating[0]->{container}->{window}, $win->{id}, "window id matches"); 32 | is($floating[0]->{container}->{floating}, $want, "floating is $want"); 33 | } 34 | 35 | my $win = open_window(); 36 | 37 | subtest 'floating enable', \&floating_subtest, $win, '[id="' . $win->{id} . '"] floating enable', 'user_on'; 38 | subtest 'floating disable', \&floating_subtest, $win, '[id="' . $win->{id} . '"] floating disable', 'user_off'; 39 | 40 | done_testing; 41 | -------------------------------------------------------------------------------- /testcases/t/236-floating-focus-raise.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that focusing floating windows with the command `focus [direction]` 18 | # promotes the focused window to the top of the rendering stack. 19 | # Ticket: #1322 20 | # Bug still in: 4.8-88-gcc09348 21 | use i3test; 22 | 23 | my $ws = fresh_workspace; 24 | 25 | my $win1 = open_floating_window; 26 | my $win2 = open_floating_window; 27 | my $win3 = open_floating_window; 28 | 29 | # it's a good idea to do this a few times because of the implementation 30 | for my $i (1 .. 3) { 31 | cmd 'focus left'; 32 | my $ws_con = get_ws($ws); 33 | is($ws_con->{floating_nodes}[-1]->{nodes}[0]->{id}, get_focused($ws), 34 | "focus left put the focused window on top of the floating windows (try $i)"); 35 | } 36 | 37 | for my $i (1 .. 3) { 38 | cmd 'focus right'; 39 | my $ws_con = get_ws($ws); 40 | is($ws_con->{floating_nodes}[-1]->{nodes}[0]->{id}, get_focused($ws), 41 | "focus right put the focused window on top of the floating windows (try $i)"); 42 | } 43 | 44 | done_testing; 45 | -------------------------------------------------------------------------------- /testcases/t/237-regress-assign-focus.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that using layout tabbed followed by focus (on a window that is 18 | # assigned to an invisible workspace) will not crash i3. 19 | # Ticket: #1338 20 | # Bug still in: 4.8-91-g294d52e 21 | use i3test i3_config => <id, # window 31 | $x->atom(name => '_NET_CLOSE_WINDOW')->id, # message type 32 | 0, # data32[0] 33 | 0, # data32[1] 34 | 0, # data32[2] 35 | 0, # data32[3] 36 | 0; # data32[4] 37 | 38 | $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg); 39 | } 40 | 41 | my $ws = fresh_workspace; 42 | my $win = open_window; 43 | 44 | send_close_window_request($win); 45 | sync_with_i3; 46 | 47 | is(@{get_ws($ws)->{nodes}}, 0, 'When a pager sends a _NET_CLOSE_WINDOW request for a window, the container should be closed'); 48 | 49 | done_testing; 50 | -------------------------------------------------------------------------------- /testcases/t/260-invalid-criteria.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Ticket: #2091 18 | use i3test; 19 | 20 | my $ws = fresh_workspace; 21 | open_window; 22 | 23 | my $result = cmd '[con_id=foobar] kill'; 24 | is($result->[0]->{success}, 0, 'command was unsuccessful'); 25 | is($result->[0]->{error}, 'Invalid match: invalid con_id', 'correct error is returned'); 26 | 27 | done_testing; 28 | -------------------------------------------------------------------------------- /testcases/t/262-config-validation.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Ensures that calling i3 with the -C switch works (smoke test). 18 | # Ticket: #2144 19 | use i3test i3_autostart => 0; 20 | use POSIX ":sys_wait_h"; 21 | use Time::HiRes qw(sleep); 22 | 23 | my $config = < 1); 31 | isnt($exit_code, 0, 'i3 exited with an error code'); 32 | 33 | my $log = get_i3_log; 34 | 35 | # We don't care so much about the output (there are tests for this), but rather 36 | # that we got correct output at all instead of, e.g., a segfault. 37 | ok($log =~ /Expected one of these tokens/, 'an invalid config token was found'); 38 | 39 | done_testing; 40 | -------------------------------------------------------------------------------- /testcases/t/263-config-reload-reverts-bind-mode.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that reloading the config reverts to the default 18 | # binding mode. 19 | # Ticket: #2228 20 | # Bug still in: 4.11-262-geb631ce 21 | use i3test i3_config => <{change}, 'default', 'change is "default"'); 37 | 38 | done_testing; 39 | -------------------------------------------------------------------------------- /testcases/t/267-regress-mark-restart.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test to check if mark and restart commands crash i3 18 | # 19 | use i3test; 20 | 21 | cmd 'open'; 22 | cmd 'mark foo'; 23 | cmd 'open'; 24 | cmd 'mark bar'; 25 | 26 | cmd 'restart'; 27 | 28 | diag('Checking if i3 still lives'); 29 | 30 | does_i3_live; 31 | 32 | done_testing; 33 | -------------------------------------------------------------------------------- /testcases/t/270-config-no-newline-end.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Make sure that configs that end without a newline don't crash i3. 18 | # Ticket: #2934 19 | use i3test i3_autostart => 0; 20 | 21 | my $first_lines = <<'EOT'; 22 | set $workspace0 workspace eggs 23 | 24 | font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 25 | EOT 26 | 27 | # Intentionally don't add a trailing newline for the last line since this is 28 | # what triggered the bug. 29 | my $last_line = 'bindsym Mod4+0 $workspace0'; 30 | my $config = "${first_lines}${last_line}"; 31 | 32 | my $pid = launch_with_config($config); 33 | does_i3_live; 34 | 35 | my $i3 = i3(get_socket_path()); 36 | my $ws = $i3->get_workspaces->recv; 37 | is($ws->[0]->{name}, 'eggs', 'last line processed correctly'); 38 | 39 | exit_gracefully($pid); 40 | done_testing; 41 | -------------------------------------------------------------------------------- /testcases/t/273-regress-focus-toggle.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: Checks if i3 still lives after using 'focus mode_toggle' on an 18 | # empty workspace. This regression was fixed in 19 | # 0848844f2d41055f6ffc69af1149d7a873460976. 20 | # 21 | use i3test; 22 | use v5.10; 23 | 24 | my $tmp = fresh_workspace; 25 | 26 | cmd 'focus mode_toggle'; 27 | 28 | does_i3_live; 29 | 30 | done_testing; 31 | -------------------------------------------------------------------------------- /testcases/t/275-ipc-window-close.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests that the ipc close event works properly 18 | # 19 | # Bug still in: 4.8-7-gf4a8253 20 | use i3test; 21 | 22 | my $window = open_window; 23 | 24 | my @events = events_for( 25 | sub { 26 | $window->unmap; 27 | sync_with_i3; 28 | }, 29 | 'window'); 30 | 31 | my @close = grep { $_->{change} eq 'close' } @events; 32 | is(scalar @close, 1, 'Received 1 window::close event'); 33 | is($close[0]->{container}->{window}, $window->{id}, 'the event should contain information about the window'); 34 | 35 | done_testing; 36 | -------------------------------------------------------------------------------- /testcases/t/276-ipc-window-move.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests that the ipc window::move event works properly 18 | # 19 | # Bug still in: 4.8-7-gf4a8253 20 | use i3test; 21 | 22 | my $dummy_window = open_window; 23 | my $window = open_window; 24 | 25 | sub move_subtest { 26 | my ($cmd) = @_; 27 | my $cv = AnyEvent->condvar; 28 | my @events = events_for( 29 | sub { cmd $cmd }, 30 | 'window'); 31 | 32 | my @move = grep { $_->{change} eq 'move' } @events; 33 | is(scalar @move, 1, 'Received 1 window::move event'); 34 | is($move[0]->{container}->{window}, $window->{id}, 'window id matches'); 35 | } 36 | 37 | subtest 'move left', \&move_subtest, 'move left'; 38 | subtest 'move to workspace', \&move_subtest, 'move to workspace ws_new'; 39 | 40 | done_testing; 41 | -------------------------------------------------------------------------------- /testcases/t/277-ipc-window-urgent.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that the window::urgent event works correctly. The window::urgent event 18 | # should be emitted when a window becomes urgent or loses its urgent status. 19 | # 20 | use i3test; 21 | 22 | fresh_workspace; 23 | my $win = open_window; 24 | my $dummy_win = open_window; 25 | 26 | sub urgency_subtest { 27 | my ($subscribecb, $win, $want) = @_; 28 | 29 | my @events = events_for( 30 | $subscribecb, 31 | 'window'); 32 | 33 | my @urgent = grep { $_->{change} eq 'urgent' } @events; 34 | is(scalar @urgent, 1, 'Received 1 window::urgent event'); 35 | is($urgent[0]->{container}->{window}, $win->{id}, "window id matches"); 36 | is($urgent[0]->{container}->{urgent}, $want, "urgent is $want"); 37 | } 38 | 39 | subtest "urgency set", \&urgency_subtest, 40 | sub { 41 | $win->add_hint('urgency'); 42 | sync_with_i3; 43 | }, 44 | $win, 45 | 1; 46 | 47 | subtest "urgency unset", \&urgency_subtest, 48 | sub { 49 | $win->delete_hint('urgency'); 50 | sync_with_i3; 51 | }, 52 | $win, 53 | 0; 54 | 55 | done_testing; 56 | -------------------------------------------------------------------------------- /testcases/t/279-regress-default-floating-border.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # This is a regression test for a bug where a normal floating default border is 18 | # not applied when the default tiling border is set to a pixel value. 19 | # Ticket: #1305 20 | # Bug still in: 4.8-62-g7381b50 21 | use i3test i3_config => <{floating_nodes}}; 34 | 35 | is($floating[0]->{nodes}[0]->{border}, 'normal', 'default floating border is `normal`'); 36 | 37 | done_testing; 38 | -------------------------------------------------------------------------------- /testcases/t/281-regress-reload-bindsym.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that the binding event works properly 18 | # Ticket: #1210 19 | use i3test i3_config => < /dev/null); 28 | 29 | skip 'xdotool is required to test the binding event. `[apt-get install|pacman -S] xdotool`', 1 if $?; 30 | 31 | qx(xdotool key r); 32 | 33 | does_i3_live; 34 | 35 | } 36 | done_testing; 37 | -------------------------------------------------------------------------------- /testcases/t/282-tabbed-floating-disable-crash.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that i3 does not crash when floating and then unfloating an 18 | # unfocused window within a tabbed container. 19 | # Ticket: #1484 20 | # Bug still in: 4.9.1-124-g856e1f9 21 | use i3test i3_config => < < < 0); 29 | open_window; 30 | cmd 'sticky enable, floating enable'; 31 | 32 | # Switch to the right output and open a new workspace. 33 | my $ws = fresh_workspace(output => 1); 34 | does_i3_live; 35 | 36 | # Verify results. 37 | is(@{get_ws($ws)->{floating_nodes}}, 0, 'workspace in right output is empty'); 38 | $ws = fresh_workspace(output => 0); 39 | is(@{get_ws($ws)->{floating_nodes}}, 1, 'new workspace in left output has the sticky container'); 40 | 41 | done_testing; 42 | -------------------------------------------------------------------------------- /testcases/t/295-net-wm-state-focused.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • http://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • http://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • http://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests for setting and removing the _NET_WM_STATE_FOCUSED atom properly. 18 | # Ticket: #2273 19 | use i3test; 20 | use X11::XCB qw(:all); 21 | 22 | my ($windowA, $windowB); 23 | 24 | fresh_workspace; 25 | $windowA = open_window; 26 | ok(is_net_wm_state_focused($windowA), 'a newly opened window that is focused should have _NET_WM_STATE_FOCUSED set'); 27 | 28 | $windowB = open_window; 29 | ok(!is_net_wm_state_focused($windowA), 'when a another window is focused, the old window should not have _NET_WM_STATE_FOCUSED set'); 30 | ok(is_net_wm_state_focused($windowB), 'a newly opened window that is focused should have _NET_WM_STATE_FOCUSED set'); 31 | 32 | # See issue #3495. 33 | cmd 'kill'; 34 | ok(is_net_wm_state_focused($windowA), 'when the second window is closed, the first window should have _NET_WM_STATE_FOCUSED set'); 35 | 36 | fresh_workspace; 37 | ok(!is_net_wm_state_focused($windowA), 'when focus moves to the ewmh support window, no window should have _NET_WM_STATE_FOCUSED set'); 38 | 39 | done_testing; 40 | -------------------------------------------------------------------------------- /testcases/t/296-regress-focus-behind-fullscreen-floating.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that directional focus gives focus to floating fullscreen containers when 18 | # switching workspaces. 19 | # Ticket: #3201 20 | # Bug still in: 4.15-59-gb849fe3e 21 | use i3test i3_config => < 0); 29 | my $ws = fresh_workspace(output => 1); 30 | open_window; 31 | open_floating_window; 32 | cmd 'fullscreen enable'; 33 | my $expected_focus = get_focused($ws); 34 | 35 | cmd 'focus left'; 36 | cmd 'focus right'; 37 | 38 | is (get_focused($ws), $expected_focus, 'floating fullscreen window focused after directional focus'); 39 | 40 | done_testing; 41 | -------------------------------------------------------------------------------- /testcases/t/299-regress-scratchpad-focus.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression test: verify that a scratchpad container that was open in another 18 | # workspace and is moved to the current workspace after a 'scratchpad show' is 19 | # focused. 20 | # Ticket: #3361 21 | # Bug still in: 4.15-190-g4b3ff9cd 22 | use i3test; 23 | 24 | my $expected_focus = open_window; 25 | cmd 'move to scratchpad'; 26 | cmd 'scratchpad show'; 27 | my $ws = fresh_workspace; 28 | open_window; 29 | cmd 'scratchpad show'; 30 | sync_with_i3; 31 | is($x->input_focus, $expected_focus->id, 'scratchpad window brought from other workspace is focused'); 32 | 33 | done_testing; 34 | -------------------------------------------------------------------------------- /testcases/t/300-restart-non-utf8.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verify that i3 does not crash when restart is issued while a window with a 18 | # title that contains non-UTF8 characters is open. 19 | # Ticket: #3156 20 | # Bug still in: 4.15-241-g9dc4df81 21 | use i3test; 22 | 23 | my $ws = fresh_workspace; 24 | open_window(name => "\x{AA} <-- invalid"); 25 | 26 | cmd 'restart'; 27 | does_i3_live; 28 | 29 | # Confirm that the invalid character got replaced with U+FFFD - "REPLACEMENT 30 | # CHARACTER" 31 | cmd '[title="^' . "\x{fffd}" . ' <-- invalid$"] fullscreen enable'; 32 | is_num_fullscreen($ws, 1, 'title based criterion works'); 33 | 34 | done_testing; 35 | -------------------------------------------------------------------------------- /testcases/t/303-regress-move-floating.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Regression: moving a container which is the only child of the only child of a 18 | # floating container crashes i3. 19 | # Ticket: #3556 20 | # Bug still in: 4.16-61-g376833db4 21 | use i3test; 22 | 23 | my $ws = fresh_workspace; 24 | open_window; 25 | open_window; 26 | cmd 'split v, focus parent, floating toggle, focus child, move right'; 27 | does_i3_live; 28 | 29 | $ws = get_ws($ws); 30 | is(scalar @{$ws->{floating_nodes}}, 0, 'No floating nodes in workspace'); 31 | is(scalar @{$ws->{nodes}}, 2, 'Two tiling nodes in workspace'); 32 | 33 | done_testing; 34 | -------------------------------------------------------------------------------- /testcases/t/305-restart-reply.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verify that restart produces a reply. 18 | # Ticket: #3565 19 | # Bug still in: 4.16-143-gca82f958 20 | use i3test; 21 | 22 | my $reply = cmd('restart'); 23 | ok($reply->[0]->{success}, 'restart reply received'); 24 | 25 | done_testing; 26 | -------------------------------------------------------------------------------- /testcases/t/306-move-to-parent.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Make sure the trick used to move the container to its parent works. 18 | # https://github.com/i3/i3/issues/1326#issuecomment-349082811 19 | use i3test; 20 | 21 | cmp_tree( 22 | msg => 'Move to parent when the parent is a workspace', 23 | layout_before => 'a H[b*] c', 24 | layout_after => 'a b* c', 25 | cb => sub { 26 | cmd 'mark _a, focus parent, focus parent, mark _b, [con_mark=_a] move window to mark _b, [con_mark=_a] focus'; 27 | }); 28 | 29 | cmp_tree( 30 | msg => 'Move to parent when the parent is a split', 31 | layout_before => 'V[a H[b*] c]', 32 | layout_after => 'V[a b* c]', 33 | cb => sub { 34 | cmd 'mark _a, focus parent, focus parent, mark _b, [con_mark=_a] move window to mark _b, [con_mark=_a] focus'; 35 | }); 36 | 37 | done_testing; 38 | -------------------------------------------------------------------------------- /testcases/t/309-crash-move-parent.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that moving a container that is to be flattened does not crash i3 18 | # Ticket: #3831 19 | # Bug still in: 4.17-199-ga638e0408 20 | use i3test; 21 | 22 | cmp_tree( 23 | msg => 'Moving a redundant container that is to be flattened does not crash i3', 24 | layout_before => 'a H[V[b* c]]', # Not very attached to this result but 25 | layout_after => 'H[a] b* c', # mainly checking if the crash happens. 26 | cb => sub { 27 | cmd 'focus parent, focus parent, move down'; 28 | does_i3_live; 29 | is(get_ws(focused_ws)->{layout}, 'splitv', 'Workspace changed to splitv'); 30 | }); 31 | 32 | cmp_tree( 33 | msg => "Same but create the redundant container with a 'split h' command", 34 | layout_before => 'a V[b* c]', 35 | layout_after => 'H[a] b* c', 36 | cb => sub { 37 | cmd 'focus parent, split h, focus parent, move down'; 38 | does_i3_live; 39 | is(get_ws(focused_ws)->{layout}, 'splitv', 'Workspace changed to splitv'); 40 | }); 41 | 42 | 43 | done_testing; 44 | -------------------------------------------------------------------------------- /testcases/t/311-get-binding-modes.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies the GET_BINDING_MODE IPC command 18 | # Ticket: #3892 19 | # Bug still in: 4.18-318-g50160eb1 20 | use i3test i3_config => <connect->recv; 31 | # TODO: use the symbolic name for the command/reply type instead of the 32 | # numerical 12: 33 | my $binding_state = $i3->message(12, "")->recv; 34 | is($binding_state->{name}, 'default', 'at startup, binding mode is default'); 35 | 36 | cmd 'mode extra'; 37 | 38 | $binding_state = $i3->message(12, "")->recv; 39 | is($binding_state->{name}, 'extra', 'after switching, binding mode is extra'); 40 | 41 | done_testing; 42 | -------------------------------------------------------------------------------- /testcases/t/312-regress-layout-default.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies i3 does not crash when using layout default. 18 | # Ticket: #4408 19 | # Bug still in: 4.19.2-83-gc8158875 20 | use i3test; 21 | 22 | cmd 'layout default'; 23 | fresh_workspace; 24 | 25 | done_testing; 26 | -------------------------------------------------------------------------------- /testcases/t/315-long-commands.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that commands with more than 10 non-identified words doesn't works 18 | # 10 is the magic number chosen for the stack size which is why it's used here 19 | # Ticket: #2968 20 | # Bug still in: 4.19.2-103-gfc65ca36 21 | use i3test; 22 | 23 | ###################################################################### 24 | # 1) run a long command 25 | ###################################################################### 26 | 27 | my $i3 = i3(get_socket_path()); 28 | my $tmp = fresh_workspace; 29 | 30 | my $floatwin = open_floating_window; 31 | 32 | 33 | my ($absolute_before, $top_before) = $floatwin->rect; 34 | 35 | cmd 'move window container to window container to window container to left'; 36 | 37 | sync_with_i3; 38 | 39 | my ($absolute, $top) = $floatwin->rect; 40 | 41 | is($absolute->x, ($absolute_before->x - 10), 'moved 10 px to the left'); 42 | is($absolute->y, $absolute_before->y, 'y not changed'); 43 | is($absolute->width, $absolute_before->width, 'width not changed'); 44 | is($absolute->height, $absolute_before->height, 'height not changed'); 45 | 46 | done_testing; 47 | -------------------------------------------------------------------------------- /testcases/t/316-transient-for-loop.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that i3 does not get stuck in an endless loop between two windows that 18 | # set transient_for for each other. 19 | # Ticket: #4404 20 | # Bug still in: 4.20-69-g43e805a00 21 | # 22 | use i3test i3_config => < 1 }); 33 | my $w2 = open_window({ dont_map => 1 }); 34 | 35 | $w1->transient_for($w2); 36 | $w2->transient_for($w1); 37 | $w1->map; 38 | $w2->map; 39 | 40 | does_i3_live; 41 | 42 | done_testing; 43 | -------------------------------------------------------------------------------- /testcases/t/317-bar-config-font-order.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that bar config blocks get the i3-wide font configured, 18 | # regardless of where the font is configured in the config file 19 | # (before or after the bar config blocks). 20 | # Ticket: #5031 21 | # Bug still in: 4.20-105-g4db383e4 22 | use i3test i3_config => <<'EOT'; 23 | # i3 config file (v4) 24 | 25 | bar { 26 | # no font directive here, no i3-wide font configured (yet) 27 | } 28 | 29 | font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 30 | EOT 31 | 32 | my $i3 = i3(get_socket_path(0)); 33 | my $bars = $i3->get_bar_config()->recv; 34 | 35 | my $bar_id = shift @$bars; 36 | my $bar_config = $i3->get_bar_config($bar_id)->recv; 37 | is($bar_config->{font}, 'fixed', 'font ok'); 38 | 39 | done_testing; 40 | -------------------------------------------------------------------------------- /testcases/t/500-multi-monitor.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests that the provided X-Server to the t/5??-*.t tests is actually providing 18 | # multiple monitors. 19 | # 20 | use i3test i3_config => <get_tree->recv; 34 | 35 | my @outputs = map { $_->{name} } @{$tree->{nodes}}; 36 | is_deeply(\@outputs, [ '__i3', 'fake-0', 'fake-1' ], 37 | 'multi-monitor outputs ok'); 38 | 39 | 40 | done_testing; 41 | -------------------------------------------------------------------------------- /testcases/t/507-workspace-move-crash.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests whether i3 crashes on cross-output moves with one workspace per output. 18 | # Ticket: #827 19 | # Bug still in: 4.3-78-g66b389c 20 | # 21 | use List::Util qw(first); 22 | use i3test i3_config => < <{workspace_layout}, 'tabbed', 'workspace layout is "tabbed"'); 35 | 36 | done_testing; 37 | -------------------------------------------------------------------------------- /testcases/t/511-scratchpad-configure-request.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests that ConfigureRequests don’t make windows fall out of the scratchpad. 18 | # Ticket: #898 19 | # Bug still in: 4.4-15-g770ead6 20 | use i3test i3_config => < 0); 28 | my $right_ws = fresh_workspace(output => 1); 29 | 30 | my $window = open_window; 31 | cmd 'move scratchpad'; 32 | 33 | # Cause a ConfigureRequest by setting the window’s position/size. 34 | my ($a, $t) = $window->rect; 35 | $window->rect(X11::XCB::Rect->new(x => 0, y => 0, width => $a->width, height => $a->height)); 36 | 37 | sync_with_i3; 38 | 39 | my $ws = get_ws($left_ws); 40 | is(scalar @{$ws->{floating_nodes}}, 0, 'scratchpad window still in scratchpad after ConfigureRequest'); 41 | $ws = get_ws($right_ws); 42 | is(scalar @{$ws->{floating_nodes}}, 0, 'scratchpad window still in scratchpad after ConfigureRequest'); 43 | 44 | done_testing; 45 | -------------------------------------------------------------------------------- /testcases/t/512-move-wraps.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Verifies that moving containers wraps across outputs. 18 | # E.g. when you have a container on the right output and you move it to the 19 | # right, it should appear on the left output. 20 | # Bug still in: 4.4-106-g3cd4b8c 21 | use i3test i3_config => < 1); 29 | my $left = fresh_workspace(output => 0); 30 | 31 | my $win = open_window; 32 | 33 | is_num_children($left, 1, 'one container on left workspace'); 34 | 35 | cmd 'move container to output right'; 36 | cmd 'focus output right'; 37 | 38 | is_num_children($left, 0, 'no containers on left workspace'); 39 | is_num_children($right, 1, 'one container on right workspace'); 40 | 41 | cmd 'move container to output right'; 42 | 43 | is_num_children($left, 1, 'one container on left workspace'); 44 | is_num_children($right, 0, 'no containers on right workspace'); 45 | 46 | done_testing; 47 | -------------------------------------------------------------------------------- /testcases/t/514-ipc-workspace-multi-monitor.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Ticket: #990 18 | # Bug still in: 4.5.1-23-g82b5978 19 | 20 | use i3test i3_config => <condvar; 29 | my @events = events_for( 30 | sub { cmd 'focus output right' }, 31 | 'workspace'); 32 | 33 | my $current_ws = get_ws(focused_ws); 34 | 35 | is(scalar @events, 1, 'Received 1 event'); 36 | is($events[0]->{current}->{id}, $current_ws->{id}, 'Event gave correct current workspace'); 37 | is($events[0]->{old}->{id}, $old_ws->{id}, 'Event gave correct old workspace'); 38 | 39 | done_testing; 40 | -------------------------------------------------------------------------------- /testcases/t/515-create-workspace.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests that new workspace names are taken from the config, 18 | # then from the first free number starting with 1. 19 | # 20 | use i3test i3_config => <get_workspaces->recv; 31 | 32 | is($ws->[0]->{name}, '1: eggs', 'new workspace uses config name'); 33 | is($ws->[1]->{name}, '2', 'naming continues with next free number'); 34 | 35 | done_testing; 36 | -------------------------------------------------------------------------------- /testcases/t/519-mouse-warping.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 12 | # (unless you are already familiar with Perl) 13 | 14 | use i3test i3_config => <root->warp_pointer(0, 0); 24 | 25 | ###################################################### 26 | # Open one workspace with one window on both outputs # 27 | ###################################################### 28 | 29 | # Open window on workspace 1, left output 30 | is(focused_ws, '1', 'starting with focus on workspace 1'); 31 | open_window; 32 | 33 | # Open window on workspace 2, right output 34 | cmd 'focus output right'; 35 | is(focused_ws, '2', 'moved focus to workspace 2'); 36 | open_window; 37 | 38 | # If mouse_warping is disabled, the pointer has not moved from 39 | # position (0, 0) when focus was switched to workspace 2 40 | $x->root->warp_pointer(0, 0); 41 | 42 | # Ensure focus is still on workspace 2 43 | is(focused_ws, '2', 'warped mouse cursor to (0, 0), focus still in workspace 2'); 44 | 45 | done_testing; 46 | -------------------------------------------------------------------------------- /testcases/t/520-regress-focus-direction-floating.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Ensure that `focus [direction]` will focus an existing floating con when no 18 | # tiling con exists on the output in [direction] when focusing across outputs 19 | # Bug still in: 4.7.2-204-g893dbae 20 | use i3test i3_config => <input_focus, $win->id, 40 | 'Focusing across outputs with `focus [direction]` should focus an existing floating con when no tiling con exists on the output in [direction].'); 41 | 42 | done_testing; 43 | -------------------------------------------------------------------------------- /testcases/t/527-focus-fallback.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Ticket: #1378 18 | use i3test; 19 | use X11::XCB qw(:all); 20 | 21 | sub get_ewmh_window { 22 | my $cookie = $x->get_property( 23 | 0, 24 | $x->get_root_window(), 25 | $x->atom(name => '_NET_SUPPORTING_WM_CHECK')->id, 26 | $x->atom(name => 'WINDOW')->id, 27 | 0, 28 | 4096 29 | ); 30 | 31 | my $reply = $x->get_property_reply($cookie->{sequence}); 32 | my $len = $reply->{length}; 33 | return undef if $len == 0; 34 | 35 | return unpack("L", $reply->{value}); 36 | } 37 | 38 | my $window = open_window; 39 | sync_with_i3; 40 | is($x->input_focus, $window->id, 'sanity check: window has input focus'); 41 | cmd 'kill'; 42 | sync_with_i3; 43 | is($x->input_focus, get_ewmh_window(), 'focus falls back to the EWMH window'); 44 | 45 | done_testing; 46 | -------------------------------------------------------------------------------- /testcases/t/530-bug-2229.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Ticket: #2229 18 | # Bug still in: 4.11-262-geb631ce 19 | use i3test i3_config => < <root->warp_pointer(500, 0); 40 | sync_with_i3; 41 | 42 | my $dropdown = open_floating_window; 43 | $dropdown->rect(X11::XCB::Rect->new(x => 1, y => 1, width => 100, height => 100)); 44 | sync_with_i3; 45 | 46 | my $cookie = $x->query_pointer($dropdown->{id}); 47 | my $reply = $x->query_pointer_reply($cookie->{sequence}); 48 | cmp_ok($reply->{root_x}, '<', 1024, 'pointer still on fake-0'); 49 | cmp_ok($reply->{root_y}, '<', 768, 'pointer still on fake-0'); 50 | 51 | done_testing; 52 | -------------------------------------------------------------------------------- /testcases/t/538-i3bar-primary-output.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests that i3bars configured to use the primary output do not have 18 | # their output names canonicalized to something other than "primary". 19 | # Ticket: #2948 20 | # Bug still in: 4.14-93-ga3a7d04a 21 | use i3test i3_config => <get_bar_config()->recv; 33 | is(@$bars, 1, 'one bar configured'); 34 | 35 | my $bar_id = shift @$bars; 36 | 37 | my $bar_config = i3->get_bar_config($bar_id)->recv; 38 | is_deeply($bar_config->{outputs}, [ "primary" ], 'bar_config output is primary'); 39 | 40 | done_testing; 41 | -------------------------------------------------------------------------------- /testcases/t/540-sigterm-cleanup.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Tests that the socket file is cleaned up properly after gracefully 18 | # shutting down i3 via SIGTERM. 19 | # Ticket: #3049 20 | use i3test i3_autostart => 0; 21 | 22 | my $config = < 1); 28 | my $socket = get_socket_path(); 29 | ok(-S $socket, "socket $socket exists"); 30 | 31 | exit_forcefully($pid, 'TERM'); 32 | 33 | ok(!-e $socket, "socket $socket no longer exists"); 34 | 35 | done_testing; 36 | -------------------------------------------------------------------------------- /testcases/t/545-i3-registration.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Tests whether our WM registration is done with the correct WM_S0 selection. 5 | 6 | use i3test; 7 | 8 | my $x = X11::XCB::Connection->new; 9 | my $reply = $x->get_selection_owner($x->atom(name => 'WM_S0')->id); 10 | ok($reply, "registration successful"); 11 | done_testing; 12 | -------------------------------------------------------------------------------- /testcases/t/546-empty-bindcommand.t: -------------------------------------------------------------------------------- 1 | #!perl 2 | # vim:ts=4:sw=4:expandtab 3 | # 4 | # Please read the following documents before working on tests: 5 | # • https://build.i3wm.org/docs/testsuite.html 6 | # (or docs/testsuite) 7 | # 8 | # • https://build.i3wm.org/docs/lib-i3test.html 9 | # (alternatively: perldoc ./testcases/lib/i3test.pm) 10 | # 11 | # • https://build.i3wm.org/docs/ipc.html 12 | # (or docs/ipc) 13 | # 14 | # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf 15 | # (unless you are already familiar with Perl) 16 | # 17 | # Test that i3 doesn't crash if the binding command is empty. 18 | # Ticket: #5000 19 | 20 | use i3test i3_autostart => 0; 21 | 22 | my $config = < 0; 22 | 23 | my $config = <" 6 | detected=0 7 | while IFS= read -r file; do 8 | if { cpp -w -fpreprocessed "$file" || exit "$?"; } | grep -E -- "$regex"; then 9 | echo "^ $file calls a function that has a safe counterpart." 10 | detected=1 11 | fi 12 | done << EOF 13 | $(find -name '*.c' -not -name safewrappers.c -not -name strndup.c) 14 | EOF 15 | if [ "$detected" -ne 0 ]; then 16 | echo 17 | echo "Calls of functions that have safe counterparts were detected." 18 | exit 1 19 | fi 20 | -------------------------------------------------------------------------------- /travis/debian-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -x 5 | 6 | DEST=$1 7 | 8 | cd distbuild 9 | # unpack dist tarball 10 | mkdir -p "${DEST}" 11 | tar xf meson-dist/*.tar.xz -C "${DEST}" --strip-components=1 12 | cp -r ../debian "${DEST}" 13 | sed -i '/^\s*libxcb-xrm-dev/d' deb/ubuntu-*/DIST/debian/control || true 14 | cd "${DEST}" 15 | debchange -m -l+g$(git describe --tags) 'Automatically built' 16 | dpkg-buildpackage -b 17 | -------------------------------------------------------------------------------- /travis/deploy-github-pages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -x 5 | 6 | GITVERSION=$(git describe --tags) 7 | 8 | mkdir build.i3wm.org 9 | cp -r deb/COPY-DOCS build.i3wm.org/docs 10 | cd build.i3wm.org 11 | echo build.i3wm.org > CNAME 12 | # Disallow search engine indexing for build.i3wm.org: users should find the 13 | # release version instead, and only developers should use build.i3wm.org. 14 | echo 'User-Agent: *' > robots.txt 15 | echo 'Disallow: /' >> robots.txt 16 | git init 17 | 18 | git config user.name "Travis CI" 19 | git config user.email "i3bot@i3wm.org" 20 | git add . 21 | git commit -m "Publish docs/static analysis for github.com/i3/i3 v${GITVERSION}" 22 | 23 | # Hide stdout/stderr because it might contain sensitive info. 24 | set +x 25 | echo "git push" 26 | git push --force --quiet "https://${GH_TOKEN}@github.com/i3/build.i3wm.org.git" master:gh-pages >/dev/null 2>&1 27 | -------------------------------------------------------------------------------- /travis/docker-build-and-push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | BASENAME=$1 6 | DOCKERFILE=$2 7 | 8 | docker build --pull --no-cache --rm -t=${BASENAME} -f ${DOCKERFILE} . 9 | # For pull requests, travis does not add secure environment variables to the 10 | # environment (because pull requests could then steal their values), so skip 11 | # the login+push step when the variable isn’t set. 12 | if [ -n "${DOCKER_PASS}" ] 13 | then 14 | docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} 15 | docker push ${BASENAME} 16 | fi 17 | -------------------------------------------------------------------------------- /travis/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -x 5 | 6 | # TODO: install the docs via meson, inject styles with an option 7 | 8 | for f in $(sed -n "s/^\s*'\(docs\/.*\)',$/\1/gp" meson.build | grep -vF .) 9 | do 10 | asciidoc -a linkcss -a stylesdir=https://i3wm.org/css -a scriptsdir=https://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf $(dirname $f)/$(basename $f .html) 11 | done 12 | 13 | ./docs/i3-pod2html --stylesurl=https://i3wm.org/css i3-dmenu-desktop man/i3-dmenu-desktop.html 14 | ./docs/i3-pod2html --stylesurl=https://i3wm.org/css i3-save-tree man/i3-save-tree.html 15 | ./docs/i3-pod2html --stylesurl=https://i3wm.org/css build/i3test.pm docs/lib-i3test.html 16 | ./docs/i3-pod2html --stylesurl=https://i3wm.org/css testcases/lib/i3test/Test.pm docs/lib-i3test-test.html 17 | 18 | for file in $(sed -n "s/^\s*'\(man\/.*\).man',$/\1.man/gp" meson.build) 19 | do 20 | [ -f "$file" ] && asciidoc -a linkcss -a stylesdir=https://i3wm.org/css -a scriptsdir=https://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf "$file" 21 | done 22 | 23 | mkdir -p deb/COPY-DOCS 24 | 25 | cp $(sed -n "s/^\s*'\(docs\/.*\)',$/\1/gp" meson.build | grep -F .) deb/COPY-DOCS/ 26 | cp $(sed -n "s/^\s*'\(man\/.*\).man',$/\1.html/gp" meson.build) deb/COPY-DOCS/ 27 | -------------------------------------------------------------------------------- /travis/ha.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Returns a hash to be used as version number suffix for the i3/travis-base 3 | # docker container. The hash is over all files which influence what gets 4 | # installed in the container, so that any changes in what needs to be installed 5 | # will result in a cache invalidation. 6 | 7 | cat debian/control "$1" | sha256sum | dd bs=1 count=8 status=none 8 | -------------------------------------------------------------------------------- /travis/push-balto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | for fn in distbuild/deb/debian-amd64/*.deb distbuild/deb/debian-i386/*.deb 6 | do 7 | echo "pushing $fn to balto" 8 | curl \ 9 | --header "Authorization: Bearer ${BALTO_TOKEN}" \ 10 | --form "package=@${fn}" \ 11 | --form distribution=all \ 12 | https://i3.baltorepo.com/i3/i3-autobuild/upload/ 13 | done 14 | 15 | for fn in distbuild/deb/ubuntu-amd64/*.deb distbuild/deb/ubuntu-i386/*.deb 16 | do 17 | echo "pushing $fn to balto" 18 | curl \ 19 | --header "Authorization: Bearer ${BALTO_TOKEN}" \ 20 | --form "package=@${fn}" \ 21 | --form distribution=all \ 22 | https://i3.baltorepo.com/i3/i3-autobuild-ubuntu/upload/ 23 | done 24 | -------------------------------------------------------------------------------- /travis/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -x 5 | 6 | cd build 7 | 8 | # TODO: remove this workaround once https://bugs.debian.org/836723 is fixed 9 | # Found at https://llvm.org/bugs/show_bug.cgi?id=27310#c8: 10 | if [ "$CC" = "clang" ] 11 | then 12 | cat >fixasan.c <