├── .editorconfig ├── .github ├── ci │ ├── Dockerfile-debian-testing │ ├── Dockerfile-ubuntu-jammy │ ├── install-deps-deb.sh │ ├── run-build.sh │ └── run-tests.sh └── workflows │ └── build-test.yml ├── .gitignore ├── CREDITS.md ├── LICENSE ├── NEWS ├── README.md ├── RELEASE.md ├── data ├── dbus │ ├── com.gexperts.Tilix.service │ └── com.gexperts.Tilix.service.in ├── gsettings │ ├── com.gexperts.Tilix.gschema.xml │ └── reset.sh ├── icons │ ├── LICENSE │ └── hicolor │ │ └── scalable │ │ └── apps │ │ ├── com.gexperts.Tilix-symbolic.svg │ │ └── com.gexperts.Tilix.svg ├── man │ ├── meson.build │ ├── po │ │ ├── ca.man.po │ │ ├── cs.man.po │ │ ├── de.man.po │ │ ├── en_GB.man.po │ │ ├── eo.man.po │ │ ├── es.man.po │ │ ├── fr.man.po │ │ ├── he.man.po │ │ ├── hi.man.po │ │ ├── hr.man.po │ │ ├── is.man.po │ │ ├── it.man.po │ │ ├── ko.man.po │ │ ├── nb_NO.man.po │ │ ├── nl.man.po │ │ ├── oc.man.po │ │ ├── pl.man.po │ │ ├── pt.man.po │ │ ├── pt_BR.man.po │ │ ├── pt_PT.man.po │ │ ├── ro.man.po │ │ ├── ru.man.po │ │ ├── sr.man.po │ │ ├── sv.man.po │ │ ├── ta.man.po │ │ ├── tilix.1.man.pot │ │ ├── tr.man.po │ │ ├── uk.man.po │ │ ├── zh_Hans.man.po │ │ └── zh_Hant.man.po │ └── tilix.1 ├── meson.build ├── metainfo │ └── com.gexperts.Tilix.appdata.xml.in ├── nautilus │ └── open-tilix.py ├── pkg │ ├── archive │ │ └── createReleaseArchive.sh │ ├── desktop │ │ └── com.gexperts.Tilix.desktop.in │ └── flatpak │ │ ├── build.sh │ │ ├── clean.sh │ │ ├── metadata │ │ └── run.sh ├── resources │ ├── css │ │ ├── tilix.Adwaita.scrollbar.css │ │ ├── tilix.Ambiance.css │ │ ├── tilix.Ambiance.scrollbar.css │ │ ├── tilix.Arc-Dark.scrollbar.css │ │ ├── tilix.Arc-Darker.scrollbar.css │ │ ├── tilix.Arc.scrollbar.css │ │ ├── tilix.Lavender.scrollbar.css │ │ ├── tilix.Radiance.css │ │ ├── tilix.Radiance.scrollbar.css │ │ ├── tilix.base.css │ │ ├── tilix.base.theme.css │ │ └── tilix.base320.css │ ├── generate-symbolic.sh │ ├── icons │ │ ├── 16x16 │ │ │ └── actions │ │ │ │ ├── tilix-add-horizontal-symbolic.symbolic.png │ │ │ │ └── tilix-add-vertical-symbolic.symbolic.png │ │ ├── 32x32 │ │ │ └── actions │ │ │ │ ├── tilix-add-horizontal-symbolic.symbolic.png │ │ │ │ └── tilix-add-vertical-symbolic.symbolic.png │ │ └── scalable │ │ │ └── actions │ │ │ ├── tilix-add-horizontal-symbolic.svg │ │ │ └── tilix-add-vertical-symbolic.svg │ ├── tilix.gresource.xml │ └── ui │ │ └── shortcuts.ui ├── schemes │ ├── base16-twilight-dark.json │ ├── linux.json │ ├── material.json │ ├── monokai.json │ ├── orchis.json │ ├── solarized-dark.json │ ├── solarized-light.json │ ├── tango.json │ └── yaru.json └── scripts │ ├── install-man-pages.sh │ └── tilix_int.sh ├── dscanner.ini ├── dub.json ├── dub.selections.json ├── experimental ├── flatpak │ ├── README.md │ ├── com.gexperts.Tilix.yaml │ ├── disable-ldc-completions.patch │ ├── dmd.conf │ ├── gtkd3-pkgconfig.patch │ ├── stemmer-dynlib.patch │ ├── tilix-flatpak-toolbox.c │ ├── vte291-command-notify-scroll-speed.patch │ └── vte291-exceptions-gcc811.patch └── vte │ ├── 0.52 │ └── alternate-screen.patch │ ├── 0.54 │ └── alternate-screen.patch │ ├── README.md │ ├── alternate-screen.patch │ └── disable-bg-draw.patch ├── extract-strings.sh ├── install.sh ├── meson.build ├── meson_post_install.py ├── po ├── LINGUAS ├── Makevars ├── POTFILES.in ├── ak.po ├── ar.po ├── ar_MA.po ├── bg.po ├── ca.po ├── cs.po ├── da.po ├── de.po ├── el.po ├── en_GB.po ├── eo.po ├── es.po ├── eu.po ├── fi.po ├── fr.po ├── gl.po ├── he.po ├── hi.po ├── hr.po ├── hu.po ├── id.po ├── is.po ├── it.po ├── ja.po ├── ko.po ├── lt.po ├── meson.build ├── mr.po ├── nb_NO.po ├── ne.po ├── nl.po ├── oc.po ├── pl.po ├── pt_BR.po ├── pt_PT.po ├── ro.po ├── ru.po ├── sr.po ├── sv.po ├── ta.po ├── tilix.pot ├── tr.po ├── uk.po ├── vi.po ├── zh_CN.po └── zh_TW.po ├── source ├── app.d ├── gx │ ├── gtk │ │ ├── actions.d │ │ ├── cairo.d │ │ ├── clipboard.d │ │ ├── color.d │ │ ├── dialog.d │ │ ├── resource.d │ │ ├── settings.d │ │ ├── threads.d │ │ ├── util.d │ │ ├── vte.d │ │ └── x11.d │ ├── i18n │ │ └── l10n.d │ ├── tilix │ │ ├── application.d │ │ ├── appwindow.d │ │ ├── bookmark │ │ │ ├── bmchooser.d │ │ │ ├── bmeditor.d │ │ │ ├── bmtreeview.d │ │ │ └── manager.d │ │ ├── closedialog.d │ │ ├── cmdparams.d │ │ ├── colorschemes.d │ │ ├── common.d │ │ ├── constants.d │ │ ├── customtitle.d │ │ ├── encoding.d │ │ ├── prefeditor │ │ │ ├── advdialog.d │ │ │ ├── bookmarkeditor.d │ │ │ ├── common.d │ │ │ ├── prefdialog.d │ │ │ ├── profileeditor.d │ │ │ └── titleeditor.d │ │ ├── preferences.d │ │ ├── session.d │ │ ├── shortcuts.d │ │ ├── sidebar.d │ │ └── terminal │ │ │ ├── actions.d │ │ │ ├── activeprocess.d │ │ │ ├── advpaste.d │ │ │ ├── exvte.d │ │ │ ├── layout.d │ │ │ ├── monitor.d │ │ │ ├── password.d │ │ │ ├── regex.d │ │ │ ├── search.d │ │ │ ├── terminal.d │ │ │ └── util.d │ └── util │ │ ├── array.d │ │ ├── path.d │ │ └── string.d ├── secret │ ├── Collection.d │ ├── Item.d │ ├── Prompt.d │ ├── Schema.d │ ├── SchemaAttribute.d │ ├── Secret.d │ ├── Service.d │ └── Value.d ├── secretc │ ├── secret.d │ └── secrettypes.d └── x11 │ ├── LICENSE │ ├── README.md │ ├── X.d │ └── Xlib.d └── uninstall.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | max_line_length = 170 5 | indent_style = space 6 | end_of_line = lf 7 | trim_trailing_whitespace = true 8 | charset = utf-8 9 | 10 | [*.yml] 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.xml] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [*.sh] 19 | indent_style = space 20 | indent_size = 2 21 | 22 | [*.d] 23 | indent_size = 4 24 | # allman, otbs or stroustrup - see https://en.wikipedia.org/wiki/Indent_style 25 | dfmt_brace_style = otbs 26 | # The formatting process will usually keep lines below this length, but they may be up to max_line_length columns long. 27 | dfmt_soft_max_line_length = 160 28 | # Place operators on the end of the previous line when splitting lines 29 | dfmt_split_operator_at_line_end = false 30 | # Insert space after the closing paren of a cast expression 31 | dfmt_space_after_cast = true 32 | # Insert space after the module name and before the : for selective imports 33 | dfmt_selective_import_space = true 34 | # Place labels on the same line as the labeled switch, for, foreach, or while statement 35 | dfmt_compact_labeled_statements = true 36 | # 37 | # Not yet implemented: 38 | # 39 | # Align labels, cases, and defaults with their enclosing switch 40 | dfmt_align_switch_statements = true 41 | # Decrease the indentation level of attributes 42 | dfmt_outdent_attributes = true 43 | # Insert space after if, while, foreach, etc, and before the ( 44 | dfmt_space_after_keywords = true 45 | -------------------------------------------------------------------------------- /.github/ci/Dockerfile-debian-testing: -------------------------------------------------------------------------------- 1 | # 2 | # Docker file for Tilix CI tests on Debian Testing 3 | # 4 | FROM debian:testing 5 | 6 | # prepare 7 | RUN mkdir -p /build/ci/ 8 | 9 | # install build dependencies 10 | COPY install-deps-deb.sh /build/ci/ 11 | RUN chmod +x /build/ci/install-deps-deb.sh && /build/ci/install-deps-deb.sh 12 | 13 | # finish 14 | WORKDIR /build 15 | -------------------------------------------------------------------------------- /.github/ci/Dockerfile-ubuntu-jammy: -------------------------------------------------------------------------------- 1 | # 2 | # Docker file for Tilix CI tests on Ubuntu Jammy 3 | # 4 | FROM ubuntu:jammy 5 | 6 | # prepare 7 | RUN mkdir -p /build/ci/ 8 | 9 | # install build dependencies 10 | COPY install-deps-deb.sh /build/ci/ 11 | RUN chmod +x /build/ci/install-deps-deb.sh && /build/ci/install-deps-deb.sh 12 | 13 | # finish 14 | WORKDIR /build 15 | -------------------------------------------------------------------------------- /.github/ci/install-deps-deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Install Tilix build dependencies 4 | # 5 | set -e 6 | set -x 7 | 8 | export DEBIAN_FRONTEND=noninteractive 9 | 10 | # update caches 11 | apt-get update -qq 12 | 13 | # install build essentials 14 | apt-get install -yq \ 15 | eatmydata \ 16 | build-essential 17 | 18 | # install build dependencies 19 | eatmydata apt-get install -yq \ 20 | meson \ 21 | ninja-build \ 22 | appstream \ 23 | desktop-file-utils \ 24 | dh-dlang \ 25 | ldc \ 26 | libgtkd-3-dev \ 27 | librsvg2-dev \ 28 | libsecret-1-dev \ 29 | libunwind-dev \ 30 | libvted-3-dev \ 31 | po4a 32 | -------------------------------------------------------------------------------- /.github/ci/run-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # This script is supposed to run inside the Tilix Docker container 5 | # on the CI system. 6 | 7 | # 8 | # Read options for the current test build 9 | # 10 | 11 | build_type=debugoptimized 12 | build_dir="cibuild" 13 | 14 | export DC=ldc2 15 | echo "D compiler: $DC" 16 | set -x 17 | $DC --version 18 | 19 | # 20 | # Configure build with all flags enabled 21 | # 22 | 23 | mkdir $build_dir && cd $build_dir 24 | meson --buildtype=$build_type \ 25 | .. 26 | 27 | # 28 | # Build & Install 29 | # 30 | 31 | ninja 32 | DESTDIR=/tmp/install_root/ ninja install 33 | rm -r /tmp/install_root/ 34 | -------------------------------------------------------------------------------- /.github/ci/run-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # This script is supposed to run inside the Tilix Docker container 5 | # on the CI system. 6 | 7 | # 8 | # Read options for the current test run 9 | # 10 | 11 | export DC=ldc2 12 | build_dir="cibuild" 13 | 14 | # 15 | # Run tests 16 | # 17 | 18 | cd $build_dir 19 | meson test --print-errorlogs 20 | -------------------------------------------------------------------------------- /.github/workflows/build-test.yml: -------------------------------------------------------------------------------- 1 | name: Build Test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | 11 | build-dub-ubuntu: 12 | name: Dub 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | dc: [dmd-latest, ldc-latest] 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - name: Install System Dependencies 21 | run: | 22 | sudo apt-get update -qq 23 | sudo apt-get install -yq \ 24 | dh-dlang \ 25 | libatk1.0-dev \ 26 | libcairo2-dev \ 27 | libglib2.0-dev \ 28 | libgtk-3-dev \ 29 | libpango1.0-dev \ 30 | librsvg2-dev \ 31 | libsecret-1-dev \ 32 | libunwind-dev \ 33 | libgtksourceview-3.0-dev \ 34 | libpeas-dev \ 35 | libvte-2.91-dev 36 | 37 | - name: Install D compiler 38 | uses: dlang-community/setup-dlang@v1 39 | with: 40 | compiler: ${{ matrix.dc }} 41 | 42 | - name: Build 43 | run: dub build --compiler=$DC 44 | 45 | - name: Test 46 | run: dub test --compiler=$DC 47 | 48 | 49 | build-debian-testing: 50 | name: Debian Testing 51 | runs-on: ubuntu-latest 52 | steps: 53 | - uses: actions/checkout@v2 54 | 55 | - name: Create Build Environment 56 | run: cd .github/ci/ && podman build -t tilix -f ./Dockerfile-debian-testing . 57 | 58 | - name: Build 59 | run: podman run -t -e COMPILER_VENDOR=$CVENDOR -e CC=gcc -e CXX=g++ -v `pwd`:/build tilix 60 | ./.github/ci/run-build.sh 61 | 62 | - name: Test 63 | run: podman run -t -e COMPILER_VENDOR=$CVENDOR -e CC=gcc -e CXX=g++ -v `pwd`:/build tilix 64 | ./.github/ci/run-tests.sh 65 | 66 | 67 | build-ubuntu: 68 | name: Ubuntu LTS 69 | runs-on: ubuntu-latest 70 | steps: 71 | - uses: actions/checkout@v2 72 | 73 | - name: Create Build Environment 74 | run: cd .github/ci/ && podman build -t tilix -f ./Dockerfile-ubuntu-jammy . 75 | 76 | - name: Build 77 | run: podman run -t -e COMPILER_VENDOR=$CVENDOR -e CC=gcc -e CXX=g++ -v `pwd`:/build tilix 78 | ./.github/ci/run-build.sh 79 | 80 | - name: Test 81 | run: podman run -t -e COMPILER_VENDOR=$CVENDOR -e CC=gcc -e CXX=g++ -v `pwd`:/build tilix 82 | ./.github/ci/run-tests.sh 83 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .flatpak-builder/ 2 | .dub 3 | docs.json 4 | __dummy.html 5 | *.o 6 | *.obj 7 | *.zip 8 | /tilix 9 | __test__library__ 10 | .vscode 11 | backup 12 | tilix.gresource 13 | data/pkg/arch/pkg 14 | data/pkg/arch/src 15 | data/pkg/desktop/com.gexperts.Tilix.desktop 16 | data/metainfo/com.gexperts.Tilix.appdata.xml 17 | data/man/man 18 | *.pkg.tar.xz 19 | *~ 20 | *.xdgapp 21 | build/builddir 22 | .xdg-app-builder 23 | 24 | ABOUT-NLS 25 | Makefile 26 | Makefile.in 27 | acaux/ 28 | aclocal.m4 29 | autom4te.cache/ 30 | config.log 31 | config.status 32 | configure 33 | data/icons/Makefile 34 | data/icons/Makefile.in 35 | data/resources/Makefile 36 | data/resources/Makefile.in 37 | m4/ 38 | po/Makefile 39 | po/Makefile.in 40 | po/Makefile.in.in 41 | po/Makevars.template 42 | po/POTFILES 43 | po/Rules-quot 44 | po/boldquot.sed 45 | po/en@boldquot.header 46 | po/en@quot.header 47 | po/insert-header.sin 48 | po/quot.sed 49 | po/remove-potcdate.sin 50 | po/stamp-po 51 | po/*.gmo 52 | po/remove-potcdate.sed 53 | -------------------------------------------------------------------------------- /CREDITS.md: -------------------------------------------------------------------------------- 1 | Credits 2 | ======= 3 | 4 | I would like to thank the following people and organizations without 5 | whom this project would not be where it is today. If I am missing anyone, 6 | please feel free to let me know or update this file via a pull request. 7 | 8 | * Gerald Nunn 9 | * Philip Wolfer 10 | * dsboger 11 | * Egmont Koblinger 12 | * Bilal Elmoussaoui 13 | * Alex Diavatis 14 | * Alex Whitman 15 | * Boiethios 16 | * Matthias Clausen 17 | * Christian Herget 18 | * Allan Day 19 | 20 | While not directly contributing to Tilix, I would also like to thank the following 21 | people and organizations for their contributions to projects without whose existence 22 | Tilix would not exist. 23 | 24 | * Christian Pesch for GTK VTE 25 | * Mike Wey for GtkD 26 | * The D Foundation 27 | * Gnome Project, http://www.gnome.org 28 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | Version 1.9.6 2 | ~~~~~~~~~~~~~~ 3 | Released: 2023-11-08 4 | 5 | Features: 6 | * Add close button to search box 7 | * Replace variables in custom link commands 8 | * Follow system color-scheme for default theme-variant 9 | 10 | Bugfixes: 11 | * nautilus: Don't import a specific version 12 | * nautilus: Add compatibility with Nautilus 43 13 | * nautilus: Avoid shell injection in open-tilix plugin 14 | * Drop manpage country names 15 | * Replace std.xml with GMarkup-based parser 16 | * icon: Fix up prompt pictogram alignment 17 | * Fix GLib critical warnings on startup 18 | 19 | Miscellaneous: 20 | * Change Gnome to GNOME 21 | * Replaced icon with more proportional one 22 | * Update to GtkD 3.10.0 23 | * ci: Run Ubuntu builds in container as well 24 | * Change label of "view shortcuts" action 25 | * Clarify tooltip of "reset to default" button for keyboard shortcuts 26 | 27 | Contributors: 28 | Aaron Honeycutt, Andrea Agosti, Arne Jørgensen, Eugene Ivanov, 29 | Felix Buehler, Jeremy Bicha, Jiehong Ma, Matthias Klumpp, 30 | Waldir Pimenta, Zsombor Welker, taoky 31 | 32 | Version 1.9.5 33 | ~~~~~~~~~~~~~~ 34 | Released: 2022-02-22 35 | 36 | Notes: 37 | * Tilix is still looking for a new maintainer! 38 | 39 | Features: 40 | * Disable advanced paste when there is no linebreak like iTerm2 41 | * Add environment variable when in quake mode 42 | * Add possibility to configure always enabled regex 43 | 44 | Bugfixes: 45 | * More appdata -> metainfo move 46 | * Add meson target for man page translations 47 | * Update flatpak manifest 48 | * meson: drop unused argument for i18n.merge_file() 49 | * Stop using deprecated Meson features 50 | * Keep quake window open if focus is restored before timeout has been reached 51 | * Don't check GtkDragResult (Wayland compatibility) 52 | * Don't add application/x-rootwindow-drop to dragSourceSet targets 53 | 54 | Contributors: 55 | Alan Scherger, Antoine Belvire, David King, Jan Beich, 56 | kohnish, luk1337, matishadow, Winston Hoy, Matthias Klumpp 57 | 58 | Version 1.9.4 59 | ~~~~~~~~~~~~~ 60 | Released: 2021-02-10 61 | 62 | Notes: 63 | * Tilix is looking for maintainers! At the moment, only very minimal maintenance is done, 64 | no new features will be implemented and pull-requests may be reviewed very slowly. 65 | 66 | If you are interested in helping Tilix, please chime in! 67 | 68 | Features: 69 | * Actually install Yaru color scheme 70 | * Give every tab the ${title} (instead of "Default") 71 | * Add option to strip trailing whitespace on paste (#1904) 72 | 73 | Bugfixes: 74 | * Fix saving of already saved session 75 | * Add shortcut to "Unselect all" 76 | * Many Meson buildsystem fixes 77 | * Avoid missing the previous command exit code when encoding URLs 78 | * Resolve some D deprecation messages 79 | * Mention powerline/fonts in README 80 | * Avoid calling `values()` on a shared object 81 | * Update metainfo data 82 | * Drop compat code for older D frontend versions 83 | * Bump minimum VTE version to 0.46 84 | * Remove deprecated Autotools support 85 | * Add release notes, NEWS file, automatic metainfo update 86 | * Update to GtkD 3.9.0 87 | 88 | Translations: 89 | * This release contains many localization updates 90 | 91 | Version 1.9.3 92 | ~~~~~~~~~~~~~ 93 | Released: 2019-05-04 94 | 95 | Bugfixes: 96 | * Fixes a problem with the session sidebar getting out of sync 97 | after having deleted a session. See issues #1680, #1637 and #1699. 98 | 99 | Version 1.9.1 100 | ~~~~~~~~~~~~~ 101 | Released: 2019-03-17 102 | 103 | Bugfixes: 104 | * Remove app menu for gnome 3.32 105 | * Update icon 106 | * Minor fixes 107 | 108 | Version 1.8.9 109 | ~~~~~~~~~~~~~ 110 | Released: 2019-01-06 111 | 112 | Bugfixes: 113 | * Small release to update localizations 114 | * Update to GtkD 3.8.5 to fix library name in GtkD. 115 | 116 | Version 1.8.7 117 | ~~~~~~~~~~~~~ 118 | Released: 2019-01-03 119 | 120 | Notes: 121 | * Some new features and bug fixes. 122 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | Tilix Release Notes 2 | =================== 3 | 4 | 1. Ensure `master` branch is up to date (`git pull`) 5 | 6 | 2. Manually write NEWS entries for Tilix in the same format as usual. 7 | 8 | `git shortlog 1.9.6.. | grep -i -v trivial | grep -v Merge > NEWS.new` 9 | 10 | ``` 11 | Version 1.9.7 12 | ~~~~~~~~~~~~~~ 13 | Released: 2024-xx-xx 14 | 15 | Notes: 16 | 17 | Features: 18 | 19 | Bugfixes: 20 | 21 | Miscellaneous: 22 | 23 | Contributors: 24 | ``` 25 | 26 | 3. Run `extract-strings.sh` script 27 | 28 | 4. Commit l10n changes to Git 29 | 30 | 5. Commit NEWS and other changes to Git, tag release: 31 | ``` 32 | git commit -a -m "Release version 1.9.7" 33 | git tag -s -f -m "Release 1.9.7" 1.9.7 34 | git push --tags 35 | git push 36 | ``` 37 | 38 | 6. Make release for the new tag in GitHub 39 | 40 | 7. Do post-release version bump in `meson.build`, `source/gx/tilix/constants.d` and `RELEASE.md` 41 | 42 | 8. Commit trivial changes: 43 | ``` 44 | git commit -a -m "trivial: post release version bump" 45 | git push 46 | ``` 47 | -------------------------------------------------------------------------------- /data/dbus/com.gexperts.Tilix.service: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=com.gexperts.Tilix 3 | Exec=/usr/bin/tilix --gapplication-service 4 | -------------------------------------------------------------------------------- /data/dbus/com.gexperts.Tilix.service.in: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=com.gexperts.Tilix 3 | Exec=@bindir@/tilix --gapplication-service 4 | -------------------------------------------------------------------------------- /data/gsettings/reset.sh: -------------------------------------------------------------------------------- 1 | # Resets Tilix settings to default for testing purposes 2 | gsettings list-schemas | grep Tilix | xargs -n 1 gsettings reset-recursively 3 | dconf list /com/gexperts/Tilix/profiles/ | xargs -I {} dconf reset -f "/com/gexperts/Tilix/profiles/"{} 4 | -------------------------------------------------------------------------------- /data/icons/LICENSE: -------------------------------------------------------------------------------- 1 | The icons in Tilix are licenced under the terms of either the GNU LGPL v3 or 2 | Creative Commons Attribution-Share Alike 3.0 United States License. 3 | 4 | To view a copy of the CC-BY-SA licence, visit 5 | http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative 6 | Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA. 7 | 8 | The icons were donated by or inspired from the GNOME Project (http://www.gnome.org) -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/apps/com.gexperts.Tilix-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 12 | 14 | 15 | 17 | image/svg+xml 18 | 20 | Gnome Symbolic Icon Theme 21 | 22 | 23 | 24 | Gnome Symbolic Icon Theme 26 | 28 | 31 | 34 | 38 | 45 | 49 | 56 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/apps/com.gexperts.Tilix.svg: -------------------------------------------------------------------------------- 1 | 2 | 162 | -------------------------------------------------------------------------------- /data/man/meson.build: -------------------------------------------------------------------------------- 1 | install_man('tilix.1') 2 | 3 | po4a = find_program('po4a-translate', required: false) 4 | 5 | if po4a.found() 6 | 7 | locales = [ 'ca', 'cs', 'de', 'es', 'fr', 'hr', 'it', 'nl', 8 | 'oc', 'pl', 'pt_BR', 'pt', 'ro', 'ru', 'sr', 'tr', 9 | 'uk', 'zh_Hant' ] 10 | 11 | foreach locale : locales 12 | custom_target('man_' + locale, 13 | output: locale, 14 | input: [ 'tilix.1', 'po/' + locale + '.man.po' ], 15 | command: [ po4a, '--keep', '0', 16 | '--format', 'man', 17 | '--master', '@INPUT0@', 18 | '--po', '@INPUT1@', 19 | '--localized', '@OUTPUT@/man1/tilix.1'], 20 | install: true, 21 | install_dir: get_option('mandir') 22 | ) 23 | endforeach 24 | 25 | endif 26 | -------------------------------------------------------------------------------- /data/man/tilix.1: -------------------------------------------------------------------------------- 1 | .\" Manpage for Tilix. 2 | .\" add issues at https://github.com/gnunn1/tilix to correct errors or typos. 3 | .TH TILIX 1 "26 December 2016" "1.4.0" "Tilix Commands" 4 | .SH NAME 5 | \fBtilix\fP \- Tiling GTK3 terminal emulator for GNOME 6 | .SH SYNOPSIS 7 | .B tilix 8 | .RI [ options ] 9 | .SH DESCRIPTION 10 | \fBtilix\fP is an advanced GTK3 tiling terminal emulator designed to adhere to GNOME Human Interface Guidelines. 11 | .SH OPTIONS 12 | The \fBtilix\fP application accepts the following command line parameters: 13 | .TP 14 | .B \-h \-\-help 15 | Show help options. 16 | .TP 17 | .B \-v \-\-version 18 | Show the version of Tilix as well as the versions of dependent components. 19 | .TP 20 | .B \-w \-\-working-directory=DIRECTORY 21 | Set the working directory of the terminal. 22 | .TP 23 | .B \-p \-\-profile=PROFILE_NAME 24 | Set the starting profile using the name of one of the existing profiles. If it matches none of those, the default profile will be used. 25 | .TP 26 | .B \-t \-\-title=TITLE 27 | Set the title of the new terminal. 28 | .TP 29 | .B \-s \-\-session=SESSION_NAME 30 | Specify a previously saved session to re-load the layout and layout options from. This will not restore the terminal to where it was left off, rather new terminals are created. 31 | .TP 32 | .B \-a \-\-action=ACTION_NAME 33 | Perform one of the following actions in the current Tilix instance: 34 | .IP 35 | .B session-add-right 36 | Add a new terminal rightwards of the current one. 37 | .IP 38 | .B session-add-down 39 | Add a new terminal below the current terminal. 40 | .IP 41 | .B app-new-session 42 | Create a new Tilix session within the current window. 43 | .IP 44 | .B app-new-window 45 | Create a new Tilix window. 46 | .TP 47 | .B \-e \-\-command=COMMAND 48 | Execute all text after this parameter as a command, thus this parameter must be the last parameter. 49 | .TP 50 | .B \-\-maximize 51 | Maximize the terminal window. 52 | .TP 53 | .B \-\-minimize 54 | Minimize the terminal window. 55 | .TP 56 | .B \-\-full\-screen 57 | Full-screen the terminal window. 58 | .TP 59 | .B \-\-focus\-window 60 | Focus the existing window. 61 | .TP 62 | .B \-\-window\-style=WINDOW_STYLE 63 | Override the preferred window style, the following styles are supported: 64 | .IP 65 | .B normal 66 | Normal window look. 67 | .IP 68 | .B disable-csd 69 | Do not show client side decorations. 70 | .IP 71 | .B disable-csd-hide-toolbar 72 | Do not show client side decorations and toolbar. 73 | .IP 74 | .B borderless 75 | Do not show window borders. 76 | .TP 77 | .B \-\-new\-process 78 | Start an additional Tilix instance as a new process. By default and as per GTK+ version 3 guidelines, Tilix maintains a single process that all windows belong to. This option forces Tilix to start as a separate process. This is not recommended and only intended for debugging purposes. Its use will prevent different Tilix windows from communicating with each other. 79 | .TP 80 | .B \-\-geometry=GEOMETRY 81 | Set the window size; for example: 80x24, or 80x24+200+200 (COLSxROWS+X+Y). 82 | .TP 83 | .B \-q \-\-quake 84 | Open a window in Quake mode or toggle existing Quake mode window visibility. 85 | .TP 86 | .B \-\-preferences 87 | Show the Tilix preferences dialog directly. 88 | .TP 89 | .B \-\-display=DISPLAY 90 | Use the specified X display. 91 | .SH SEE ALSO 92 | None 93 | .SH BUGS 94 | See bugs at https://github.com/gnunn1/tilix/issues 95 | .SH AUTHOR 96 | Gerald Nunn and other contributors. 97 | -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | subdir('man') 2 | 3 | # install the icons 4 | install_data( 5 | 'icons/hicolor/scalable/apps/@0@.svg'.format(project_id), 6 | install_dir: iconsdir / 'scalable' / 'apps' 7 | ) 8 | install_data( 9 | 'icons/hicolor/scalable/apps/@0@-symbolic.svg'.format(project_id), 10 | install_dir: iconsdir / 'symbolic' / 'apps' 11 | ) 12 | 13 | # Install the desktop file 14 | desktop_file = i18n.merge_file( 15 | output: '@BASENAME@', 16 | input: 'pkg/desktop/@0@.desktop.in'.format(project_id), 17 | po_dir: meson.project_source_root() / 'po', 18 | type: 'desktop', 19 | install: true, 20 | install_dir: appdir 21 | ) 22 | 23 | # Validate desktop file 24 | desktop_file_validate = find_program('desktop-file-validate', required: false) 25 | if desktop_file_validate.found() 26 | test ( 27 | 'Validate desktop file', 28 | desktop_file_validate, 29 | args: desktop_file.full_path() 30 | ) 31 | endif 32 | 33 | # Merge release information into MetaInfo file 34 | tilix_metainfo_name = '@0@.appdata.xml'.format(project_id) 35 | appstreamcli = find_program('appstreamcli') 36 | metainfo_with_releases = custom_target('metainfo-news-merge', 37 | input : ['../NEWS', 'metainfo/@0@.in'.format(tilix_metainfo_name)], 38 | output : ['untranslated-@0@.appdata.xml'.format(project_id)], 39 | command : [appstreamcli, 'news-to-metainfo', '--limit=6', '@INPUT0@', '@INPUT1@', '@OUTPUT@'] 40 | ) 41 | 42 | # Install the MetaInfo file 43 | metainfo_file = i18n.merge_file( 44 | output: tilix_metainfo_name, 45 | input: metainfo_with_releases, 46 | po_dir: meson.project_source_root() / 'po', 47 | install: true, 48 | install_dir: datadir / 'metainfo' 49 | ) 50 | 51 | # Validate MetaInfo file 52 | if appstreamcli.found() 53 | test ( 54 | 'Validate metainfo file', 55 | appstreamcli, 56 | args: ['validate', '--no-net', 57 | join_paths(meson.current_source_dir(), 'metainfo', '@0@.in'.format(tilix_metainfo_name)) 58 | ] 59 | ) 60 | endif 61 | 62 | # Build resources 63 | gresource = gnome.compile_resources( 64 | 'tilix', 65 | 'resources/tilix.gresource.xml', 66 | gresource_bundle: true, 67 | install: true, 68 | source_dir: 'resources/', 69 | install_dir: pkgdatadir / 'resources' 70 | ) 71 | 72 | # Install GSchemas 73 | install_data( 74 | 'gsettings/@0@.gschema.xml'.format(project_id), 75 | install_dir: schemadir 76 | ) 77 | 78 | # Color schemes 79 | install_data( 80 | [ 81 | 'schemes/base16-twilight-dark.json', 82 | 'schemes/linux.json', 83 | 'schemes/material.json', 84 | 'schemes/monokai.json', 85 | 'schemes/orchis.json', 86 | 'schemes/solarized-dark.json', 87 | 'schemes/solarized-light.json', 88 | 'schemes/tango.json', 89 | 'schemes/yaru.json', 90 | ], 91 | install_dir: pkgdatadir / 'schemes' 92 | ) 93 | 94 | # Scripts 95 | install_data( 96 | 'scripts/tilix_int.sh', 97 | install_dir: pkgdatadir / 'scripts' 98 | ) 99 | 100 | # Copying Nautilus extension 101 | install_data( 102 | 'nautilus/open-tilix.py', 103 | install_dir: datadir / 'nautilus-python' / 'extensions' 104 | ) 105 | 106 | # Copy D-Bus service descriptor 107 | conf = configuration_data() 108 | conf.set('bindir', bindir) 109 | 110 | configure_file( 111 | input: 'dbus/@0@.service.in'.format(project_id), 112 | output: '@BASENAME@', 113 | configuration: conf, 114 | install_dir: datadir / 'dbus-1' / 'services' 115 | ) 116 | -------------------------------------------------------------------------------- /data/metainfo/com.gexperts.Tilix.appdata.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | com.gexperts.Tilix 5 | CC0-1.0 6 | MPL-2.0 7 | 8 | Tilix 9 | A tiling terminal for GNOME 10 | 11 | 12 | pointing 13 | keyboard 14 | 15 | 16 | 17 |

18 | Tilix is a tiling terminal emulator. 19 |

20 |

It lets you:

21 |
    22 |
  • Layout terminals in any fashion by splitting them horizontally or vertically
  • 23 |
  • Terminals can be re-arranged using drag and drop both within and between windows
  • 24 |
  • Terminals can be detached into a new window via drag and drop
  • 25 |
  • Input can be synchronized between terminals so commands typed in one terminal are replicated to the others
  • 26 |
  • The grouping of terminals can be saved and loaded from disk
  • 27 |
  • Terminals support custom titles
  • 28 |
  • Color schemes are stored in files and custom color schemes can be created by simply creating a new file
  • 29 |
  • Transparent background
  • 30 |
  • Supports notifications when processes are completed out of view
  • 31 |
32 |

33 | The application was written using GTK 3 and an effort was made to conform to 34 | GNOME Human Interface Guidelines (HIG). As a result, it does use client-side-decorations, though it can be disabled if necessary. 35 |

36 |

Tilix has been tested with GNOME and with Unity.

37 |
38 | 39 | 40 | 41 | https://gnunn1.github.io/tilix-web/assets/images/gallery/tilix-screenshot-1.png 42 | 43 | 44 | https://gnunn1.github.io/tilix-web/assets/images/gallery/tilix-screenshot-2.png 45 | 46 | 47 | https://gnunn1.github.io/tilix-web/assets/images/gallery/tilix-screenshot-3.png 48 | 49 | 50 | 51 | https://gnunn1.github.io/tilix-web/ 52 | https://gnunn1.github.io/tilix-web/manual/ 53 | https://gnunn1.github.io/tilix-web/faq 54 | https://github.com/gnunn1/tilix/issues 55 | https://hosted.weblate.org/projects/tilix/translations/ 56 | 57 | tilix 58 | com.gexperts.Tilix.desktop 59 | 60 | 61 | 62 | Gerald Nunn 63 | 64 | 65 | 66 | tilix 67 | 68 |
69 | -------------------------------------------------------------------------------- /data/nautilus/open-tilix.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | # This example is contributed by Martin Enlund 3 | # Example modified for Tilix 4 | # Shortcuts Provider was inspired by captain nemo extension 5 | 6 | from gettext import gettext, textdomain 7 | from subprocess import Popen 8 | import shutil 9 | import shlex 10 | try: 11 | from urllib import unquote 12 | from urlparse import urlparse 13 | except ImportError: 14 | from urllib.parse import unquote, urlparse 15 | 16 | 17 | from gi.repository import Gio, GObject, Nautilus 18 | from gi import require_version 19 | if hasattr(Nautilus, "LocationWidgetProvider"): 20 | require_version('Gtk', '3.0') 21 | from gi.repository import Gtk 22 | 23 | 24 | TERMINAL = shutil.which("tilix") 25 | TILIX_KEYBINDINGS = "com.gexperts.Tilix.Keybindings" 26 | GSETTINGS_OPEN_TERMINAL = "nautilus-open" 27 | REMOTE_URI_SCHEME = ['ftp', 'sftp'] 28 | textdomain("tilix") 29 | _ = gettext 30 | 31 | def _checkdecode(s): 32 | """Decode string assuming utf encoding if it's bytes, else return unmodified""" 33 | return s.decode('utf-8') if isinstance(s, bytes) else s 34 | 35 | def open_terminal_in_file(filename): 36 | if filename: 37 | Popen([TERMINAL, '-w', filename]) 38 | else: 39 | Popen([TERMINAL]) 40 | 41 | # Nautilus 43 doesn't offer the LocationWidgetProvider any more 42 | if hasattr(Nautilus, "LocationWidgetProvider"): 43 | class OpenTilixShortcutProvider(GObject.GObject, 44 | Nautilus.LocationWidgetProvider): 45 | 46 | def __init__(self): 47 | source = Gio.SettingsSchemaSource.get_default() 48 | if source.lookup(TILIX_KEYBINDINGS, True): 49 | self._gsettings = Gio.Settings.new(TILIX_KEYBINDINGS) 50 | self._gsettings.connect("changed", self._bind_shortcut) 51 | self._create_accel_group() 52 | self._window = None 53 | self._uri = None 54 | 55 | def _create_accel_group(self): 56 | self._accel_group = Gtk.AccelGroup() 57 | shortcut = self._gsettings.get_string(GSETTINGS_OPEN_TERMINAL) 58 | key, mod = Gtk.accelerator_parse(shortcut) 59 | self._accel_group.connect(key, mod, Gtk.AccelFlags.VISIBLE, 60 | self._open_terminal) 61 | 62 | def _bind_shortcut(self, gsettings, key): 63 | if key == GSETTINGS_OPEN_TERMINAL: 64 | self._accel_group.disconnect(self._open_terminal) 65 | self._create_accel_group() 66 | 67 | def _open_terminal(self, *args): 68 | filename = unquote(self._uri[7:]) 69 | open_terminal_in_file(filename) 70 | 71 | def get_widget(self, uri, window): 72 | self._uri = uri 73 | if self._window: 74 | self._window.remove_accel_group(self._accel_group) 75 | if self._gsettings: 76 | window.add_accel_group(self._accel_group) 77 | self._window = window 78 | return None 79 | 80 | 81 | class OpenTilixExtension(GObject.GObject, Nautilus.MenuProvider): 82 | 83 | def _open_terminal(self, file_): 84 | if file_.get_uri_scheme() in REMOTE_URI_SCHEME: 85 | result = urlparse(file_.get_uri()) 86 | if result.username: 87 | value = 'ssh -t {0}@{1}'.format(result.username, 88 | result.hostname) 89 | else: 90 | value = 'ssh -t {0}'.format(result.hostname) 91 | if result.port: 92 | value = "{0} -p {1}".format(value, result.port) 93 | if file_.is_directory(): 94 | value = '{0} cd {1} ; $SHELL'.format(value, shlex.quote(result.path)) 95 | 96 | Popen([TERMINAL, '-e', value]) 97 | else: 98 | filename = Gio.File.new_for_uri(file_.get_uri()).get_path() 99 | open_terminal_in_file(filename) 100 | 101 | def _menu_activate_cb(self, menu, file_): 102 | self._open_terminal(file_) 103 | 104 | def _menu_background_activate_cb(self, menu, file_): 105 | self._open_terminal(file_) 106 | 107 | def get_file_items(self, *args): 108 | files = args[-1] 109 | if len(files) != 1: 110 | return 111 | items = [] 112 | file_ = files[0] 113 | 114 | if file_.is_directory(): 115 | 116 | if file_.get_uri_scheme() in REMOTE_URI_SCHEME: 117 | uri = _checkdecode(file_.get_uri()) 118 | item = Nautilus.MenuItem(name='NautilusPython::open_remote_item', 119 | label=_(u'Open Remote Tilix'), 120 | tip=_(u'Open Remote Tilix In {}').format(uri)) 121 | item.connect('activate', self._menu_activate_cb, file_) 122 | items.append(item) 123 | 124 | filename = _checkdecode(file_.get_name()) 125 | item = Nautilus.MenuItem(name='NautilusPython::open_file_item', 126 | label=_(u'Open In Tilix'), 127 | tip=_(u'Open Tilix In {}').format(filename)) 128 | item.connect('activate', self._menu_activate_cb, file_) 129 | items.append(item) 130 | 131 | return items 132 | 133 | def get_background_items(self, *args): 134 | file_ = args[-1] 135 | items = [] 136 | if file_.get_uri_scheme() in REMOTE_URI_SCHEME: 137 | item = Nautilus.MenuItem(name='NautilusPython::open_bg_remote_item', 138 | label=_(u'Open Remote Tilix Here'), 139 | tip=_(u'Open Remote Tilix In This Directory')) 140 | item.connect('activate', self._menu_activate_cb, file_) 141 | items.append(item) 142 | 143 | item = Nautilus.MenuItem(name='NautilusPython::open_bg_file_item', 144 | label=_(u'Open Tilix Here'), 145 | tip=_(u'Open Tilix In This Directory')) 146 | item.connect('activate', self._menu_background_activate_cb, file_) 147 | items.append(item) 148 | return items 149 | -------------------------------------------------------------------------------- /data/pkg/archive/createReleaseArchive.sh: -------------------------------------------------------------------------------- 1 | export TILIX_ARCHIVE_PATH="/tmp/tilix/archive"; 2 | 3 | rm -rf ${TILIX_ARCHIVE_PATH} 4 | 5 | CURRENT_DIR=$(pwd) 6 | 7 | echo "Building application..." 8 | cd ../../.. 9 | dub build --build=release --compiler=ldc2 10 | strip tilix 11 | 12 | ./install.sh ${TILIX_ARCHIVE_PATH}/usr 13 | 14 | # Remove compiled schema 15 | rm ${TILIX_ARCHIVE_PATH}/usr/share/glib-2.0/schemas/gschemas.compiled 16 | 17 | echo "Creating archive" 18 | cd ${TILIX_ARCHIVE_PATH} 19 | zip -r tilix.zip * 20 | 21 | cp tilix.zip ${CURRENT_DIR}/tilix.zip 22 | cd ${CURRENT_DIR} 23 | -------------------------------------------------------------------------------- /data/pkg/desktop/com.gexperts.Tilix.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Version=1.0 3 | Name=Tilix 4 | Comment=A tiling terminal for GNOME 5 | Keywords=shell;prompt;command;commandline;cmd; 6 | Exec=tilix 7 | Terminal=false 8 | Type=Application 9 | StartupNotify=true 10 | Categories=System;TerminalEmulator;X-GNOME-Utilities; 11 | Icon=com.gexperts.Tilix 12 | DBusActivatable=true 13 | Actions=new-window;new-session;preferences; 14 | 15 | [Desktop Action new-window] 16 | Name=New Window 17 | Exec=tilix --action=app-new-window 18 | 19 | [Desktop Action new-session] 20 | Name=New Session 21 | Exec=tilix --action=app-new-session 22 | 23 | [Desktop Action preferences] 24 | Name=Preferences 25 | Exec=tilix --preferences 26 | -------------------------------------------------------------------------------- /data/pkg/flatpak/build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | CURRENT_DIR=$(pwd) 4 | 5 | ./clean.sh 6 | 7 | flatpak build-init terminix com.gexperts.Terminix org.gnome.Sdk org.gnome.Platform 3.22 8 | 9 | cd ../../.. 10 | 11 | dub build --build=release 12 | ./install.sh ${CURRENT_DIR}/terminix/files 13 | 14 | cd ${CURRENT_DIR} 15 | 16 | flatpak build-finish --socket=x11 --socket=wayland --socket=pulseaudio --device=dri --filesystem=host --filesystem=home --filesystem=~/.config/dconf:ro --filesystem=xdg-run/dconf --talk-name=org.freedesktop.Flatpak --talk-name=ca.desrt.dconf --env=DCONF_USER_CONFIG_DIR=.config/dconf --allow=devel terminix 17 | 18 | flatpak build-export repo terminix 19 | 20 | flatpak --user remote-add --no-gpg-verify terminix-repo repo 21 | flatpak --user install terminix-repo com.gexperts.Terminix 22 | -------------------------------------------------------------------------------- /data/pkg/flatpak/clean.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | flatpak --user uninstall com.gexperts.Terminix 4 | flatpak --user remote-delete terminix-repo 5 | 6 | rm -rf terminix 7 | rm -rf repo 8 | -------------------------------------------------------------------------------- /data/pkg/flatpak/metadata: -------------------------------------------------------------------------------- 1 | [Application] 2 | name=com.gexperts.Terminix 3 | runtime=org.gnome.Platform/x86_64/3.22 4 | sdk=org.gnome.Sdk/x86_64/3.22 5 | command=terminix 6 | 7 | [Context] 8 | shared=ipc;network; 9 | sockets=x11;wayland;pulseaudio; 10 | devices=dri; 11 | filesystems=host;~/.config/dconf:ro;xdg-run/dconf; 12 | talk-name=ca.desrt.dconf 13 | 14 | [Environment] 15 | DCONF_USER_CONFIG_DIR=.config/dconf 16 | 17 | [Session Bus Policy] 18 | -------------------------------------------------------------------------------- /data/pkg/flatpak/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | flatpak run com.gexperts.Terminix -------------------------------------------------------------------------------- /data/resources/css/tilix.Adwaita.scrollbar.css: -------------------------------------------------------------------------------- 1 | /* GTK 3.20 */ 2 | scrollbar { 3 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 4 | } 5 | /* GTK 3.18 */ 6 | .scrollbar:not(.slider) { 7 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 8 | border-left: 0px; 9 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.Ambiance.css: -------------------------------------------------------------------------------- 1 | /** Ambiance specific CSS to fix Ubuntu problems so the rest of us can have nice things **/ 2 | 3 | /* Fix Ubuntu Popover label borders, see #217 */ 4 | GtkBox > .label.separator { 5 | border: 0px; 6 | color: @theme_fg_color; 7 | opacity: 0.4; 8 | } 9 | 10 | /* Attempt to improve scrollbars */ 11 | .tilix-terminal-scrollbar:hover:not(.slider), 12 | .tilix-terminal-scrollbar.dragging:not(.slider) { 13 | background-color: alpha(@scrollbar_track_color, 0.4); 14 | } 15 | 16 | /* Since .hovering class is not working here, we always use the same radius */ 17 | .tilix-terminal-scrollbar.slider.hovering, 18 | .tilix-terminal-scrollbar.slider.dragging { 19 | border-left: 0px; 20 | } 21 | 22 | .tilix-terminal-scrollbar.vertical:hover:dir(ltr), 23 | .tilix-terminal-scrollbar.vertical.dragging:dir(ltr) { 24 | margin-left: 0px; 25 | } 26 | 27 | .tilix-terminal-scrollbar.vertical:hover:dir(rtl), 28 | .tilix-terminal-scrollbar.vertical.dragging:dir(rtl) { 29 | margin-right: 0px; 30 | } 31 | 32 | /* Add support for wide handle toggle to Ubuntu themes */ 33 | GtkPaned { 34 | -GtkPaned-handle-size: 2; 35 | } 36 | 37 | GtkPaned.wide { 38 | -GtkPaned-handle-size: 6; 39 | } 40 | 41 | /* Fix split header bar colors */ 42 | .tilix-title-separator { 43 | border-color: #333333; 44 | background-color: #AEA79F; 45 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.Ambiance.scrollbar.css: -------------------------------------------------------------------------------- 1 | /* GTK 3.18 */ 2 | .scrollbar:not(.slider) { 3 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 4 | } 5 | 6 | /* GTK 3.20 */ 7 | scrollbar:not(slider) { 8 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 9 | } 10 | 11 | scrollbar.vertical:active:dir(ltr) { 12 | margin-left: 0px; 13 | padding-left: 2px; 14 | } 15 | 16 | scrollbar.vertical:dir(ltr):not(:hover):not(.dragging) { 17 | margin-left: 0px; 18 | padding-left: 7px; 19 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.Arc-Dark.scrollbar.css: -------------------------------------------------------------------------------- 1 | /* GTK 3.20 */ 2 | scrollbar { 3 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 4 | } 5 | /* GTK 3.18 */ 6 | .scrollbar:not(.slider) { 7 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 8 | border-left: 0px; 9 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.Arc-Darker.scrollbar.css: -------------------------------------------------------------------------------- 1 | /* GTK 3.20 */ 2 | scrollbar { 3 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 4 | } 5 | /* GTK 3.18 */ 6 | .scrollbar:not(.slider) { 7 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 8 | border-left: 0px; 9 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.Arc.scrollbar.css: -------------------------------------------------------------------------------- 1 | /* GTK 3.20 */ 2 | scrollbar { 3 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 4 | } 5 | /* GTK 3.18 */ 6 | .scrollbar:not(.slider) { 7 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 8 | border-left: 0px; 9 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.Lavender.scrollbar.css: -------------------------------------------------------------------------------- 1 | /* GTK 3.20 */ 2 | scrollbar { 3 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 4 | } 5 | -------------------------------------------------------------------------------- /data/resources/css/tilix.Radiance.css: -------------------------------------------------------------------------------- 1 | /** Radiance specific CSS to fix Ubuntu problems so the rest of us can have nice things **/ 2 | 3 | /* Fix Ubuntu Popover label borders, see #217 */ 4 | GtkBox > .label.separator { 5 | border: 0px; 6 | color: @theme_fg_color; 7 | opacity: 0.4; 8 | } 9 | 10 | /* Attempt to improve scrollbars */ 11 | .tilix-terminal-scrollbar:hover:not(.slider), 12 | .tilix-terminal-scrollbar.dragging:not(.slider) { 13 | background-color: alpha(@scrollbar_track_color, 0.4); 14 | } 15 | 16 | /* Since .hovering class is not working here, we always use the same radius */ 17 | .tilix-terminal-scrollbar.slider.hovering, 18 | .tilix-terminal-scrollbar.slider.dragging { 19 | /*border-radius: 1px;*/ 20 | border-left: 0px; 21 | } 22 | 23 | .tilix-terminal-scrollbar.vertical:hover:dir(ltr), 24 | .tilix-terminal-scrollbar.vertical.dragging:dir(ltr) { 25 | margin-left: 0px; 26 | } 27 | 28 | .tilix-terminal-scrollbar.vertical:hover:dir(rtl), 29 | .tilix-terminal-scrollbar.vertical.dragging:dir(rtl) { 30 | margin-right: 0px; 31 | } 32 | 33 | /* Add support for wide handle toggle to Ubuntu themes */ 34 | GtkPaned { 35 | -GtkPaned-handle-size: 2; 36 | } 37 | 38 | GtkPaned.wide { 39 | -GtkPaned-handle-size: 6; 40 | } 41 | 42 | /* Fix split header bar colors */ 43 | .tilix-title-separator { 44 | background-color: #AEA79F; 45 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.Radiance.scrollbar.css: -------------------------------------------------------------------------------- 1 | .scrollbar:not(.slider) { 2 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 3 | } 4 | 5 | /* GTK 3.20 */ 6 | scrollbar:not(.slider) { 7 | background-color: alpha($TERMINAL_BG, $TERMINAL_OPACITY); 8 | } 9 | 10 | scrollbar.vertical:active:dir(ltr) { 11 | margin-left: 0px; 12 | padding-left: 2px; 13 | } 14 | 15 | scrollbar.vertical:dir(ltr):not(:hover):not(.dragging) { 16 | margin-left: 0px; 17 | padding-left: 7px; 18 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.base.css: -------------------------------------------------------------------------------- 1 | .tilix-search-entry { 2 | padding-bottom: 6px; 3 | padding-top: 6px; 4 | } 5 | 6 | .tilix-search-frame { 7 | border-bottom: 1px solid @borders; 8 | } 9 | 10 | .tilix-notification-counter { 11 | background-color: @theme_fg_color; 12 | color: @theme_bg_color; 13 | border: 1px solid @borders; 14 | padding: 1px 4px 1px 4px; 15 | font-size: 0.8em; 16 | } 17 | 18 | .tilix-tab-notification-counter { 19 | background-color: @theme_selected_bg_color; 20 | color: @theme_selected_fg_color; 21 | border: 1px solid @borders; 22 | /* 23 | padding: 2px 4px 2px 4px; 24 | margin-top: 2px; 25 | margin-bottom: 2px; 26 | */ 27 | font-size: 0.8em; 28 | } 29 | 30 | .tilix-small-button { 31 | padding: 2px 4px; 32 | } 33 | 34 | .tilix-notebook-page { 35 | background-color: @theme_bg_color; 36 | } 37 | 38 | /* Used to give backgrounds to widgets that end up transparent 39 | due to transparent window */ 40 | .tilix-background { 41 | background-color: @theme_bg_color; 42 | } 43 | 44 | /* Only used when CSD is disabled */ 45 | .tilix-toolbar { 46 | background-color: @theme_bg_color; 47 | border-bottom: 1px solid @borders; 48 | } 49 | 50 | .tilix-notification-count { 51 | background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(@theme_selected_bg_color), to(transparent)), -gtk-gradient(radial, center center, 0, center center, 0.5, to(rgba(255, 255, 255, 0.76923)), to(transparent)); 52 | color: @theme_selected_fg_color; 53 | font-size: smaller; 54 | } 55 | 56 | .tilix-notification-count > label { 57 | color: @theme_selected_fg_color; 58 | } 59 | 60 | .tilix-session-index { 61 | background-image: -gtk-gradient(radial, center center, 0, center center, 0.5, to(@theme_fg_color), to(transparent)), -gtk-gradient(radial, center center, 0, center center, 0.5, to(rgba(255, 255, 255, 0.76923)), to(transparent)); 62 | color: @theme_bg_color; 63 | font-size: smaller; 64 | } 65 | 66 | .tilix-session-index > label { 67 | color: @theme_bg_color; 68 | } 69 | 70 | .tilix-session-sidebar { 71 | background-color: @theme_bg_color; 72 | } 73 | 74 | revealer.left > scrolledwindow { 75 | border-width: 0 1px 0 0; 76 | } 77 | 78 | revealer.right > scrolledwindow { 79 | border-width: 0 0 0 1px; 80 | } 81 | 82 | .tilix-terminal-scrolledwindow > undershoot.top { 83 | background-image: none; 84 | } 85 | 86 | .tilix-terminal-scrolledwindow > undershoot.bottom { 87 | background-image: none; 88 | } 89 | 90 | .tilix-session-name { 91 | color: @theme_bg_color; 92 | background-color: @theme_fg_color; 93 | border-radius: 8px 8px 8px 8px / 50% 50% 50% 50%; 94 | padding-left: 8px; 95 | padding-right: 8px; 96 | font-size: smaller; 97 | } 98 | 99 | /* Remove padding from buttons when in compact mode */ 100 | .compact > .button { 101 | padding: 0px; 102 | } 103 | 104 | /* Support small titlebars in 3.20 */ 105 | .compact > button { 106 | padding: 0px; 107 | } 108 | 109 | .tilix-sidebar-close-button { 110 | border: 0px; 111 | padding: 0px; 112 | margin: 0px; 113 | } 114 | 115 | .tilix-session-switcher { 116 | background-color: @theme_bg_color; 117 | } 118 | 119 | /* Visual Bell Animation, note each frame defined 120 | separately because GTK doesn't support grouping them 121 | together like normal CSS 122 | */ 123 | @keyframes shake { 124 | 0% {-gtk-icon-transform: translateX(0);} 125 | 100% {-gtk-icon-transform: translateX(0);} 126 | 10% {-gtk-icon-transform: translateX(-1px);} 127 | 30% {-gtk-icon-transform: translateX(-1px);} 128 | 50% {-gtk-icon-transform: translateX(-1px);} 129 | 70% {-gtk-icon-transform: translateX(-1px);} 130 | 90% {-gtk-icon-transform: translateX(-1px);} 131 | 20% {-gtk-icon-transform: translateX(1px);} 132 | 40% {-gtk-icon-transform: translateX(1px);} 133 | 60% {-gtk-icon-transform: translateX(1px);} 134 | 80% {-gtk-icon-transform: translateX(1px);} 135 | } 136 | 137 | .tilix-bell { 138 | background: none; 139 | opacity: 0; 140 | -gtk-icon-source: -gtk-icontheme("alarm-symbolic"); 141 | } 142 | 143 | .tilix-bell:checked { 144 | opacity: 1; 145 | animation: shake 1s linear infinite; 146 | } 147 | 148 | /* New Button in new UI */ 149 | .session-new-button { 150 | padding-left: 2px; 151 | padding-right: 2px; 152 | } 153 | 154 | /* Remove rounded corners when disable-csd set to true */ 155 | .tilix-embedded-headerbar { 156 | border-radius: 0; 157 | } 158 | 159 | /* Quake window border */ 160 | .tilix-quake-frame { 161 | border: 1px solid rgba(0, 0, 0, .7); 162 | } 163 | 164 | /* 165 | .tilix-quake-frame > border { 166 | border-width: 0px; 167 | } 168 | */ 169 | 170 | .tilix-error { 171 | color: @error_color; 172 | } -------------------------------------------------------------------------------- /data/resources/css/tilix.base.theme.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS that is loaded with lower priority to lower themes to override. 3 | */ 4 | .terminal-titlebar { 5 | border-bottom: 1px solid @borders; 6 | } 7 | 8 | .terminal-titlebar > button { 9 | border-radius: 0; 10 | border-top: none; 11 | border-bottom: none; 12 | } 13 | 14 | .terminal-titlebar > button:first-child { 15 | border-left: none; 16 | } 17 | 18 | .terminal-titlebar > button:last-child { 19 | border-right: none; 20 | } 21 | 22 | .terminal-titlebar > image, 23 | .tilix-bell { 24 | padding-left: 8px; 25 | padding-right: 8px; 26 | } 27 | -------------------------------------------------------------------------------- /data/resources/css/tilix.base320.css: -------------------------------------------------------------------------------- 1 | /* Easier navigation in tree view */ 2 | @binding-set TilixTreeViewBinding 3 | { 4 | bind "Left" { 5 | "select-cursor-parent" () 6 | "expand-collapse-cursor-row" (0,0,0) 7 | }; 8 | bind "Right" { 9 | "expand-collapse-cursor-row" (0,1,0) 10 | }; 11 | } 12 | 13 | treeview 14 | { 15 | -gtk-key-bindings: TilixTreeViewBinding; 16 | } -------------------------------------------------------------------------------- /data/resources/generate-symbolic.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | echo "Creating PNG symbolic resource icons" 4 | mkdir -p icons/16x16/actions 5 | mkdir -p icons/32x32/actions 6 | 7 | find icons -type f -name "*.symbolic.png" -delete 8 | 9 | gtk-encode-symbolic-svg -o icons/16x16/actions icons/scalable/actions/tilix-add-horizontal-symbolic.svg 16x16 10 | gtk-encode-symbolic-svg -o icons/16x16/actions icons/scalable/actions/tilix-add-vertical-symbolic.svg 16x16 11 | gtk-encode-symbolic-svg -o icons/32x32/actions icons/scalable/actions/tilix-add-horizontal-symbolic.svg 32x32 12 | gtk-encode-symbolic-svg -o icons/32x32/actions icons/scalable/actions/tilix-add-vertical-symbolic.svg 32x32 13 | -------------------------------------------------------------------------------- /data/resources/icons/16x16/actions/tilix-add-horizontal-symbolic.symbolic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnunn1/tilix/d25ded871d87f9f0a60ae64f38aa4c7af3ffcc41/data/resources/icons/16x16/actions/tilix-add-horizontal-symbolic.symbolic.png -------------------------------------------------------------------------------- /data/resources/icons/16x16/actions/tilix-add-vertical-symbolic.symbolic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnunn1/tilix/d25ded871d87f9f0a60ae64f38aa4c7af3ffcc41/data/resources/icons/16x16/actions/tilix-add-vertical-symbolic.symbolic.png -------------------------------------------------------------------------------- /data/resources/icons/32x32/actions/tilix-add-horizontal-symbolic.symbolic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnunn1/tilix/d25ded871d87f9f0a60ae64f38aa4c7af3ffcc41/data/resources/icons/32x32/actions/tilix-add-horizontal-symbolic.symbolic.png -------------------------------------------------------------------------------- /data/resources/icons/32x32/actions/tilix-add-vertical-symbolic.symbolic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gnunn1/tilix/d25ded871d87f9f0a60ae64f38aa4c7af3ffcc41/data/resources/icons/32x32/actions/tilix-add-vertical-symbolic.symbolic.png -------------------------------------------------------------------------------- /data/resources/icons/scalable/actions/tilix-add-horizontal-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 42 | 45 | 46 | 48 | 49 | 51 | image/svg+xml 52 | 54 | 55 | 56 | 57 | 58 | 63 | 68 | 70 | 73 | 79 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /data/resources/icons/scalable/actions/tilix-add-vertical-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 42 | 45 | 46 | 48 | 49 | 51 | image/svg+xml 52 | 54 | 55 | 56 | 57 | 58 | 63 | 68 | 71 | 74 | 80 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /data/resources/tilix.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icons/16x16/actions/tilix-add-horizontal-symbolic.symbolic.png 5 | icons/16x16/actions/tilix-add-vertical-symbolic.symbolic.png 6 | icons/32x32/actions/tilix-add-horizontal-symbolic.symbolic.png 7 | icons/32x32/actions/tilix-add-vertical-symbolic.symbolic.png 8 | css/tilix.base.css 9 | css/tilix.base320.css 10 | css/tilix.base.theme.css 11 | css/tilix.Ambiance.css 12 | css/tilix.Radiance.css 13 | css/tilix.Adwaita.scrollbar.css 14 | css/tilix.Lavender.scrollbar.css 15 | css/tilix.Ambiance.scrollbar.css 16 | css/tilix.Radiance.scrollbar.css 17 | css/tilix.Arc.scrollbar.css 18 | css/tilix.Arc-Dark.scrollbar.css 19 | css/tilix.Arc-Darker.scrollbar.css 20 | ui/shortcuts.ui 21 | 22 | 23 | -------------------------------------------------------------------------------- /data/schemes/base16-twilight-dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "base16: Twilight (dark)", 3 | "comment": "@chriskempson's base16 Twilight (dark variant)", 4 | "use-theme-colors": false, 5 | "foreground-color": "#a7a7a7", 6 | "background-color": "#1e1e1e", 7 | "palette": [ 8 | "#1e1e1e", 9 | "#cf6a4c", 10 | "#8f9d6a", 11 | "#f9ee98", 12 | "#7587a6", 13 | "#9b859d", 14 | "#afc4db", 15 | "#a7a7a7", 16 | "#5f5a60", 17 | "#cf6a4c", 18 | "#8f9d6a", 19 | "#f9ee98", 20 | "#7587a6", 21 | "#9b859d", 22 | "#afc4db", 23 | "#ffffff" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /data/schemes/linux.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Linux", 3 | "comment": "Taken from Gnome Terminal", 4 | "use-theme-colors": true, 5 | "palette": [ 6 | "#000000", 7 | "#AA0000", 8 | "#00AA00", 9 | "#AA5400", 10 | "#0000AA", 11 | "#AA00AA", 12 | "#00AAAA", 13 | "#AAAAAA", 14 | "#545454", 15 | "#FF5454", 16 | "#54FF54", 17 | "#FFFF54", 18 | "#5454FF", 19 | "#FF54FF", 20 | "#54FFFF", 21 | "#FFFFFF" 22 | ] 23 | } -------------------------------------------------------------------------------- /data/schemes/material.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Material", 3 | "comment": "Material Oceanic Scheme", 4 | "use-theme-colors": false, 5 | "foreground-color": "#A1B0B8", 6 | "background-color": "#263238", 7 | "palette": [ 8 | "#252525", 9 | "#FF5252", 10 | "#C3D82C", 11 | "#FFC135", 12 | "#42A5F5", 13 | "#D81B60", 14 | "#00ACC1", 15 | "#F5F5F5", 16 | "#708284", 17 | "#FF5252", 18 | "#C3D82C", 19 | "#FFC135", 20 | "#42A5F5", 21 | "#D81B60", 22 | "#00ACC1", 23 | "#F5F5F5" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /data/schemes/monokai.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Monokai Dark", 3 | "comment": "Monokai Dark Scheme", 4 | "use-theme-colors": false, 5 | "foreground-color": "#F8F8F2", 6 | "background-color": "#272822", 7 | "palette": [ 8 | "#272822", 9 | "#f92672", 10 | "#a6e22e", 11 | "#f4bf75", 12 | "#66d9ef", 13 | "#ae81ff", 14 | "#a1efe4", 15 | "#f8f8f2", 16 | "#75715e", 17 | "#f92672", 18 | "#a6e22e", 19 | "#f4bf75", 20 | "#66d9ef", 21 | "#ae81ff", 22 | "#a1efe4", 23 | "#f9f8f5" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /data/schemes/orchis.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Orchis", 3 | "comment": "Tango but using Orchis foreground/background colors", 4 | "foreground-color": "#EFEFEF", 5 | "background-color": "#303030", 6 | "use-theme-colors": false, 7 | "use-highlight-color": false, 8 | "highlight-foreground-color": "#ffffff", 9 | "highlight-background-color": "#a348b1", 10 | "use-cursor-color": false, 11 | "cursor-foreground-color": "#ffffff", 12 | "cursor-background-color": "#efefef", 13 | "use-badge-color": true, 14 | "badge-color": "#ac7ea8", 15 | "palette": [ 16 | "#000000", 17 | "#CC0000", 18 | "#4D9A05", 19 | "#C3A000", 20 | "#3464A3", 21 | "#754F7B", 22 | "#05979A", 23 | "#D3D6CF", 24 | "#545652", 25 | "#EF2828", 26 | "#89E234", 27 | "#FBE84F", 28 | "#729ECF", 29 | "#AC7EA8", 30 | "#34E2E2", 31 | "#EDEDEB" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /data/schemes/solarized-dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Solarized Dark", 3 | "comment": "Taken from Gnome Terminal", 4 | "use-theme-colors": false, 5 | "foreground-color": "#839496", 6 | "background-color": "#002B36", 7 | "palette": [ 8 | "#073642", 9 | "#DC322F", 10 | "#859900", 11 | "#B58900", 12 | "#268BD2", 13 | "#D33682", 14 | "#2AA198", 15 | "#EEE8D5", 16 | "#002B36", 17 | "#CB4B16", 18 | "#586E75", 19 | "#657B83", 20 | "#839496", 21 | "#6C71C4", 22 | "#93A1A1", 23 | "#FDF6E3" 24 | ] 25 | } -------------------------------------------------------------------------------- /data/schemes/solarized-light.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Solarized Light", 3 | "comment": "Taken from Gnome Terminal", 4 | "use-theme-colors": false, 5 | "foreground-color": "#657B83", 6 | "background-color": "#FDF6E3", 7 | "palette": [ 8 | "#073642", 9 | "#DC322F", 10 | "#859900", 11 | "#B58900", 12 | "#268BD2", 13 | "#D33682", 14 | "#2AA198", 15 | "#EEE8D5", 16 | "#002B36", 17 | "#CB4B16", 18 | "#586E75", 19 | "#657B83", 20 | "#839496", 21 | "#6C71C4", 22 | "#93A1A1", 23 | "#FDF6E3" 24 | ] 25 | } -------------------------------------------------------------------------------- /data/schemes/tango.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Tango", 3 | "comment": "Taken from Gnome Terminal", 4 | "use-theme-colors": true, 5 | "palette": [ 6 | "#000000", 7 | "#CC0000", 8 | "#4D9A05", 9 | "#C3A000", 10 | "#3464A3", 11 | "#754F7B", 12 | "#05979A", 13 | "#D3D6CF", 14 | "#545652", 15 | "#EF2828", 16 | "#89E234", 17 | "#FBE84F", 18 | "#729ECF", 19 | "#AC7EA8", 20 | "#34E2E2", 21 | "#EDEDEB" 22 | ] 23 | } -------------------------------------------------------------------------------- /data/schemes/yaru.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Yaru", 3 | "comment": "Yaru Color Scheme", 4 | "use-theme-colors": false, 5 | "foreground-color": "#ffffff", 6 | "background-color": "#300a24", 7 | "palette": [ 8 | "#2E3436", 9 | "#CC0000", 10 | "#4E9A06", 11 | "#C4A000", 12 | "#3465A4", 13 | "#75507B", 14 | "#06989A", 15 | "#D3D7CF", 16 | "#555753", 17 | "#EF2929", 18 | "#8AE234", 19 | "#FCE94F", 20 | "#729FCF", 21 | "#AD7FA8", 22 | "#34E2E2", 23 | "#EEEEEC" 24 | ] 25 | } -------------------------------------------------------------------------------- /data/scripts/install-man-pages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/env sh 2 | 3 | # Determine PREFIX. 4 | if [ -z "$1" ]; then 5 | if [ -n "$PREFIX" ]; then 6 | PREFIX='/usr' 7 | fi 8 | else 9 | PREFIX="$1" 10 | fi 11 | export PREFIX 12 | 13 | echo "Installing man pages" 14 | install -Dm 644 'data/man/tilix.1' "$PREFIX/share/man/man1/tilix.1" 15 | gzip -f "$PREFIX/share/man/man1/tilix.1" 16 | 17 | if type po4a-translate >/dev/null 2>&1; then 18 | for f in data/man/po/*.man.po; do 19 | LOCALE=$(basename "$f" .man.po) 20 | install -d "$PREFIX/share/man/$LOCALE/man1" 21 | po4a-translate -k 0 -f man -m data/man/tilix -p "data/man/po/$LOCALE.man.po" -l "$PREFIX/share/man/$LOCALE/man1/tilix.1" 22 | gzip -f "$PREFIX/share/man/$LOCALE/man1/tilix.1" 23 | done 24 | fi 25 | -------------------------------------------------------------------------------- /data/scripts/tilix_int.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Adapted from vte.sh script, copyright notice from that ensues: 3 | 4 | # Copyright © 2006 Shaun McCance 5 | # Copyright © 2013 Peter De Wachter 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with this program. If not, see . 19 | if [ -z ${HOSTNAME+x} ] 20 | then 21 | HOSTNAME=$(hostname) 22 | fi 23 | # Not bash or zsh? 24 | [ -n "$BASH_VERSION" -o -n "$ZSH_VERSION" ] || return 0 25 | 26 | # Not an interactive shell? 27 | [[ $- == *i* ]] || return 0 28 | 29 | __tilix_urlencode() ( 30 | # This is important to make sure string manipulation is handled 31 | # byte-by-byte. 32 | LC_ALL=C 33 | str="$1" 34 | while [ -n "$str" ]; do 35 | safe="${str%%[!a-zA-Z0-9/:_\.\-\!\'\(\)~]*}" 36 | printf "%s" "$safe" 37 | str="${str#"$safe"}" 38 | if [ -n "$str" ]; then 39 | printf "%%%02X" "'$str" 40 | str="${str#?}" 41 | fi 42 | done 43 | ) 44 | 45 | __tilix_osc7() ( 46 | local previous_exit_status=$? 47 | printf "\033]7;file://%s%s\007" "${HOSTNAME:-}" "$(__tilix_urlencode "${PWD}")" 48 | return $previous_exit_status 49 | ) 50 | 51 | if [[ $PROMPT_COMMAND != *"__vte_prompt_command"* ]] 52 | then 53 | if [ "$TILIX_SILENT" != "1" ]; then 54 | echo "Adding tilix osc7" 55 | fi 56 | [ -n "$BASH_VERSION" ] && PROMPT_COMMAND="__tilix_osc7" 57 | [ -n "$ZSH_VERSION" ] && precmd_functions+=(__tilix_osc7) 58 | fi 59 | -------------------------------------------------------------------------------- /dscanner.ini: -------------------------------------------------------------------------------- 1 | ; Configure which static analysis checks are enabled 2 | [analysis.config.StaticAnalysisConfig] 3 | ; Check variable, class, struct, interface, union, and function names against the Phobos style guide 4 | style_check="enabled" 5 | ; Check for array literals that cause unnecessary allocation 6 | enum_array_literal_check="enabled" 7 | ; Check for poor exception handling practices 8 | exception_check="enabled" 9 | ; Check for use of the deprecated 'delete' keyword 10 | delete_check="enabled" 11 | ; Check for use of the deprecated floating point operators 12 | float_operator_check="enabled" 13 | ; Check number literals for readability 14 | number_style_check="enabled" 15 | ; Checks that opEquals, opCmp, toHash, and toString are either const, immutable, or inout. 16 | object_const_check="enabled" 17 | ; Checks for .. expressions where the left side is larger than the right. 18 | backwards_range_check="enabled" 19 | ; Checks for if statements whose 'then' block is the same as the 'else' block 20 | if_else_same_check="enabled" 21 | ; Checks for some problems with constructors 22 | constructor_check="enabled" 23 | ; Checks for unused variables and function parameters 24 | unused_variable_check="disabled" 25 | ; Checks for unused labels 26 | unused_label_check="enabled" 27 | ; Checks for duplicate attributes 28 | duplicate_attribute="enabled" 29 | ; Checks that opEquals and toHash are both defined or neither are defined 30 | opequals_tohash_check="enabled" 31 | ; Checks for subtraction from .length properties 32 | length_subtraction_check="enabled" 33 | ; Checks for methods or properties whose names conflict with built-in properties 34 | builtin_property_names_check="enabled" 35 | ; Checks for confusing code in inline asm statements 36 | asm_style_check="enabled" 37 | ; Checks for confusing logical operator precedence 38 | logical_precedence_check="enabled" 39 | ; Checks for undocumented public declarations 40 | undocumented_declaration_check="enabled" 41 | ; Checks for poor placement of function attributes 42 | function_attribute_check="enabled" 43 | ; Checks for use of the comma operator 44 | comma_expression_check="enabled" 45 | ; Checks for local imports that are too broad 46 | local_import_check="enabled" 47 | ; Checks for variables that could be declared immutable 48 | could_be_immutable_check="disabled" 49 | ; Checks for redundant expressions in if statements 50 | redundant_if_check="enabled" 51 | ; Checks for redundant parenthesis 52 | redundant_parens_check="enabled" 53 | ; Checks for mismatched argument and parameter names 54 | mismatched_args_check="enabled" 55 | ; Checks for labels with the same name as variables 56 | label_var_same_name_check="enabled" 57 | ; Checks for lines longer than 120 characters 58 | long_line_check="disabled" 59 | ; Checks for assignment to auto-ref function parameters 60 | auto_ref_assignment_check="enabled" 61 | ; Checks for incorrect infinite range definitions 62 | incorrect_infinite_range_check="enabled" 63 | ; Checks for asserts that are always true 64 | useless_assert_check="enabled" 65 | ; Check for uses of the old-style alias syntax 66 | alias_syntax_check="enabled" 67 | ; Checks for else if that should be else static if 68 | static_if_else_check="enabled" 69 | ; Check for unclear lambda syntax 70 | lambda_return_check="enabled" -------------------------------------------------------------------------------- /dub.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tilix", 3 | "description": "A VTE based terminal emulator for Linux", 4 | "copyright": "Copyright © 2016, Gerald Nunn", 5 | "authors": ["Gerald Nunn"], 6 | "mainSourceFile": "source/app.d", 7 | "dflags-ldc": ["-disable-linker-strip-dead","-link-defaultlib-shared=false"], 8 | "dependencies": { 9 | "gtk-d:gtkd": { 10 | "version": "3.10.0" 11 | }, 12 | "gtk-d:vte": { 13 | "version": "3.10.0" 14 | } 15 | }, 16 | "buildTypes": { 17 | "release": { 18 | }, 19 | "debug": { 20 | "debugVersions": ["GC"], 21 | "dflags": ["-g"] 22 | }, 23 | "localize": { 24 | "versions": ["Localize"] 25 | }, 26 | "i686": { 27 | "dflags": ["-m32", "-c"] 28 | } 29 | }, 30 | 31 | "configurations": [ 32 | { 33 | "name": "default", 34 | "targetType": "executable", 35 | "libs-linux": ["X11"], 36 | "versions": ["StdLoggerDisableTrace"] 37 | }, 38 | { 39 | "name": "trace", 40 | "targetType": "executable", 41 | "libs-linux": ["X11"], 42 | "debugVersions": ["Destructors"] 43 | }, 44 | { 45 | "name": "dynamic", 46 | "targetType": "executable", 47 | "libs": ["gtkd-3"], 48 | "libs-linux": ["X11"], 49 | "lflags": ["-defaultlib=libgtkd-3.so"], 50 | "versions": ["StdLoggerDisableTrace"] 51 | } 52 | ] 53 | } -------------------------------------------------------------------------------- /dub.selections.json: -------------------------------------------------------------------------------- 1 | { 2 | "fileVersion": 1, 3 | "versions": { 4 | "gtk-d": "3.10.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /experimental/flatpak/README.md: -------------------------------------------------------------------------------- 1 | ### Building Tilix Flatpak Bundle 2 | 3 | This folder contains the scripts required to build Tilix as an Flatpak bundle. Flatpak allows desktop applications to be distributed independently of traditional Linux package managers, applications distributed in this way run in a sandboxed environment. Additional information on Flatpak can be found [here](http://flatpak.org/). 4 | 5 | The first step to building the Tilix Flatpak Bundle is to install the flatpak framework. This will vary by distribution, see [Getting Flatpak](http://flatpak.org/getting.html). 6 | 7 | Once that is done you will need to install the Gnome runtimes, this can be done by following the instructions on the [Flatpak wiki](http://docs.flatpak.org/en/latest/getting-setup.html). The specific steps you need are as follows: 8 | ) 9 | ``` 10 | flatpak install flathub org.gnome.Sdk//3.30 11 | flatpak install flathub org.gnome.Platform//3.30 12 | ``` 13 | With all the dependencies in place, you can now build the bundle: 14 | 15 | ``` 16 | flatpak-builder --install flatpak-builder com.gexperts.Tilix.yaml 17 | ``` 18 | 19 | And then run the application: 20 | 21 | ``` 22 | flatpak run com.gexperts.Tilix 23 | ``` 24 | -------------------------------------------------------------------------------- /experimental/flatpak/com.gexperts.Tilix.yaml: -------------------------------------------------------------------------------- 1 | id: com.gexperts.Tilix 2 | branch: master 3 | runtime: org.gnome.Platform 4 | runtime-version: '3.34' 5 | sdk: org.gnome.Sdk 6 | sdk-extensions: 7 | - org.freedesktop.Sdk.Extension.ldc 8 | - org.freedesktop.Sdk.Extension.dmd 9 | command: tilix 10 | finish-args: 11 | - --share=ipc 12 | - --socket=x11 13 | - --socket=wayland 14 | - --filesystem=xdg-run/dconf 15 | - --filesystem=~/.config/dconf:ro 16 | - --talk-name=ca.desrt.dconf 17 | - --env=DCONF_USER_CONFIG_DIR=.config/dconf 18 | - --own-name=com.gexperts.Tilix 19 | - --talk-name=org.freedesktop.Flatpak 20 | - --talk-name=org.freedesktop.secrets 21 | - --device=all 22 | cleanup: 23 | - '/bin/appstreamcli' 24 | - '/bin/ncurses6-config' 25 | - '/bin/po4a*' 26 | - '/bin/vte*' 27 | - '/etc/appstream.conf' 28 | - '/etc/bash_completion.d' 29 | - '/include' 30 | - '/lib/cmake' 31 | - '/lib/debug' 32 | - '/lib/libappstream.*' 33 | - '/lib/libstemmer.*' 34 | - '/lib/libyaml*' 35 | - '/lib/pkgconfig' 36 | - '/share/gtk-doc' 37 | - '/share/man' 38 | - '/share/metainfo' 39 | - '/src' 40 | - '*.la' 41 | - '*.a' 42 | build-options: 43 | env: 44 | PERLLIB: '/app/lib' 45 | modules: 46 | - name: termcap 47 | buildsystem: autotools 48 | sources: 49 | - type: archive 50 | url: https://ftp.gnu.org/gnu/termcap/termcap-1.3.1.tar.gz 51 | sha256: 91a0e22e5387ca4467b5bcb18edf1c51b930262fd466d5fda396dd9d26719100 52 | - name: ncurses 53 | buildsystem: autotools 54 | config-opts: 55 | - '--with-shared' 56 | sources: 57 | - type: archive 58 | url: https://ftp.gnu.org/gnu/ncurses/ncurses-6.1.tar.gz 59 | sha256: aa057eeeb4a14d470101eff4597d5833dcef5965331be3528c08d99cebaa0d17 60 | - name: libconfig 61 | buildsystem: autotools 62 | sources: 63 | - type: archive 64 | url: https://hyperrealm.github.io/libconfig/dist/libconfig-1.7.2.tar.gz 65 | sha256: 7c3c7a9c73ff3302084386e96f903eb62ce06953bb1666235fac74363a16fad9 66 | - name: libedit 67 | buildsystem: autotools 68 | sources: 69 | - type: archive 70 | url: https://thrysoee.dk/editline/libedit-20181209-3.1.tar.gz 71 | sha256: 2811d70c0b000f2ca91b7cb1a37203134441743c4fcc9c37b0b687f328611064 72 | - name: gtkd 73 | buildsystem: simple 74 | build-options: 75 | append-path: /usr/lib/sdk/dmd/bin 76 | build-commands: 77 | - 'make -j2 prefix=/app install-gtkd install-vte' 78 | sources: 79 | - type: archive 80 | url: https://gtkd.org/Downloads/sources/GtkD-3.9.0.zip 81 | sha512: f8b8a7b83a23af990abb77f16e4bddf2f72bb65ad210ff8f138b0d4ff66fb5fb2a73a3cbe868a8d2ecf3abf98ece5af771af63068dc2fbf8668e46039320cf0f 82 | strip-components: 0 83 | - type: patch 84 | path: gtkd3-pkgconfig.patch 85 | - name: po4a 86 | buildsystem: simple 87 | build-commands: 88 | - 'install -m 755 po4a /app/bin' 89 | - 'install -m 755 po4a-gettextize /app/bin' 90 | - 'install -m 755 po4a-normalize /app/bin' 91 | - 'install -m 755 po4a-translate /app/bin' 92 | - 'install -m 755 po4a-updatepo /app/bin' 93 | - 'cp -r lib/* /app/lib' 94 | sources: 95 | - type: archive 96 | url: https://github.com/mquinson/po4a/releases/download/v0.54/po4a-0.54.tar.gz 97 | sha256: 596f7621697f9dd12709958c229e256b56683d25997ac73c9625a2cc0c603d51 98 | # TODO: Use shared module from flathub. 99 | - name: intltool 100 | cleanup: 101 | - "*" 102 | sources: 103 | - type: archive 104 | url: https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz 105 | sha512: 4c93cb26592ed0b1622d3b7800b5d6622ffa36f58ac73f2ef0bddfab522565fdfb8fa73d81914b9a202f1d62bc995a08960f8adb9f62c86918e75498e85fbfdf 106 | - name: libvte-patched 107 | buildsystem: autotools 108 | config-opts: 109 | - '--disable-introspection' 110 | - '--disable-vala' 111 | sources: 112 | - type: archive 113 | url: https://download.gnome.org/sources/vte/0.53/vte-0.53.0.tar.xz 114 | sha256: c319eb34e9c64c78cd4940cde0892bd18784bcdcaaa7a23a9c8ec6052317a130 115 | - type: patch 116 | path: vte291-command-notify-scroll-speed.patch 117 | - type: patch 118 | path: vte291-exceptions-gcc811.patch 119 | - name: toolbox 120 | buildsystem: simple 121 | build-commands: 122 | - 'gcc -o /app/bin/tilix-flatpak-toolbox tilix-flatpak-toolbox.c' 123 | sources: 124 | - type: file 125 | path: tilix-flatpak-toolbox.c 126 | - name: yaml 127 | sources: 128 | - type: archive 129 | url: https://github.com/yaml/libyaml/releases/download/0.2.5/yaml-0.2.5.tar.gz 130 | sha512: dadd7d8e0d88b5ebab005e5d521d56d541580198aa497370966b98c904586e642a1cd4f3881094eb57624f218d50db77417bbfd0ffdce50340f011e35e8c4c02 131 | - name: lmdb 132 | buildsystem: simple 133 | subdir: libraries/liblmdb 134 | build-commands: 135 | - 'sed -i s~/usr/local~/app~ Makefile' 136 | - 'make -j $FLATPAK_BUILDER_N_JOBS' 137 | - 'make install' 138 | - 'rm /app/lib/liblmdb.a' 139 | sources: 140 | - type: git 141 | url: https://github.com/LMDB/lmdb.git 142 | tag: LMDB_0.9.29 143 | commit: 8ad7be2510414b9506ec9f9e24f24d04d9b04a1a 144 | cleanup: 145 | - '/bin' 146 | - '/include' 147 | - '/lib/debug' 148 | - '/share' 149 | - name: stemmer 150 | buildsystem: simple 151 | build-commands: 152 | - 'make libstemmer.so -j$FLATPAK_BUILDER_N_JOBS' 153 | - 'install -Dm644 include/libstemmer.h /app/include/libstemmer.h' 154 | - 'install -Dm644 libstemmer.so.0.0.0 /app/lib/libstemmer.so.0.0.0' 155 | - 'ln -s libstemmer.so.0.0.0 /app/lib/libstemmer.so.0' 156 | - 'ln -s libstemmer.so.0 /app/lib/libstemmer.so' 157 | sources: 158 | - type: git 159 | url: https://github.com/snowballstem/snowball.git 160 | commit: d29510ae32702a81cdc29177a133e894df854550 161 | - type: patch 162 | path: stemmer-dynlib.patch 163 | - name: appstream 164 | buildsystem: meson 165 | sources: 166 | - type: git 167 | url: https://github.com/ximion/appstream.git 168 | cleanup: 169 | - '/share/doc' 170 | - '/share/gettext' 171 | - '/share/installed-tests' 172 | - name: tilix 173 | buildsystem: meson 174 | build-options: 175 | append-path: /usr/lib/sdk/dmd/bin 176 | sources: 177 | - type: git 178 | url: https://github.com/gnunn1/tilix.git 179 | -------------------------------------------------------------------------------- /experimental/flatpak/disable-ldc-completions.patch: -------------------------------------------------------------------------------- 1 | --- ldc-0.17.5/CMakeLists.orig.txt 2017-09-12 12:08:40.000000000 -0500 2 | +++ ldc-0.17.5/CMakeLists.txt 2018-07-29 19:48:51.253680698 -0500 3 | @@ -607,17 +607,6 @@ 4 | configure_file(vcbuild/x86.bat ${PROJECT_BINARY_DIR}/bin/x86.bat COPYONLY) 5 | endif() 6 | 7 | -if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 8 | - find_package(bash-completion QUIET) 9 | - if(NOT BASH_COMPLETION_FOUND) 10 | - set(BASH_COMPLETION_COMPLETIONSDIR "${CONF_INST_DIR}/bash_completion.d") 11 | - if(LINUX_DISTRIBUTION_IS_GENTOO) 12 | - set(BASH_COMPLETION_COMPLETIONSDIR "/usr/share/bash-completion") 13 | - endif() 14 | - endif() 15 | - install(DIRECTORY bash_completion.d/ DESTINATION ${BASH_COMPLETION_COMPLETIONSDIR}) 16 | -endif() 17 | - 18 | # 19 | # Packaging 20 | # 21 | -------------------------------------------------------------------------------- /experimental/flatpak/dmd.conf: -------------------------------------------------------------------------------- 1 | [Environment32] 2 | DFLAGS=-I%@P%/../src/phobos -I%@P%/../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic 3 | 4 | [Environment64] 5 | DFLAGS=-I%@P%/../src/phobos -I%@P%/../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -fPIC 6 | -------------------------------------------------------------------------------- /experimental/flatpak/gtkd3-pkgconfig.patch: -------------------------------------------------------------------------------- 1 | From a9db09117ab27127ca4c3b8d2f308fae483a9199 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Filipe=20La=C3=ADns?= 3 | Date: Fri, 7 Jun 2019 15:21:44 +0100 4 | Subject: [PATCH] makefile: fix install path for pkconfig files (#273) 5 | MIME-Version: 1.0 6 | Content-Type: text/plain; charset=UTF-8 7 | Content-Transfer-Encoding: 8bit 8 | 9 | 3742eda70ca3e045b6f513a57082d3487c97abe1 introduced a wrong behavior 10 | where the install commands for pkgconfig files were blindly ignoring 11 | $(prefix). This obviously breaks the build and introduces the 12 | possibility of the pkgconfig files not being installed to the system 13 | at all since $(libdir) is not suposed to have a leading /, that is 14 | $(prefix)'s job. All this resulted in a bad makefile being shipped 15 | in the 3.9.0 release. 16 | 17 | Signed-off-by: Filipe Laíns 18 | --- 19 | GNUmakefile | 26 +++++++++++++------------- 20 | 1 file changed, 13 insertions(+), 13 deletions(-) 21 | 22 | diff --git a/GNUmakefile b/GNUmakefile 23 | index a5919f5ee..0f44b4c15 100644 24 | --- a/GNUmakefile 25 | +++ b/GNUmakefile 26 | @@ -378,33 +378,33 @@ install-shared-peas: $(SONAME_PEASD) install-shared-gtkd 27 | 28 | install-headers-gtkd: gtkd-$(MAJOR).pc 29 | install -d $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR) 30 | - install -d $(DESTDIR)$(libdir)/pkgconfig 31 | + install -d $(DESTDIR)$(prefix)/$(libdir)/pkgconfig 32 | (cd generated/gtkd; echo $(SOURCES_GTKD) | sed -e s,generated/gtkd/,,g | xargs tar cf -) | (cd $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR); tar xvf -) 33 | - install -m 644 gtkd-$(MAJOR).pc $(DESTDIR)$(libdir)/pkgconfig 34 | + install -m 644 gtkd-$(MAJOR).pc $(DESTDIR)$(prefix)/$(libdir)/pkgconfig 35 | 36 | install-headers-gtkdgl: gtkdgl-$(MAJOR).pc install-headers-gtkd 37 | (cd generated/gtkdgl; echo $(SOURCES_GTKDGL) | sed -e s,generated/gtkdgl/,,g | xargs tar cf -) | (cd $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR); tar xvf -) 38 | - install -m 644 gtkdgl-$(MAJOR).pc $(DESTDIR)$(libdir)/pkgconfig 39 | + install -m 644 gtkdgl-$(MAJOR).pc $(DESTDIR)$(prefix)/$(libdir)/pkgconfig 40 | 41 | install-headers-gtkdsv: gtkdsv-$(MAJOR).pc install-headers-gtkd 42 | (cd generated/sourceview; echo $(SOURCES_GTKDSV) | sed -e s,generated/sourceview/,,g | xargs tar cf -) | (cd $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR); tar xvf -) 43 | - install -m 644 gtkdsv-$(MAJOR).pc $(DESTDIR)$(libdir)/pkgconfig 44 | + install -m 644 gtkdsv-$(MAJOR).pc $(DESTDIR)$(prefix)/$(libdir)/pkgconfig 45 | 46 | install-headers-gstreamer: gstreamerd-$(MAJOR).pc install-headers-gtkd 47 | (cd generated/gstreamer; echo $(SOURCES_GSTREAMERD) | sed -e s,generated/gstreamer/,,g | xargs tar cf -) | (cd $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR); tar xvf -) 48 | - install -m 644 gstreamerd-$(MAJOR).pc $(DESTDIR)$(libdir)/pkgconfig 49 | + install -m 644 gstreamerd-$(MAJOR).pc $(DESTDIR)$(prefix)/$(libdir)/pkgconfig 50 | 51 | install-headers-vte: vted-$(MAJOR).pc install-headers-gtkd 52 | (cd generated/vte; echo $(SOURCES_VTED) | sed -e s,generated/vte/,,g | xargs tar cf -) | (cd $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR); tar xvf -) 53 | - install -m 644 vted-$(MAJOR).pc $(DESTDIR)$(libdir)/pkgconfig 54 | + install -m 644 vted-$(MAJOR).pc $(DESTDIR)$(prefix)/$(libdir)/pkgconfig 55 | 56 | install-headers-peas: peasd-$(MAJOR).pc install-headers-gtkd 57 | (cd generated/peas; echo $(SOURCES_PEASD) | sed -e s,generated/peas/,,g | xargs tar cf -) | (cd $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR); tar xvf -) 58 | - install -m 644 peasd-$(MAJOR).pc $(DESTDIR)$(libdir)/pkgconfig 59 | + install -m 644 peasd-$(MAJOR).pc $(DESTDIR)$(prefix)/$(libdir)/pkgconfig 60 | 61 | uninstall: uninstall-gtkdgl uninstall-gtkdsv uninstall-gstreamer uninstall-vte uninstall-peas 62 | $(foreach dir,$(shell ls generated/gtkd) , rm -rf $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR)/$(dir)) 63 | - rm -f $(DESTDIR)$(libdir)/pkgconfig/gtkd-$(MAJOR).pc 64 | + rm -f $(DESTDIR)$(prefix)/$(libdir)/pkgconfig/gtkd-$(MAJOR).pc 65 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(LIBNAME_GTKD) 66 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_GTKD) 67 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_GTKD).$(SO_VERSION) 68 | @@ -412,7 +412,7 @@ uninstall: uninstall-gtkdgl uninstall-gtkdsv uninstall-gstreamer uninstall-vte u 69 | 70 | uninstall-gtkdgl: 71 | $(foreach dir,$(shell ls generated/gtkdgl), rm -rf $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR)/$(dir)) 72 | - rm -f $(DESTDIR)$(libdir)/pkgconfig/gtkdgl-$(MAJOR).pc 73 | + rm -f $(DESTDIR)$(prefix)/$(libdir)/pkgconfig/gtkdgl-$(MAJOR).pc 74 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(LIBNAME_GTKDGL) 75 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_GTKDGL) 76 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_GTKDGL).$(SO_VERSION) 77 | @@ -420,7 +420,7 @@ uninstall-gtkdgl: 78 | 79 | uninstall-gtkdsv: 80 | $(foreach dir,$(shell ls generated/sourceview), rm -rf $(DESTDIR)$(prefix)/include/d/$(dir)) 81 | - rm -f $(DESTDIR)$(libdir)/pkgconfig/gtkdsv-$(MAJOR).pc 82 | + rm -f $(DESTDIR)$(prefix)/$(libdir)/pkgconfig/gtkdsv-$(MAJOR).pc 83 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(LIBNAME_GTKDSV) 84 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_GTKDSV) 85 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_GTKDSV).$(SO_VERSION) 86 | @@ -428,7 +428,7 @@ uninstall-gtkdsv: 87 | 88 | uninstall-gstreamer: 89 | $(foreach dir,$(shell ls generated/gstreamer), rm -rf $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR)/$(dir)) 90 | - rm -f $(DESTDIR)$(libdir)/pkgconfig/gstreamerd-$(MAJOR).pc 91 | + rm -f $(DESTDIR)$(prefix)/$(libdir)/pkgconfig/gstreamerd-$(MAJOR).pc 92 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(LIBNAME_GSTREAMERD) 93 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_GSTREAMERD) 94 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_GSTREAMERD).$(SO_VERSION) 95 | @@ -436,7 +436,7 @@ uninstall-gstreamer: 96 | 97 | uninstall-vte: 98 | $(foreach dir,$(shell ls generated/vte), rm -rf $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR)/$(dir)) 99 | - rm -f $(DESTDIR)$(libdir)/pkgconfig/vted-$(MAJOR).pc 100 | + rm -f $(DESTDIR)$(prefix)/$(libdir)/pkgconfig/vted-$(MAJOR).pc 101 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(LIBNAME_VTED) 102 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_VTED) 103 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_VTED).$(SO_VERSION) 104 | @@ -444,7 +444,7 @@ uninstall-vte: 105 | 106 | uninstall-peas: 107 | $(foreach dir,$(shell ls generated/peas), rm -rf $(DESTDIR)$(prefix)/include/d/gtkd-$(MAJOR)/$(dir)) 108 | - rm -f $(DESTDIR)$(libdir)/pkgconfig/peasd-$(MAJOR).pc 109 | + rm -f $(DESTDIR)$(prefix)/$(libdir)/pkgconfig/peasd-$(MAJOR).pc 110 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(LIBNAME_PEASD) 111 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_PEASD) 112 | rm -f $(DESTDIR)$(prefix)/$(libdir)/$(SONAME_PEASD).$(SO_VERSION) 113 | -------------------------------------------------------------------------------- /experimental/flatpak/stemmer-dynlib.patch: -------------------------------------------------------------------------------- 1 | diff --git c/GNUmakefile i/GNUmakefile 2 | index 1693f5a..b33a42e 100644 3 | --- c/GNUmakefile 4 | +++ i/GNUmakefile 5 | @@ -112,10 +112,10 @@ C_OTHER_OBJECTS = $(C_OTHER_SOURCES:.c=.o) 6 | JAVA_CLASSES = $(JAVA_SOURCES:.java=.class) 7 | JAVA_RUNTIME_CLASSES=$(JAVARUNTIME_SOURCES:.java=.class) 8 | 9 | -CFLAGS=-O2 -W -Wall -Wmissing-prototypes -Wmissing-declarations 10 | +CFLAGS=-O2 -fPIC -W -Wall -Wmissing-prototypes -Wmissing-declarations 11 | CPPFLAGS=-Iinclude 12 | 13 | -all: snowball libstemmer.o stemwords $(C_OTHER_SOURCES) $(C_OTHER_HEADERS) $(C_OTHER_OBJECTS) 14 | +all: snowball libstemmer.o libstemmer.so stemwords $(C_OTHER_SOURCES) $(C_OTHER_HEADERS) $(C_OTHER_OBJECTS) 15 | 16 | clean: 17 | rm -f $(COMPILER_OBJECTS) $(RUNTIME_OBJECTS) \ 18 | @@ -158,6 +158,9 @@ libstemmer/libstemmer.o: libstemmer/modules.h $(C_LIB_HEADERS) 19 | libstemmer.o: libstemmer/libstemmer.o $(RUNTIME_OBJECTS) $(C_LIB_OBJECTS) 20 | $(AR) -cru $@ $^ 21 | 22 | +libstemmer.so: libstemmer/libstemmer.o $(RUNTIME_OBJECTS) $(C_LIB_OBJECTS) 23 | + $(CC) $(CFLAGS) -shared $(LDFLAGS) -Wl,-soname,libstemmer.so.0,-version-script,libstemmer/symbol.map -o $@.0.0.0 $^ 24 | + 25 | stemwords: $(STEMWORDS_OBJECTS) libstemmer.o 26 | $(CC) -o $@ $^ 27 | 28 | diff --git c/libstemmer/symbol.map i/libstemmer/symbol.map 29 | new file mode 100644 30 | index 0000000..7a3d423 31 | --- /dev/null 32 | +++ i/libstemmer/symbol.map 33 | @@ -0,0 +1,6 @@ 34 | +SB_STEMMER_0 { 35 | + global: 36 | + sb_stemmer_*; 37 | + local: 38 | + *; 39 | +}; 40 | -------------------------------------------------------------------------------- /experimental/flatpak/tilix-flatpak-toolbox.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc, char **argv) { 8 | if (argc != 3) { 9 | fprintf(stderr, "usage: tilix-flatpak-toolbox \n"); 10 | return 1; 11 | } 12 | 13 | if (strcmp(argv[1], "get-passwd") == 0) { 14 | execlp("getent", "getent", "passwd", argv[2], NULL); 15 | perror("error calling execlp"); 16 | return 1; 17 | } else if (strcmp(argv[1], "get-child-pid") == 0) { 18 | // Caller should have saved terminal to fd 3. 19 | pid_t pid = tcgetpgrp(3); 20 | if (pid == -1) { 21 | perror("error calling tcgetpgrp"); 22 | return 1; 23 | } 24 | 25 | printf("%ld\n", (long)pid); 26 | } else if (strcmp(argv[1], "get-proc-stat") == 0) { 27 | long value = strtol(argv[2], NULL, 10); 28 | char path[32]; 29 | snprintf(path, sizeof(path), "/proc/%lu/stat", value); 30 | 31 | FILE *fp = fopen(path, "r"); 32 | if (fp == NULL) { 33 | perror("error opening /proc//stat"); 34 | return 1; 35 | } 36 | 37 | for (;;) { 38 | char buf[1024]; 39 | int sz = fread(buf, 1, sizeof(buf)-1, fp); 40 | buf[sz] = 0; 41 | 42 | printf("%s", buf); 43 | 44 | if (sz < sizeof(buf)) { 45 | if (feof(fp)) { 46 | break; 47 | } else if (ferror(fp)) { 48 | perror("error reading from /proc//stat"); 49 | fclose(fp); 50 | return 1; 51 | } 52 | } 53 | } 54 | 55 | fclose(fp); 56 | fflush(stdout); 57 | } else { 58 | fprintf(stderr, "Invalid command: %s\n", argv[1]); 59 | return 1; 60 | } 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /experimental/flatpak/vte291-exceptions-gcc811.patch: -------------------------------------------------------------------------------- 1 | From a13b07d346b280592510e7ee6af05bc602197691 Mon Sep 17 00:00:00 2001 2 | From: Debarshi Ray 3 | Date: Tue, 19 Jun 2018 18:28:25 +0200 4 | Subject: [PATCH] parser: Fix the build with GCC 8.1.1 5 | 6 | Otherwise it fails with: 7 | 8 | vteseq.cc:47:1: error: declaration of 9 | 'void vte::parser::Sequence::print() const' has a different 10 | exception specifier 11 | vte::parser::Sequence::print() const 12 | ^~~ 13 | In file included from vteinternal.hh:30, 14 | from vteseq.cc:34: 15 | parser-glue.hh:83:14: note: from previous declaration 16 | 'void vte::parser::Sequence::print() const noexcept' 17 | void print() const noexcept; 18 | ^~~~~ 19 | 20 | ... and so on. 21 | 22 | Fixes GNOME/vte#5: 23 | https://gitlab.gnome.org/GNOME/vte/issues/5 24 | --- 25 | src/vteseq.cc | 6 +++--- 26 | 1 file changed, 3 insertions(+), 3 deletions(-) 27 | 28 | diff --git a/src/vteseq.cc b/src/vteseq.cc 29 | index ba97480c..98f71b87 100644 30 | --- a/src/vteseq.cc 31 | +++ b/src/vteseq.cc 32 | @@ -44,7 +44,7 @@ 33 | using namespace std::literals; 34 | 35 | void 36 | -vte::parser::Sequence::print() const 37 | +vte::parser::Sequence::print() const noexcept 38 | { 39 | #ifdef VTE_DEBUG 40 | auto c = m_seq != nullptr ? terminator() : 0; 41 | @@ -145,7 +145,7 @@ vte_unichar_strlen(gunichar const* c) 42 | */ 43 | char* 44 | vte::parser::Sequence::ucs4_to_utf8(gunichar const* str, 45 | - ssize_t len) const 46 | + ssize_t len) const noexcept 47 | { 48 | if (len < 0) 49 | len = vte_unichar_strlen(str); 50 | @@ -1406,7 +1406,7 @@ VteTerminalPrivate::set_color_index(vte::parser::Sequence const& seq, 51 | int number, 52 | int index, 53 | int index_fallback, 54 | - int osc) 55 | + int osc) noexcept 56 | { 57 | auto const str = *token; 58 | 59 | -- 60 | GitLab 61 | 62 | -------------------------------------------------------------------------------- /experimental/vte/0.52/alternate-screen.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h 2 | index 4e2896cf..16795eaa 100644 3 | --- a/src/vte/vteterminal.h 4 | +++ b/src/vte/vteterminal.h 5 | @@ -104,8 +104,10 @@ struct _VteTerminalClass { 6 | 7 | void (*bell)(VteTerminal* terminal); 8 | 9 | + void (*terminal_screen_changed)(VteTerminal* terminal); 10 | + 11 | /* Padding for future expansion. */ 12 | - gpointer padding[16]; 13 | + gpointer padding[15]; 14 | 15 | VteTerminalClassPrivate *priv; 16 | }; 17 | diff --git a/src/vtegtk.cc b/src/vtegtk.cc 18 | index 516e0425..33697c01 100644 19 | --- a/src/vtegtk.cc 20 | +++ b/src/vtegtk.cc 21 | @@ -739,6 +739,8 @@ vte_terminal_class_init(VteTerminalClass *klass) 22 | 23 | klass->bell = NULL; 24 | 25 | + klass->terminal_screen_changed = NULL; 26 | + 27 | /* GtkScrollable interface properties */ 28 | g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment"); 29 | g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment"); 30 | @@ -1286,6 +1288,23 @@ vte_terminal_class_init(VteTerminalClass *klass) 31 | g_cclosure_marshal_VOID__VOID, 32 | G_TYPE_NONE, 0); 33 | 34 | + /** 35 | + * VteTerminal::screen-changed: 36 | + * @vteterminal: the object which received the signal 37 | + * 38 | + * This signal is emitted when the terminal screen changes between 39 | + * normal and alternate screen. 40 | + */ 41 | + signals[SIGNAL_TERMINAL_SCREEN_CHANGED] = 42 | + g_signal_new(I_("terminal-screen-changed"), 43 | + G_OBJECT_CLASS_TYPE(klass), 44 | + G_SIGNAL_RUN_LAST, 45 | + G_STRUCT_OFFSET(VteTerminalClass, bell), 46 | + NULL, 47 | + NULL, 48 | + g_cclosure_marshal_VOID__INT, 49 | + G_TYPE_NONE, 1, G_TYPE_INT); 50 | + 51 | /** 52 | * VteTerminal:allow-bold: 53 | * 54 | diff --git a/src/vtegtk.hh b/src/vtegtk.hh 55 | index c49754ef..3a13e308 100644 56 | --- a/src/vtegtk.hh 57 | +++ b/src/vtegtk.hh 58 | @@ -52,6 +52,7 @@ enum { 59 | SIGNAL_RESIZE_WINDOW, 60 | SIGNAL_RESTORE_WINDOW, 61 | SIGNAL_SELECTION_CHANGED, 62 | + SIGNAL_TERMINAL_SCREEN_CHANGED, 63 | SIGNAL_TEXT_DELETED, 64 | SIGNAL_TEXT_INSERTED, 65 | SIGNAL_TEXT_MODIFIED, 66 | diff --git a/src/vteinternal.hh b/src/vteinternal.hh 67 | index f8139131..35334e70 100644 68 | --- a/src/vteinternal.hh 69 | +++ b/src/vteinternal.hh 70 | @@ -1359,6 +1359,8 @@ public: 71 | void select_empty(vte::grid::column_t col, 72 | vte::grid::row_t row); 73 | 74 | + void emit_terminal_screen_changed(int screen); 75 | + 76 | #define SEQUENCE_HANDLER(name) \ 77 | inline void seq_ ## name (vte::parser::Params const& params); 78 | #include "vteseq-list.hh" 79 | diff --git a/src/vteseq.cc b/src/vteseq.cc 80 | index 99b8bb37..b68b389d 100644 81 | --- a/src/vteseq.cc 82 | +++ b/src/vteseq.cc 83 | @@ -186,6 +186,13 @@ VteTerminalPrivate::emit_resize_window(guint columns, 84 | g_signal_emit(m_terminal, signals[SIGNAL_RESIZE_WINDOW], 0, columns, rows); 85 | } 86 | 87 | +/* Emit a "terminal-screen-changed" signal */ 88 | +void 89 | +VteTerminalPrivate::emit_terminal_screen_changed(int screen) 90 | +{ 91 | + _vte_debug_print(VTE_DEBUG_SIGNALS, "Emitting `terminal_screen_changed'.\n"); 92 | + g_signal_emit(m_terminal, signals[SIGNAL_TERMINAL_SCREEN_CHANGED], 0, screen); 93 | +} 94 | 95 | /* Some common functions */ 96 | 97 | @@ -446,6 +453,9 @@ void 98 | VteTerminalPrivate::switch_normal_screen() 99 | { 100 | switch_screen(&m_normal_screen); 101 | + 102 | + /* Emit signal */ 103 | + emit_terminal_screen_changed(0); 104 | } 105 | 106 | void 107 | @@ -478,6 +488,9 @@ void 108 | VteTerminalPrivate::switch_alternate_screen() 109 | { 110 | switch_screen(&m_alternate_screen); 111 | + 112 | + /* Emit signal */ 113 | + emit_terminal_screen_changed(1); 114 | } 115 | 116 | /* Switch to normal screen and restore cursor (in this order). */ 117 | -------------------------------------------------------------------------------- /experimental/vte/0.54/alternate-screen.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h 2 | index 89539cc4..080ed2e6 100644 3 | --- a/src/vte/vteterminal.h 4 | +++ b/src/vte/vteterminal.h 5 | @@ -104,8 +104,10 @@ struct _VteTerminalClass { 6 | 7 | void (*bell)(VteTerminal* terminal); 8 | 9 | + void (*terminal_screen_changed)(VteTerminal* terminal); 10 | + 11 | /* Padding for future expansion. */ 12 | - gpointer padding[16]; 13 | + gpointer padding[15]; 14 | 15 | VteTerminalClassPrivate *priv; 16 | }; 17 | diff --git a/src/vtegtk.cc b/src/vtegtk.cc 18 | index 89e3d7a8..60384168 100644 19 | --- a/src/vtegtk.cc 20 | +++ b/src/vtegtk.cc 21 | @@ -759,6 +759,8 @@ vte_terminal_class_init(VteTerminalClass *klass) 22 | 23 | klass->bell = NULL; 24 | 25 | + klass->terminal_screen_changed = NULL; 26 | + 27 | /* GtkScrollable interface properties */ 28 | g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment"); 29 | g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment"); 30 | @@ -1306,6 +1308,24 @@ vte_terminal_class_init(VteTerminalClass *klass) 31 | g_cclosure_marshal_VOID__VOID, 32 | G_TYPE_NONE, 0); 33 | 34 | + /** 35 | + * VteTerminal::screen-changed: 36 | + * @vteterminal: the object which received the signal 37 | + * 38 | + * This signal is emitted when the terminal screen changes between 39 | + * normal and alternate screen. 40 | + */ 41 | + signals[SIGNAL_TERMINAL_SCREEN_CHANGED] = 42 | + g_signal_new(I_("terminal-screen-changed"), 43 | + G_OBJECT_CLASS_TYPE(klass), 44 | + G_SIGNAL_RUN_LAST, 45 | + G_STRUCT_OFFSET(VteTerminalClass, terminal_screen_changed), 46 | + NULL, 47 | + NULL, 48 | + g_cclosure_marshal_VOID__INT, 49 | + G_TYPE_NONE, 1, G_TYPE_INT); 50 | + 51 | + 52 | /** 53 | * VteTerminal:allow-bold: 54 | * 55 | diff --git a/src/vtegtk.hh b/src/vtegtk.hh 56 | index c49754ef..bb814370 100644 57 | --- a/src/vtegtk.hh 58 | +++ b/src/vtegtk.hh 59 | @@ -52,6 +52,7 @@ enum { 60 | SIGNAL_RESIZE_WINDOW, 61 | SIGNAL_RESTORE_WINDOW, 62 | SIGNAL_SELECTION_CHANGED, 63 | + SIGNAL_TERMINAL_SCREEN_CHANGED, 64 | SIGNAL_TEXT_DELETED, 65 | SIGNAL_TEXT_INSERTED, 66 | SIGNAL_TEXT_MODIFIED, 67 | diff --git a/src/vteinternal.hh b/src/vteinternal.hh 68 | index 1652ca5f..3ba48d54 100644 69 | --- a/src/vteinternal.hh 70 | +++ b/src/vteinternal.hh 71 | @@ -1347,6 +1347,8 @@ public: 72 | vte::parser::StringTokeniser::const_iterator& token, 73 | vte::parser::StringTokeniser::const_iterator const& endtoken) noexcept; 74 | 75 | + void emit_terminal_screen_changed(int screen); 76 | + 77 | /* Sequence handlers */ 78 | bool m_line_wrapped; // signals line wrapped from character insertion 79 | // Note: inlining the handlers seems to worsen the performance, so we don't do that 80 | diff --git a/src/vteseq.cc b/src/vteseq.cc 81 | index 877cc571..4d4cf226 100644 82 | --- a/src/vteseq.cc 83 | +++ b/src/vteseq.cc 84 | @@ -249,6 +249,15 @@ Terminal::emit_resize_window(guint columns, 85 | g_signal_emit(m_terminal, signals[SIGNAL_RESIZE_WINDOW], 0, columns, rows); 86 | } 87 | 88 | +void 89 | +Terminal::emit_terminal_screen_changed(int screen) 90 | +{ 91 | + _vte_debug_print(VTE_DEBUG_SIGNALS, "Emitting `terminal_screen_changed'.\n"); 92 | + g_signal_emit(m_terminal, signals[SIGNAL_TERMINAL_SCREEN_CHANGED], 0, screen); 93 | +} 94 | + 95 | + 96 | + 97 | /* Some common functions */ 98 | 99 | /* In Xterm, upon printing a character in the last column the cursor doesn't 100 | @@ -405,6 +414,9 @@ void 101 | Terminal::switch_normal_screen() 102 | { 103 | switch_screen(&m_normal_screen); 104 | + 105 | + /* Emit signal */ 106 | + emit_terminal_screen_changed(0); 107 | } 108 | 109 | void 110 | @@ -437,6 +449,9 @@ void 111 | Terminal::switch_alternate_screen() 112 | { 113 | switch_screen(&m_alternate_screen); 114 | + 115 | + /* Emit signal */ 116 | + emit_terminal_screen_changed(1); 117 | } 118 | 119 | void 120 | -------------------------------------------------------------------------------- /experimental/vte/README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | This folder contains patches to the GTK 3 VTE widget to support additional functionality in Terminix. The VTE widget provides the actual underlying terminal emulation and is used by many terminal emulators including gnome-terminal, terminator, xfce4-terminal, etc. 4 | 5 | Since the VTE is the component providing the terminal emulation, there is a limit to what Terminix can do in terms of supporting features. The VTE widget quite rightly abstracts a lot of this and provides higher level functionality to the enclosing application. Anything that involves interacting with the other underlying terminal emulation such as handling OSC codes, understanding the alternate screem, etc may require changes in the VTE to support. 6 | 7 | In an ideal world the patches available here would be upstreamed or equivalent functionality provided by upstream. Upstream typically prefers higher level patches that fully encompass the functionality to benefit all of the terminal emulators that depend on VTE, and this is the right approach in my opinion. However time is not infinite and my skills with C are limited so it's not always possible to make this happen. As well, sometimes I want to POC some piece of functionality before making a full commitment to implement it in VTE and a tactical approach is used in these cases. 8 | 9 | Generally the patches contained here should be considered experimental and applied cautiously. If you are not comfortable with development you are probably better off avoiding them. 10 | 11 | Finally note that applying these patches can break other terminal emulators depending on VTE, I make no guarentee of fitness or suitability. 12 | 13 | ## Patches 14 | 15 | The following patches are available: 16 | 17 | | Patch | Compatible | Description | 18 | |---|---|---| 19 | | alternate-screen.patch| Yes | This patch adds a new event to the VTE that signals when the terminal switches between normal and alternate screens. This patch is required to support triggers which are deactivated in Terminix unless this new event is detected as being available. Note that if this patch is applied with the fedora-notifications patch, the padding field in /src/vte/vteterminal.h must be decremented from 15 to 14 since that patch also adds a new event. Failure to do so will break gnome-terminal. 20 | |disable-bg-draw.patch| Yes| This patch adds a new property to the VTE that disables the background draw and allows the application to assume responsibility for it. In Terminix this is used to support badges, however if it gets accepted by upstream some of the other features like background image will leverage it in teh future. | 21 | 22 | ## Testing Patches 23 | 24 | To test these patches, you will need to manually compile the vte widget. To do so, first clone the VTE git respository: 25 | 26 | ``` 27 | git clone https://github.com/GNOME/vte 28 | ``` 29 | 30 | Next you will need to select either the 0.44 or 0.46 branches, these patches should work with either: 31 | 32 | ``` 33 | cd vte 34 | git checkout vte-0-46 35 | ``` 36 | 37 | At this point we can apply the patches. Copy the patches into the vte directory and then run the following: 38 | 39 | ``` 40 | patch -p1 -i alternate-screen.patch 41 | patch -p1 -i disable-bg-draw.patch 42 | ``` 43 | 44 | Finally build vte as normal: 45 | 46 | ``` 47 | ./autogen.sh 48 | make 49 | ``` 50 | 51 | And finally to run terminix with the patched VTE: 52 | 53 | ``` 54 | LD_PRELOAD=src/.libs/libvte-2.91.so terminix 55 | ``` -------------------------------------------------------------------------------- /experimental/vte/alternate-screen.patch: -------------------------------------------------------------------------------- 1 | From eee603b537de69b778095059c78de771f16f49af Mon Sep 17 00:00:00 2001 2 | From: gnunn1 3 | Date: Sat, 20 Aug 2016 14:25:54 -0400 4 | Subject: [PATCH 1/2] Add terminal-screen-changed signal 5 | 6 | --- 7 | src/vte/vteterminal.h | 2 ++ 8 | src/vtegtk.cc | 19 +++++++++++++++++++ 9 | src/vtegtk.hh | 1 + 10 | src/vteinternal.hh | 2 ++ 11 | src/vteseq.cc | 12 ++++++++++++ 12 | 5 files changed, 36 insertions(+) 13 | 14 | diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h 15 | index 7836271..5741f47 100644 16 | --- a/src/vte/vteterminal.h 17 | +++ b/src/vte/vteterminal.h 18 | @@ -104,6 +104,8 @@ struct _VteTerminalClass { 19 | 20 | void (*bell)(VteTerminal* terminal); 21 | 22 | + void (*terminal_screen_changed)(VteTerminal* terminal); 23 | + 24 | /* Padding for future expansion. */ 25 | gpointer padding[16]; 26 | 27 | diff --git a/src/vtegtk.cc b/src/vtegtk.cc 28 | index c9dbddc..cacf6e5 100644 29 | --- a/src/vtegtk.cc 30 | +++ b/src/vtegtk.cc 31 | @@ -687,6 +687,8 @@ vte_terminal_class_init(VteTerminalClass *klass) 32 | 33 | klass->bell = NULL; 34 | 35 | + klass->terminal_screen_changed = NULL; 36 | + 37 | /* GtkScrollable interface properties */ 38 | g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment"); 39 | g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment"); 40 | @@ -1206,6 +1208,23 @@ vte_terminal_class_init(VteTerminalClass *klass) 41 | G_TYPE_NONE, 0); 42 | 43 | /** 44 | + * VteTerminal::screen-changed: 45 | + * @vteterminal: the object which received the signal 46 | + * 47 | + * This signal is emitted when the terminal screen changes between 48 | + * normal and alternate screen. 49 | + */ 50 | + signals[SIGNAL_TERMINAL_SCREEN_CHANGED] = 51 | + g_signal_new(I_("terminal-screen-changed"), 52 | + G_OBJECT_CLASS_TYPE(klass), 53 | + G_SIGNAL_RUN_LAST, 54 | + G_STRUCT_OFFSET(VteTerminalClass, bell), 55 | + NULL, 56 | + NULL, 57 | + g_cclosure_marshal_VOID__INT, 58 | + G_TYPE_NONE, 1, G_TYPE_INT); 59 | + 60 | + /** 61 | * VteTerminal:allow-bold: 62 | * 63 | * Controls whether or not the terminal will attempt to draw bold text. 64 | diff --git a/src/vtegtk.hh b/src/vtegtk.hh 65 | index 5340725..118f38c 100644 66 | --- a/src/vtegtk.hh 67 | +++ b/src/vtegtk.hh 68 | @@ -51,6 +51,7 @@ enum { 69 | SIGNAL_RESIZE_WINDOW, 70 | SIGNAL_RESTORE_WINDOW, 71 | SIGNAL_SELECTION_CHANGED, 72 | + SIGNAL_TERMINAL_SCREEN_CHANGED, 73 | SIGNAL_TEXT_DELETED, 74 | SIGNAL_TEXT_INSERTED, 75 | SIGNAL_TEXT_MODIFIED, 76 | diff --git a/src/vteinternal.hh b/src/vteinternal.hh 77 | index cff2157..8b6e7cc 100644 78 | --- a/src/vteinternal.hh 79 | +++ b/src/vteinternal.hh 80 | @@ -1181,6 +1181,8 @@ public: 81 | vte::grid::row_t end_row); 82 | void select_empty(vte::grid::column_t col, 83 | vte::grid::row_t row); 84 | + 85 | + void emit_terminal_screen_changed(int screen); 86 | }; 87 | 88 | extern GTimer *process_timer; 89 | diff --git a/src/vteseq.cc b/src/vteseq.cc 90 | index 2330939..09eb648 100644 91 | --- a/src/vteseq.cc 92 | +++ b/src/vteseq.cc 93 | @@ -202,6 +202,12 @@ VteTerminalPrivate::emit_resize_window(guint columns, 94 | g_signal_emit(m_terminal, signals[SIGNAL_RESIZE_WINDOW], 0, columns, rows); 95 | } 96 | 97 | +void 98 | +VteTerminalPrivate::emit_terminal_screen_changed(int screen) 99 | +{ 100 | + _vte_debug_print(VTE_DEBUG_SIGNALS, "Emitting `terminal_screen_changed'.\n"); 101 | + g_signal_emit(m_terminal, signals[SIGNAL_TERMINAL_SCREEN_CHANGED], 0, screen); 102 | +} 103 | 104 | /* Some common functions */ 105 | 106 | @@ -380,6 +386,9 @@ void 107 | VteTerminalPrivate::seq_normal_screen() 108 | { 109 | seq_switch_screen(&m_normal_screen); 110 | + 111 | + /* Emit signal */ 112 | + emit_terminal_screen_changed(0); 113 | } 114 | 115 | void 116 | @@ -407,6 +416,9 @@ void 117 | VteTerminalPrivate::seq_alternate_screen() 118 | { 119 | seq_switch_screen(&m_alternate_screen); 120 | + 121 | + /* Emit signal */ 122 | + emit_terminal_screen_changed(1); 123 | } 124 | 125 | /* Switch to normal screen and restore cursor (in this order). */ 126 | -- 127 | 2.9.3 128 | 129 | 130 | From 17864fdc08cde1b767f5af78386d1566ab33e515 Mon Sep 17 00:00:00 2001 131 | From: gnunn1 132 | Date: Sat, 20 Aug 2016 19:12:13 -0400 133 | Subject: [PATCH 2/2] Fix padding 134 | 135 | --- 136 | src/vte/vteterminal.h | 2 +- 137 | src/vteseq.cc | 1 + 138 | 2 files changed, 2 insertions(+), 1 deletion(-) 139 | 140 | diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h 141 | index 5741f47..7f93e85 100644 142 | --- a/src/vte/vteterminal.h 143 | +++ b/src/vte/vteterminal.h 144 | @@ -107,7 +107,7 @@ struct _VteTerminalClass { 145 | void (*terminal_screen_changed)(VteTerminal* terminal); 146 | 147 | /* Padding for future expansion. */ 148 | - gpointer padding[16]; 149 | + gpointer padding[15]; 150 | 151 | VteTerminalClassPrivate *priv; 152 | }; 153 | diff --git a/src/vteseq.cc b/src/vteseq.cc 154 | index 09eb648..eb741e1 100644 155 | --- a/src/vteseq.cc 156 | +++ b/src/vteseq.cc 157 | @@ -202,6 +202,7 @@ VteTerminalPrivate::emit_resize_window(guint columns, 158 | g_signal_emit(m_terminal, signals[SIGNAL_RESIZE_WINDOW], 0, columns, rows); 159 | } 160 | 161 | +/* Emit a "terminal-screen-changed" signal */ 162 | void 163 | VteTerminalPrivate::emit_terminal_screen_changed(int screen) 164 | { 165 | -- 166 | 2.9.3 167 | 168 | -------------------------------------------------------------------------------- /extract-strings.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | DOMAIN=tilix 5 | BASEDIR=$(dirname $0) 6 | OUTPUT_FILE=${BASEDIR}/po/${DOMAIN}.pot 7 | 8 | echo "Extracting translatable strings... " 9 | 10 | # Extract the strings from D source code. Since xgettext does not support D 11 | # as a language we use Vala, which works reasonable well. 12 | find ${BASEDIR}/source -name '*.d' | xgettext \ 13 | --output $OUTPUT_FILE \ 14 | --files-from=- \ 15 | --directory=$BASEDIR \ 16 | --language=Vala \ 17 | --keyword=C_:1c,2 \ 18 | --from-code=utf-8 \ 19 | --add-comments=TRANSLATORS 20 | 21 | xgettext \ 22 | --join-existing \ 23 | --output $OUTPUT_FILE \ 24 | --directory=$BASEDIR \ 25 | ${BASEDIR}/data/nautilus/open-tilix.py 26 | 27 | # Glade UI Files 28 | find ${BASEDIR}/data/resources/ui -name '*.ui' | xgettext \ 29 | --join-existing \ 30 | --output $OUTPUT_FILE \ 31 | --files-from=- \ 32 | --directory=$BASEDIR \ 33 | --language=Glade \ 34 | --from-code=utf-8 35 | 36 | xgettext \ 37 | --join-existing \ 38 | --output $OUTPUT_FILE \ 39 | --default-domain=$DOMAIN \ 40 | --package-name=$DOMAIN \ 41 | --directory=$BASEDIR \ 42 | --foreign-user \ 43 | --language=Desktop \ 44 | ${BASEDIR}/data/pkg/desktop/com.gexperts.Tilix.desktop.in 45 | 46 | TMP_METAINFO_FILE=${BASEDIR}/data/metainfo/com.gexperts.Tilix.appdata.xml.rel.in 47 | appstreamcli news-to-metainfo ${BASEDIR}/NEWS \ 48 | ${BASEDIR}/data/metainfo/com.gexperts.Tilix.appdata.xml.in \ 49 | ${TMP_METAINFO_FILE} 50 | xgettext \ 51 | --join-existing \ 52 | --output $OUTPUT_FILE \ 53 | --default-domain=$DOMAIN \ 54 | --package-name=$DOMAIN \ 55 | --directory=$BASEDIR \ 56 | --foreign-user \ 57 | --language=appdata \ 58 | ${TMP_METAINFO_FILE} 59 | rm -f ${TMP_METAINFO_FILE} 60 | 61 | # Merge the messages with existing po files 62 | echo "Merging with existing translations... " 63 | for file in ${BASEDIR}/po/*.po 64 | do 65 | echo -n $file 66 | msgmerge -F --update $file $OUTPUT_FILE 67 | done 68 | 69 | echo "Updating LINGUAS file..." 70 | find ${BASEDIR}/po \ 71 | -type f \ 72 | -iname "*.po" \ 73 | -printf '%f\n' \ 74 | | grep -oP '.*(?=[.])' | sort \ 75 | > ${BASEDIR}/po/LINGUAS 76 | 77 | # Update manpage translations 78 | echo "Updating manpage translations..." 79 | if type po4a-updatepo >/dev/null 2>&1; then 80 | MANDIR=${BASEDIR}/data/man 81 | po4a-gettextize -f man -m ${MANDIR}/tilix.1 -p ${MANDIR}/po/tilix.1.man.pot 82 | for file in ${MANDIR}/po/*.man.po 83 | do 84 | echo -n $file 85 | po4a-updatepo -f man -m ${MANDIR}/tilix.1 -p $file 86 | done 87 | fi 88 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # exit on first error 3 | set -o errexit 4 | 5 | # Determine PREFIX. 6 | if [ -z "$1" ]; then 7 | if [ -z "$PREFIX" ]; then 8 | PREFIX='/usr' 9 | fi 10 | else 11 | PREFIX="$1" 12 | fi 13 | export PREFIX 14 | 15 | if [ "$PREFIX" = "/usr" ] && [ "$(id -u)" != "0" ]; then 16 | # Make sure only root can run our script 17 | echo "This script must be run as root" 1>&2 18 | exit 1 19 | fi 20 | 21 | if [ ! -f tilix ]; then 22 | echo "The tilix executable does not exist, please run 'dub build --build=release' before using this script" 23 | exit 1 24 | fi 25 | 26 | # Check availability of required commands 27 | COMMANDS="install glib-compile-schemas glib-compile-resources msgfmt desktop-file-validate gtk-update-icon-cache" 28 | if [ "$PREFIX" = '/usr' ] || [ "$PREFIX" = "/usr/local" ]; then 29 | COMMANDS="$COMMANDS xdg-desktop-menu" 30 | fi 31 | PACKAGES="coreutils glib2 gettext desktop-file-utils gtk-update-icon-cache xdg-utils" 32 | i=0 33 | for COMMAND in $COMMANDS; do 34 | type $COMMAND >/dev/null 2>&1 || { 35 | j=0 36 | for PACKAGE in $PACKAGES; do 37 | if [ $i = $j ]; then 38 | break 39 | fi 40 | j=$(( $j + 1 )) 41 | done 42 | echo "Your system is missing command $COMMAND, please install $PACKAGE" 43 | exit 1 44 | } 45 | i=$(( $i + 1 )) 46 | done 47 | 48 | echo "Installing to prefix $PREFIX" 49 | 50 | # Copy and compile schema 51 | echo "Copying and compiling schema..." 52 | install -Dm 644 data/gsettings/com.gexperts.Tilix.gschema.xml -t "$PREFIX/share/glib-2.0/schemas/" 53 | glib-compile-schemas $PREFIX/share/glib-2.0/schemas/ 54 | 55 | export TILIX_SHARE="$PREFIX/share/tilix" 56 | 57 | # Copy and compile icons 58 | cd data/resources 59 | 60 | echo "Building and copy resources..." 61 | glib-compile-resources tilix.gresource.xml 62 | install -Dm 644 tilix.gresource -t "$TILIX_SHARE/resources/" 63 | 64 | cd ../.. 65 | 66 | # Copy shell integration script 67 | echo "Copying scripts..." 68 | install -Dm 755 data/scripts/* -t "$TILIX_SHARE/scripts/" 69 | 70 | # Copy color schemes 71 | echo "Copying color schemes..." 72 | install -Dm 644 data/schemes/* -t "$TILIX_SHARE/schemes/" 73 | 74 | # Create/Update LINGUAS file 75 | find po -name "*\.po" -printf "%f\\n" | sed "s/\.po//g" | sort > po/LINGUAS 76 | 77 | # Compile po files 78 | echo "Copying and installing localization files" 79 | for f in po/*.po; do 80 | echo "Processing $f" 81 | LOCALE=$(basename "$f" .po) 82 | msgfmt $f -o "$LOCALE.mo" 83 | install -Dm 644 "$LOCALE.mo" "$PREFIX/share/locale/$LOCALE/LC_MESSAGES/tilix.mo" 84 | rm -f "$LOCALE.mo" 85 | done 86 | 87 | # Generate desktop file 88 | msgfmt --desktop --template=data/pkg/desktop/com.gexperts.Tilix.desktop.in -d po -o data/pkg/desktop/com.gexperts.Tilix.desktop 89 | if [ $? -ne 0 ]; then 90 | echo "Note that localizating appdata requires a newer version of xgettext, copying instead" 91 | cp data/pkg/desktop/com.gexperts.Tilix.desktop.in data/pkg/desktop/com.gexperts.Tilix.desktop 92 | fi 93 | 94 | desktop-file-validate data/pkg/desktop/com.gexperts.Tilix.desktop 95 | 96 | # Generate appdata file, requires xgettext 0.19.7 97 | msgfmt --xml --template=data/metainfo/com.gexperts.Tilix.appdata.xml.in -d po -o data/metainfo/com.gexperts.Tilix.appdata.xml 98 | if [ $? -ne 0 ]; then 99 | echo "Note that localizating appdata requires xgettext 0.19.7 or later, copying instead" 100 | cp data/metainfo/com.gexperts.Tilix.appdata.xml.in data/metainfo/com.gexperts.Tilix.appdata.xml 101 | fi 102 | 103 | # Copying Nautilus extension 104 | echo "Copying Nautilus extension" 105 | install -Dm 644 data/nautilus/open-tilix.py -t "$PREFIX/share/nautilus-python/extensions/" 106 | 107 | # Copy D-Bus service descriptor 108 | install -Dm 644 data/dbus/com.gexperts.Tilix.service -t "$PREFIX/share/dbus-1/services/" 109 | 110 | # Copy man page 111 | . $(dirname $(realpath "$0"))/data/scripts/install-man-pages.sh 112 | 113 | # Copy Icons 114 | cd data/icons/hicolor 115 | 116 | find . -type f | while read f; do 117 | install -Dm 644 "$f" "$PREFIX/share/icons/hicolor/$f" 118 | done 119 | 120 | cd ../../.. 121 | 122 | # Copy executable, desktop and appdata file 123 | install -Dm 755 tilix -t "$PREFIX/bin/" 124 | 125 | install -Dm 644 data/pkg/desktop/com.gexperts.Tilix.desktop -t "$PREFIX/share/applications/" 126 | install -Dm 644 data/metainfo/com.gexperts.Tilix.appdata.xml -t "$PREFIX/share/metainfo/" 127 | 128 | # Update icon cache if Prefix is /usr 129 | if [ "$PREFIX" = '/usr' ] || [ "$PREFIX" = "/usr/local" ]; then 130 | echo "Updating desktop file cache" 131 | xdg-desktop-menu forceupdate --mode system 132 | 133 | echo "Updating icon cache" 134 | gtk-update-icon-cache -f "$PREFIX/share/icons/hicolor/" 135 | fi 136 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project( 2 | 'Tilix', 'd', 3 | version: '1.9.7', 4 | license: 'MPL-2.0', 5 | meson_version: '>= 0.56' 6 | ) 7 | 8 | compiler = meson.get_compiler('d') 9 | if compiler.get_id() == 'llvm' 10 | d_extra_args = ['-vcolumns'] 11 | d_link_args = [] 12 | else 13 | d_extra_args = [] 14 | d_link_args = [] 15 | endif 16 | 17 | project_id = 'com.gexperts.Tilix' 18 | project_name = meson.project_name() 19 | 20 | gnome = import('gnome') 21 | i18n = import('i18n') 22 | 23 | prefix = get_option('prefix') 24 | bindir = prefix / get_option('bindir') 25 | datadir = prefix / get_option('datadir') 26 | pkgdatadir = datadir / project_name.to_lower() 27 | schemadir = datadir / 'glib-2.0' / 'schemas' 28 | iconsdir = datadir / 'icons' / 'hicolor' 29 | appdir = datadir / 'applications' 30 | 31 | tilix_sources = [ 32 | 'source/gx/gtk/actions.d', 33 | 'source/gx/gtk/cairo.d', 34 | 'source/gx/gtk/clipboard.d', 35 | 'source/gx/gtk/color.d', 36 | 'source/gx/gtk/dialog.d', 37 | 'source/gx/gtk/resource.d', 38 | 'source/gx/gtk/settings.d', 39 | 'source/gx/gtk/threads.d', 40 | 'source/gx/gtk/util.d', 41 | 'source/gx/gtk/vte.d', 42 | 'source/gx/gtk/x11.d', 43 | 'source/gx/i18n/l10n.d', 44 | 'source/gx/tilix/bookmark/bmchooser.d', 45 | 'source/gx/tilix/bookmark/bmeditor.d', 46 | 'source/gx/tilix/bookmark/bmtreeview.d', 47 | 'source/gx/tilix/bookmark/manager.d', 48 | 'source/gx/tilix/prefeditor/advdialog.d', 49 | 'source/gx/tilix/prefeditor/bookmarkeditor.d', 50 | 'source/gx/tilix/prefeditor/common.d', 51 | 'source/gx/tilix/prefeditor/prefdialog.d', 52 | 'source/gx/tilix/prefeditor/profileeditor.d', 53 | 'source/gx/tilix/prefeditor/titleeditor.d', 54 | 'source/gx/tilix/terminal/actions.d', 55 | 'source/gx/tilix/terminal/activeprocess.d', 56 | 'source/gx/tilix/terminal/advpaste.d', 57 | 'source/gx/tilix/terminal/exvte.d', 58 | 'source/gx/tilix/terminal/layout.d', 59 | 'source/gx/tilix/terminal/monitor.d', 60 | 'source/gx/tilix/terminal/password.d', 61 | 'source/gx/tilix/terminal/regex.d', 62 | 'source/gx/tilix/terminal/search.d', 63 | 'source/gx/tilix/terminal/terminal.d', 64 | 'source/gx/tilix/terminal/util.d', 65 | 'source/gx/tilix/application.d', 66 | 'source/gx/tilix/appwindow.d', 67 | 'source/gx/tilix/closedialog.d', 68 | 'source/gx/tilix/cmdparams.d', 69 | 'source/gx/tilix/colorschemes.d', 70 | 'source/gx/tilix/common.d', 71 | 'source/gx/tilix/constants.d', 72 | 'source/gx/tilix/customtitle.d', 73 | 'source/gx/tilix/encoding.d', 74 | 'source/gx/tilix/preferences.d', 75 | 'source/gx/tilix/session.d', 76 | 'source/gx/tilix/shortcuts.d', 77 | 'source/gx/tilix/sidebar.d', 78 | 'source/gx/util/array.d', 79 | 'source/gx/util/path.d', 80 | 'source/gx/util/string.d', 81 | 'source/secret/Collection.d', 82 | 'source/secret/Item.d', 83 | 'source/secret/Prompt.d', 84 | 'source/secret/Schema.d', 85 | 'source/secret/SchemaAttribute.d', 86 | 'source/secret/Secret.d', 87 | 'source/secret/Service.d', 88 | 'source/secret/Value.d', 89 | 'source/secretc/secret.d', 90 | 'source/secretc/secrettypes.d', 91 | 'source/x11/X.d', 92 | 'source/x11/Xlib.d', 93 | 'source/app.d' 94 | ] 95 | 96 | sources_dir = include_directories('source/') 97 | 98 | # Dependencies 99 | gtkd_dep = dependency('gtkd-3', version: '>=3.8.5') 100 | vted_dep = dependency('vted-3', version: '>=3.8.5') 101 | xlib_dep = dependency('x11') 102 | libunwind_dep = dependency('libunwind') 103 | libsecret_dep = dependency('libsecret-1', required: false) 104 | 105 | subdir('po') 106 | subdir('data') 107 | 108 | # Build & Test 109 | executable('tilix', 110 | [tilix_sources, gresource], 111 | include_directories : sources_dir, 112 | dependencies : [gtkd_dep, 113 | vted_dep, 114 | xlib_dep, 115 | libunwind_dep, 116 | libsecret_dep], 117 | d_args: d_extra_args, 118 | d_module_versions: ['StdLoggerDisableTrace'], 119 | link_args: d_link_args, 120 | install : true 121 | ) 122 | 123 | tilix_test_exe = executable('tilix_test', 124 | [tilix_sources], 125 | include_directories : [sources_dir], 126 | dependencies : [gtkd_dep, 127 | vted_dep, 128 | xlib_dep], 129 | d_args: d_extra_args, 130 | link_args: d_link_args, 131 | d_unittest: true 132 | ) 133 | test('tilix_test', tilix_test_exe) 134 | 135 | meson.add_install_script('meson_post_install.py') 136 | -------------------------------------------------------------------------------- /meson_post_install.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from os import environ, path 3 | from subprocess import call 4 | 5 | if not environ.get('DESTDIR', ''): 6 | PREFIX = environ.get('MESON_INSTALL_PREFIX', '/usr/local') 7 | DATA_DIR = path.join(PREFIX, 'share') 8 | print('Updating icon cache...') 9 | call(['gtk-update-icon-cache', '-qtf', path.join(DATA_DIR, 'icons/hicolor')]) 10 | print("compiling new schemas") 11 | call(["glib-compile-schemas", path.join(DATA_DIR, 'glib-2.0/schemas/')]) 12 | print("Updating desktop database") 13 | call(["update-desktop-database", path.join(DATA_DIR, 'applications')]) -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | ak 2 | ar 3 | ar_MA 4 | bg 5 | ca 6 | cs 7 | de 8 | el 9 | en_GB 10 | eo 11 | es 12 | eu 13 | fi 14 | fr 15 | gl 16 | he 17 | hr 18 | hu 19 | id 20 | is 21 | it 22 | ja 23 | ko 24 | lt 25 | mr 26 | nb_NO 27 | ne 28 | nl 29 | oc 30 | pl 31 | pt_BR 32 | pt_PT 33 | ro 34 | ru 35 | sr 36 | sv 37 | tr 38 | uk 39 | vi 40 | zh_CN 41 | zh_TW 42 | -------------------------------------------------------------------------------- /po/Makevars: -------------------------------------------------------------------------------- 1 | # Makefile variables for PO directory in any package using GNU gettext. 2 | 3 | # Usually the message domain is the same as the package name. 4 | DOMAIN = $(PACKAGE) 5 | 6 | # These two variables depend on the location of this directory. 7 | subdir = po 8 | top_builddir = .. 9 | 10 | # These options get passed to xgettext. 11 | XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ 12 | 13 | # This is the copyright holder that gets inserted into the header of the 14 | # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding 15 | # package. (Note that the msgstr strings, extracted from the package's 16 | # sources, belong to the copyright holder of the package.) Translators are 17 | # expected to transfer the copyright for their translations to this person 18 | # or entity, or to disclaim their copyright. The empty string stands for 19 | # the public domain; in this case the translators are expected to disclaim 20 | # their copyright. 21 | COPYRIGHT_HOLDER = Free Software Foundation, Inc. 22 | 23 | # This tells whether or not to prepend "GNU " prefix to the package 24 | # name that gets inserted into the header of the $(DOMAIN).pot file. 25 | # Possible values are "yes", "no", or empty. If it is empty, try to 26 | # detect it automatically by scanning the files in $(top_srcdir) for 27 | # "GNU packagename" string. 28 | PACKAGE_GNU = 29 | 30 | # This is the email address or URL to which the translators shall report 31 | # bugs in the untranslated strings: 32 | # - Strings which are not entire sentences, see the maintainer guidelines 33 | # in the GNU gettext documentation, section 'Preparing Strings'. 34 | # - Strings which use unclear terms or require additional context to be 35 | # understood. 36 | # - Strings which make invalid assumptions about notation of date, time or 37 | # money. 38 | # - Pluralisation problems. 39 | # - Incorrect English spelling. 40 | # - Incorrect formatting. 41 | # It can be your email address, or a mailing list address where translators 42 | # can write to without being subscribed, or the URL of a web page through 43 | # which the translators can contact you. 44 | MSGID_BUGS_ADDRESS = 45 | 46 | # This is the list of locale categories, beyond LC_MESSAGES, for which the 47 | # message catalogs shall be used. It is usually empty. 48 | EXTRA_LOCALE_CATEGORIES = 49 | 50 | # This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' 51 | # context. Possible values are "yes" and "no". Set this to yes if the 52 | # package uses functions taking also a message context, like pgettext(), or 53 | # if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. 54 | USE_MSGCTXT = no 55 | 56 | # These options get passed to msgmerge. 57 | # Useful options are in particular: 58 | # --previous to keep previous msgids of translated messages, 59 | # --quiet to reduce the verbosity. 60 | MSGMERGE_OPTIONS = 61 | 62 | # These options get passed to msginit. 63 | # If you want to disable line wrapping when writing PO files, add 64 | # --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and 65 | # MSGINIT_OPTIONS. 66 | MSGINIT_OPTIONS = 67 | 68 | # This tells whether or not to regenerate a PO file when $(DOMAIN).pot 69 | # has changed. Possible values are "yes" and "no". Set this to no if 70 | # the POT file is checked in the repository and the version control 71 | # program ignores timestamps. 72 | PO_DEPENDS_ON_POT = no 73 | 74 | # This tells whether or not to forcibly update $(DOMAIN).pot and 75 | # regenerate PO files on "make dist". Possible values are "yes" and 76 | # "no". Set this to no if the POT file and PO files are maintained 77 | # externally. 78 | DIST_DEPENDS_ON_UPDATE_PO = no 79 | -------------------------------------------------------------------------------- /po/POTFILES.in: -------------------------------------------------------------------------------- 1 | # Using 'make update-po' does not work (multiple types of sources of translatable strings) 2 | # Use the script 'extract-strings.sh' to update pot and po files. 3 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext('tilix', preset: 'glib') -------------------------------------------------------------------------------- /source/gx/gtk/clipboard.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.gtk.clipboard; 6 | 7 | import gdk.Atom; 8 | 9 | /* Clipboard Atoms */ 10 | GdkAtom GDK_SELECTION_CLIPBOARD; 11 | GdkAtom GDK_SELECTION_PRIMARY; 12 | GdkAtom GDK_SELECTION_SECONDARY; 13 | 14 | static this() { 15 | GDK_SELECTION_CLIPBOARD = intern("CLIPBOARD", true); 16 | GDK_SELECTION_PRIMARY = intern("PRIMARY", true); 17 | GDK_SELECTION_SECONDARY = intern("SECONDARY", true); 18 | } -------------------------------------------------------------------------------- /source/gx/gtk/color.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | 6 | module gx.gtk.color; 7 | 8 | import std.conv; 9 | import std.experimental.logger; 10 | import std.format; 11 | 12 | import gdk.RGBA; 13 | 14 | public: 15 | 16 | /** 17 | * Converts an RGBA structure to a 8 bit HEX string, i.e #2E3436 18 | * 19 | * Params: 20 | * RGBA = The color to convert 21 | * includeAlpha = Whether to include the alpha channel 22 | * includeHash = Whether to preface the color string with a # 23 | */ 24 | string rgbaTo8bitHex(RGBA color, bool includeAlpha = false, bool includeHash = false) { 25 | string prepend = includeHash ? "#" : ""; 26 | int red = to!(int)(color.red() * 255); 27 | int green = to!(int)(color.green() * 255); 28 | int blue = to!(int)(color.blue() * 255); 29 | if (includeAlpha) { 30 | int alpha = to!(int)(color.alpha() * 255); 31 | return prepend ~ format("%02X%02X%02X%02X", red, green, blue, alpha); 32 | } else { 33 | return prepend ~ format("%02X%02X%02X", red, green, blue); 34 | } 35 | } 36 | 37 | /** 38 | * Converts an RGBA structure to a 16 bit HEX string, i.e #2E2E34343636 39 | * Right now this just takes an 8 bit string and repeats each channel 40 | * 41 | * Params: 42 | * RGBA = The color to convert 43 | * includeAlpha = Whether to include the alpha channel 44 | * includeHash = Whether to preface the color string with a # 45 | */ 46 | string rgbaTo16bitHex(RGBA color, bool includeAlpha = false, bool includeHash = false) { 47 | string prepend = includeHash ? "#" : ""; 48 | int red = to!(int)(color.red() * 255); 49 | int green = to!(int)(color.green() * 255); 50 | int blue = to!(int)(color.blue() * 255); 51 | if (includeAlpha) { 52 | int alpha = to!(int)(color.alpha() * 255); 53 | return prepend ~ format("%02X%02X%02X%02X%02X%02X%02X%02X", red, red, green, green, blue, blue, alpha, alpha); 54 | } else { 55 | return prepend ~ format("%02X%02X%02X%02X%02X%02X", red, red, green, green, blue, blue); 56 | } 57 | } 58 | 59 | RGBA getOppositeColor(RGBA rgba) { 60 | RGBA result = new RGBA(1.0 - rgba.red, 1 - rgba.green, 1 - rgba.red, rgba.alpha); 61 | tracef("Original: %s, New: %s", rgbaTo8bitHex(rgba, true, true), rgbaTo8bitHex(result, true, true)); 62 | return result; 63 | } 64 | 65 | void contrast(double percent, RGBA rgba, out double r, out double g, out double b) { 66 | double brightness = ((rgba.red * 299.0) + (rgba.green * 587.0) + (rgba.blue * 114.0)) / 1000; 67 | if (brightness > 0.5) darken(percent, rgba, r, g, b); 68 | else lighten(percent, rgba, r, g, b); 69 | } 70 | 71 | void lighten(double percent, RGBA rgba, out double r, out double g, out double b) { 72 | adjustColor(percent, rgba, r, g, b); 73 | } 74 | 75 | void darken(double percent, RGBA rgba, out double r, out double g, out double b) { 76 | adjustColor(-percent, rgba, r, g, b); 77 | } 78 | 79 | void adjustColor(double cf, RGBA rgba, out double r, out double g, out double b) { 80 | if (cf < 0) { 81 | cf = 1 + cf; 82 | r = rgba.red * cf; 83 | g = rgba.green * cf; 84 | b = rgba.blue * cf; 85 | } else { 86 | r = (1 - rgba.red) * cf + rgba.red; 87 | g = (1 - rgba.green) * cf + rgba.green; 88 | b = (1 - rgba.blue) * cf + rgba.blue; 89 | } 90 | } 91 | 92 | void desaturate(double percent, RGBA rgba, out double r, out double g, out double b) { 93 | tracef("desaturate: %f, %f, %f, %f", percent, rgba.red, rgba.green, rgba.blue); 94 | double L = 0.3 * rgba.red + 0.6 * rgba.green + 0.1 * rgba.blue; 95 | r = rgba.red + percent * (L - rgba.red); 96 | g = rgba.green + percent * (L - rgba.green); 97 | b = rgba.blue + percent * (L - rgba.blue); 98 | tracef("Desaturated color: %f, %f, %f", r, g, b); 99 | } -------------------------------------------------------------------------------- /source/gx/gtk/dialog.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.gtk.dialog; 6 | 7 | import gio.Settings: GSettings = Settings; 8 | 9 | import gtk.CheckButton; 10 | import gtk.Entry; 11 | import gtk.MessageDialog; 12 | import gtk.Window; 13 | 14 | import gx.i18n.l10n; 15 | 16 | /** 17 | * Displays an error message in a dialog 18 | */ 19 | void showErrorDialog(Window parent, string message, string title = null) { 20 | showMessageDialog(MessageType.ERROR, parent, message, title); 21 | } 22 | 23 | /** 24 | * Displays a message dialog of the specified type 25 | */ 26 | void showMessageDialog(MessageType mt, Window parent, string message, string title = null) { 27 | MessageDialog dialog = new MessageDialog(parent, DialogFlags.MODAL + DialogFlags.USE_HEADER_BAR, mt, ButtonsType.OK, message, null); 28 | scope (exit) { 29 | dialog.destroy(); 30 | } 31 | dialog.setTransientFor(parent); 32 | if (title.length > 0) 33 | dialog.setTitle(title); 34 | dialog.run(); 35 | } 36 | 37 | alias OnValidate = bool delegate(string value); 38 | 39 | /** 40 | * Show an input dialog with a single entry for input 41 | */ 42 | bool showInputDialog(Window parent, out string value, string initialValue = "", string title = "", string message = "", OnValidate validate = null) { 43 | MessageDialog dialog = new MessageDialog(parent, DialogFlags.MODAL + DialogFlags.USE_HEADER_BAR, MessageType.QUESTION, ButtonsType.OK_CANCEL, message, null); 44 | scope (exit) { 45 | dialog.destroy(); 46 | } 47 | dialog.setTransientFor(parent); 48 | dialog.setTitle(title); 49 | Entry entry; 50 | if (initialValue.length > 0) { 51 | entry = new Entry(initialValue); 52 | } else { 53 | entry = new Entry(); 54 | } 55 | entry.addOnActivate(delegate(Entry) { 56 | dialog.response(ResponseType.OK); 57 | }); 58 | if (validate !is null) { 59 | entry.addOnChanged(delegate(EditableIF) { 60 | if (validate(entry.getText)) { 61 | entry.getStyleContext().removeClass("error"); 62 | dialog.setResponseSensitive(ResponseType.OK, true); 63 | } else { 64 | entry.getStyleContext().addClass("error"); 65 | dialog.setResponseSensitive(ResponseType.OK, false); 66 | } 67 | }); 68 | } 69 | dialog.getMessageArea().add(entry); 70 | entry.showAll(); 71 | dialog.setDefaultResponse(ResponseType.OK); 72 | if (dialog.run() == ResponseType.OK) { 73 | value = entry.getText(); 74 | return true; 75 | } else { 76 | return false; 77 | } 78 | } 79 | 80 | /** 81 | * Shows a confirmation dialog with the optional ability to include an ignore checkbox 82 | * tied to gio.Settings so the user no longer has to see the dialog. 83 | */ 84 | bool showConfirmDialog(Window parent, string message, GSettings settings = null, string promptKey = "") { 85 | if (settings !is null && !settings.getBoolean(promptKey)) return true; 86 | 87 | MessageDialog dialog = new MessageDialog(parent, DialogFlags.MODAL + DialogFlags.USE_HEADER_BAR, MessageType.QUESTION, ButtonsType.OK_CANCEL, 88 | message, null); 89 | CheckButton cbPrompt = new CheckButton(_("Do not show this again")); 90 | cbPrompt.setMarginLeft(12); 91 | dialog.getContentArea().add(cbPrompt); 92 | dialog.setDefaultResponse(ResponseType.CANCEL); 93 | scope (exit) { 94 | dialog.destroy(); 95 | } 96 | dialog.showAll(); 97 | bool result = true; 98 | if (dialog.run() != ResponseType.OK) { 99 | result = false; 100 | } 101 | settings.setBoolean(promptKey, !cbPrompt.getActive()); 102 | return result; 103 | } -------------------------------------------------------------------------------- /source/gx/gtk/resource.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.gtk.resource; 6 | 7 | import std.array; 8 | import std.conv; 9 | import std.experimental.logger; 10 | import std.file; 11 | import std.path; 12 | 13 | import gdk.Screen; 14 | 15 | import glib.Bytes; 16 | import glib.GException; 17 | import glib.Util; 18 | 19 | import gio.Resource; 20 | 21 | import gtk.CssProvider; 22 | import gtk.StyleContext; 23 | 24 | import gtkc.giotypes; 25 | 26 | /** 27 | * Defined here since not defined in GtkD 28 | */ 29 | enum ProviderPriority : uint { 30 | FALLBACK = 1, 31 | THEME = 200, 32 | SETTINGS = 400, 33 | APPLICATION = 600, 34 | USER = 800 35 | } 36 | 37 | /** 38 | * Find and optionally register a resource 39 | */ 40 | Resource findResource(string resourcePath, bool register = true) { 41 | foreach (path; Util.getSystemDataDirs()) { 42 | auto fullpath = buildPath(path, resourcePath); 43 | trace("looking for resource " ~ fullpath); 44 | if (exists(fullpath)) { 45 | Resource resource = Resource.load(fullpath); 46 | if (register && resource) { 47 | trace("Resource found and registered " ~ fullpath); 48 | Resource.register(resource); 49 | } 50 | return resource; 51 | } 52 | } 53 | errorf("Resource %s could not be found", resourcePath); 54 | return null; 55 | } 56 | 57 | CssProvider createCssProvider(string filename, string[string] variables = null) { 58 | try { 59 | CssProvider provider = new CssProvider(); 60 | string css = getResource(filename, variables); 61 | if (css.length > 0) { 62 | if (provider.loadFromData(css)) { 63 | return provider; 64 | } 65 | } 66 | } catch (GException ge) { 67 | trace("Unexpected error loading css provider " ~ filename); 68 | trace("Error: " ~ ge.msg); 69 | } 70 | return null; 71 | } 72 | 73 | /** 74 | * Adds a CSSProvider to the default screen, if no provider is found it 75 | * returns null 76 | */ 77 | CssProvider addCssProvider(string filename, ProviderPriority priority, string[string] variables = null) { 78 | try { 79 | CssProvider provider = createCssProvider(filename, variables); 80 | if (provider !is null) { 81 | Screen screen = Screen.getDefault(); 82 | if (screen !is null) { 83 | StyleContext.addProviderForScreen(Screen.getDefault(), provider, priority); 84 | return provider; 85 | } else { 86 | warning("Default screen is null, no CSS provider added and as a result Tilix UI may appear incorrect"); 87 | return null; 88 | } 89 | } 90 | } catch (GException ge) { 91 | trace("Unexpected error loading css provider " ~ filename); 92 | trace("Error: " ~ ge.msg); 93 | } 94 | return null; 95 | } 96 | 97 | /** 98 | * Loads a textual resource and performs string subsitution based on key-value pairs 99 | */ 100 | string getResource(string filename, string[string] variables = null) { 101 | Bytes bytes; 102 | try { 103 | bytes = Resource.resourcesLookupData(filename, GResourceLookupFlags.NONE); 104 | } catch (GException ge) { 105 | return null; 106 | } 107 | if (bytes is null || bytes.getSize() == 0) return null; 108 | else { 109 | string contents = to!string(cast(char*)bytes.getData()); 110 | if (variables !is null) { 111 | foreach(variable; variables.byKeyValue()) { 112 | contents = contents.replace(variable.key, variable.value); 113 | } 114 | } 115 | return contents; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /source/gx/gtk/settings.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.gtk.settings; 6 | 7 | import std.experimental.logger; 8 | 9 | import gtkc.giotypes; 10 | 11 | import gobject.ObjectG; 12 | import gio.Settings: GSettings = Settings; 13 | 14 | /** 15 | * Bookkeeping class that keps track of objects which are 16 | * binded to a GSettings object so they can be unbinded later. it 17 | * also supports the concept of deferred bindings where a binding 18 | * can be added but is not actually attached to a Settings object 19 | * until one is set. 20 | */ 21 | class BindingHelper { 22 | 23 | private: 24 | Binding[] bindings; 25 | GSettings _settings; 26 | 27 | void bindAll() { 28 | if (_settings !is null) { 29 | foreach(binding; bindings) { 30 | _settings.bind(binding.key, binding.object, binding.property, binding.flags); 31 | } 32 | } 33 | } 34 | 35 | /** 36 | * Adds a binding to the list 37 | */ 38 | void addBind(string key, ObjectG object, string property, GSettingsBindFlags flags) { 39 | bindings ~= Binding(key, object, property, flags); 40 | } 41 | 42 | public: 43 | 44 | this() { 45 | } 46 | 47 | this(GSettings settings) { 48 | this(); 49 | _settings = settings; 50 | } 51 | 52 | /** 53 | * The current Settings object being used. 54 | */ 55 | @property GSettings settings() { 56 | return _settings; 57 | } 58 | 59 | /** 60 | * Setting a new GSettings object will cause this class to unbind 61 | * previously set bindings and re-bind to the new settings automatically. 62 | */ 63 | @property void settings(GSettings value) { 64 | if (value != _settings) { 65 | if (_settings !is null && bindings.length > 0) unbind(); 66 | _settings = value; 67 | if (_settings !is null) bindAll(); 68 | } 69 | } 70 | 71 | /** 72 | * Add a binding to list and binds to Settings if it is set. 73 | */ 74 | void bind(string key, ObjectG object, string property, GSettingsBindFlags flags) { 75 | addBind(key, object, property, flags); 76 | if (settings !is null) { 77 | _settings.bind(key, object, property, flags); 78 | } 79 | } 80 | 81 | /** 82 | * Unbinds all added binds from settings object 83 | */ 84 | void unbind() { 85 | foreach(binding; bindings) { 86 | _settings.unbind(binding.object, binding.property); 87 | } 88 | } 89 | 90 | /** 91 | * Unbinds all bindings and clears list of bindings. 92 | */ 93 | void clear() { 94 | unbind(); 95 | bindings.length = 0; 96 | } 97 | } 98 | 99 | private: 100 | 101 | struct Binding { 102 | string key; 103 | ObjectG object; 104 | string property; 105 | GSettingsBindFlags flags; 106 | } 107 | -------------------------------------------------------------------------------- /source/gx/gtk/x11.d: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2005-2007 Benedikt Meurer 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms of the GNU General Public License as published by the Free 6 | * Software Foundation; either version 2 of the License, or (at your option) 7 | * any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 | * more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | */ 17 | 18 | module gx.gtk.x11; 19 | 20 | import std.experimental.logger; 21 | import std.string; 22 | 23 | import gtkc.glibtypes; 24 | 25 | import gtkc.Loader; 26 | import gtkc.paths; 27 | 28 | import gdk.Atom; 29 | import gdk.Gdk; 30 | import gdk.X11; 31 | 32 | import gtk.Main; 33 | import gtk.Window; 34 | 35 | import x11.X: Atom, ClientMessage, StructureNotifyMask, XWindow=Window; 36 | import x11.Xlib: Display, XClientMessageEvent, XSendEvent, XEvent; 37 | 38 | /** 39 | * This function activates an X11 using the _NET_ACTIVE_WINDOW 40 | * event for X11. Works around some edge cases with respect to 41 | * window focus. 42 | * 43 | * Code was translated from a C version in xfce4_terminal, see original here: 44 | * http://bazaar.launchpad.net/~vcs-imports/xfce4-terminal/trunk/view/head:/terminal/terminal-util.c 45 | * 46 | * The original xfce code was licensed under GPL and that license remains in effect for this method only, 47 | * since code translations are considered a derived work under GPL. 48 | */ 49 | void activateX11Window(Window window) { 50 | uint timestamp = Main.getCurrentEventTime(); 51 | 52 | if (timestamp == 0) 53 | timestamp = gdk_x11_get_server_time(window.getWindow().getWindowStruct()); 54 | 55 | XClientMessageEvent event; 56 | event.type = ClientMessage; 57 | event.window = getXid(window.getWindow()); 58 | const(char*) name = toStringz("_NET_ACTIVE_WINDOW"); 59 | event.message_type = gdk_x11_get_xatom_by_name(name); 60 | event.format = 32; 61 | event.data.l[0] = 1; 62 | event.data.l[1] = timestamp; 63 | event.data.l[2] = event.data.l[3] = event.data.l[4] = 0; 64 | 65 | Display* display = gdk_x11_get_default_xdisplay(); 66 | XWindow root = gdk_x11_get_default_root_xwindow(); 67 | 68 | Gdk.errorTrapPush(); 69 | XSendEvent(display, root, false, StructureNotifyMask, cast(XEvent*) &event); 70 | Gdk.flush; 71 | if (Gdk.errorTrapPop() != 0) { 72 | error("Failed to focus window"); 73 | } 74 | } 75 | 76 | private: 77 | 78 | import gdk.c.functions; 79 | 80 | shared static this() 81 | { 82 | // Link in some extra functions not provided by GtkD 83 | Linker.link(gdk_x11_get_xatom_by_name, "gdk_x11_get_xatom_by_name", LIBRARY_GDK); 84 | Linker.link(gdk_x11_get_default_xdisplay, "gdk_x11_get_default_xdisplay", LIBRARY_GDK); 85 | Linker.link(gdk_x11_get_default_root_xwindow, "gdk_x11_get_default_root_xwindow", LIBRARY_GDK); 86 | Linker.link(gdk_x11_get_server_time, "gdk_x11_get_server_time", LIBRARY_GDK); 87 | } 88 | 89 | __gshared extern(C) 90 | { 91 | Atom function(const(char)* atom_name) c_gdk_x11_get_xatom_by_name; 92 | Display* function() c_gdk_x11_get_default_xdisplay; 93 | XWindow function() c_gdk_x11_get_default_root_xwindow; 94 | uint function(GdkWindow* window) c_gdk_x11_get_server_time; 95 | } 96 | 97 | alias c_gdk_x11_get_xatom_by_name gdk_x11_get_xatom_by_name; 98 | alias c_gdk_x11_get_default_xdisplay gdk_x11_get_default_xdisplay; 99 | alias c_gdk_x11_get_default_root_xwindow gdk_x11_get_default_root_xwindow; 100 | alias c_gdk_x11_get_server_time gdk_x11_get_server_time; 101 | -------------------------------------------------------------------------------- /source/gx/i18n/l10n.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.i18n.l10n; 6 | 7 | import glib.Internationalization; 8 | 9 | void textdomain(string domain) { 10 | _textdomain = domain; 11 | } 12 | 13 | /** 14 | * Localize text using GLib integration with GNU gettext 15 | * and po files for translation 16 | */ 17 | string _(string text) { 18 | return Internationalization.dgettext(_textdomain, text); 19 | } 20 | 21 | /** 22 | * Uses gettext to get the translation for text in the given context. 23 | * This is mainly useful for short strings which may need different 24 | * translations, depending on the context in which they are used. 25 | */ 26 | string C_(string context, string text) { 27 | return Internationalization.dpgettext2(_textdomain, context, text); 28 | } 29 | 30 | /** 31 | * Only marks a string for translation. This is useful in situations where the 32 | * translated strings can't be directly used, e.g. in string array initializers. 33 | * To get the translated string, call _() at runtime. 34 | */ 35 | string N_(string text) { 36 | return text; 37 | } 38 | 39 | private: 40 | string _textdomain; 41 | -------------------------------------------------------------------------------- /source/gx/tilix/bookmark/bmchooser.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.bookmark.bmchooser; 6 | 7 | import gdk.Event; 8 | import gdk.Keysyms; 9 | 10 | import gio.Settings: GSettings = Settings; 11 | 12 | import gtk.Box; 13 | import gtk.CheckButton; 14 | import gtk.Dialog; 15 | import gtk.ScrolledWindow; 16 | import gtk.SearchEntry; 17 | import gtk.Widget; 18 | import gtk.Window; 19 | 20 | import gx.gtk.util; 21 | 22 | import gx.i18n.l10n; 23 | 24 | import gx.tilix.bookmark.bmtreeview; 25 | import gx.tilix.bookmark.manager; 26 | import gx.tilix.preferences; 27 | 28 | /** 29 | * Selection mode dialog should used 30 | */ 31 | enum BMSelectionMode {ANY, LEAF, FOLDER} 32 | 33 | /** 34 | * Dialog that allows the user to select a bookmark. Not actually used 35 | * at the moment as the GTK TreeModelFilter is too limited when dealing with 36 | * heirarchal data. 37 | */ 38 | class BookmarkChooser: Dialog { 39 | private: 40 | BMTreeView tv; 41 | BMSelectionMode mode; 42 | 43 | GSettings gsSettings; 44 | 45 | void createUI() { 46 | tv = new BMTreeView(true, mode == BMSelectionMode.FOLDER); 47 | tv.setActivateOnSingleClick(false); 48 | tv.setHeadersVisible(false); 49 | tv.getSelection().setMode(SelectionMode.BROWSE); 50 | tv.addOnCursorChanged(delegate(TreeView) { 51 | updateUI(); 52 | }); 53 | tv.addOnRowActivated(delegate(TreePath, TreeViewColumn, TreeView) { 54 | response(ResponseType.OK); 55 | }); 56 | tv.addOnKeyPress(&checkKeyPress); 57 | 58 | ScrolledWindow sw = new ScrolledWindow(tv); 59 | sw.setShadowType(ShadowType.ETCHED_IN); 60 | sw.setPolicy(PolicyType.NEVER, PolicyType.AUTOMATIC); 61 | sw.setHexpand(true); 62 | sw.setVexpand(true); 63 | sw.setSizeRequest(-1, 200); 64 | 65 | SearchEntry se = new SearchEntry(); 66 | se.addOnSearchChanged(delegate(SearchEntry) { 67 | tv.filterText = se.getText(); 68 | updateUI(); 69 | }); 70 | se.addOnKeyPress(&checkKeyPress); 71 | 72 | Box box = new Box(Orientation.VERTICAL, 6); 73 | setAllMargins(box, 18); 74 | box.add(se); 75 | box.add(sw); 76 | 77 | if (mode != BMSelectionMode.FOLDER) { 78 | gsSettings = new GSettings(SETTINGS_ID); 79 | CheckButton cbIncludeEnter = new CheckButton(_("Include return character with bookmark")); 80 | gsSettings.bind(SETTINGS_BOOKMARK_INCLUDE_RETURN_KEY, cbIncludeEnter, "active", GSettingsBindFlags.DEFAULT); 81 | box.add(cbIncludeEnter); 82 | } 83 | 84 | getContentArea().add(box); 85 | } 86 | 87 | void updateUI() { 88 | setResponseSensitive(ResponseType.OK, isSelectEnabled()); 89 | } 90 | 91 | bool isSelectEnabled() { 92 | Bookmark bm = tv.getSelectedBookmark(); 93 | bool enabled = bm !is null; 94 | switch (mode) { 95 | case BMSelectionMode.FOLDER: 96 | enabled = enabled && (cast(FolderBookmark)bm !is null); 97 | break; 98 | case BMSelectionMode.LEAF: 99 | enabled = enabled && (cast(FolderBookmark)bm is null); 100 | break; 101 | default: 102 | break; 103 | } 104 | return enabled; 105 | } 106 | 107 | bool checkKeyPress(Event event, Widget w) { 108 | uint keyval; 109 | if (event.getKeyval(keyval)) { 110 | if (keyval == GdkKeysyms.GDK_Escape) { 111 | response = ResponseType.CANCEL; 112 | return true; 113 | } 114 | if (keyval == GdkKeysyms.GDK_Return) { 115 | if (isSelectEnabled()) { 116 | response = ResponseType.OK; 117 | return true; 118 | } 119 | } 120 | } 121 | return false; 122 | } 123 | 124 | public: 125 | this(Window parent, BMSelectionMode mode) { 126 | string title = mode == BMSelectionMode.FOLDER? _("Select Folder"):_("Select Bookmark"); 127 | super(title, parent, GtkDialogFlags.MODAL + GtkDialogFlags.USE_HEADER_BAR, [_("OK"), _("Cancel")], [GtkResponseType.OK, GtkResponseType.CANCEL]); 128 | setDefaultResponse(GtkResponseType.OK); 129 | this.mode = mode; 130 | createUI(); 131 | updateUI(); 132 | } 133 | 134 | @property Bookmark bookmark() { 135 | return tv.getSelectedBookmark(); 136 | } 137 | } 138 | 139 | -------------------------------------------------------------------------------- /source/gx/tilix/encoding.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.encoding; 6 | 7 | import gx.i18n.l10n; 8 | 9 | /** 10 | * Hashmap of encodings 11 | */ 12 | string[string] lookupEncoding; 13 | 14 | /** 15 | * Array of available encodings 16 | */ 17 | string[2][] encodings = [ 18 | ["ISO-8859-1", N_("Western")], 19 | ["ISO-8859-2", N_("Central European")], 20 | ["ISO-8859-3", N_("South European")], 21 | ["ISO-8859-4", N_("Baltic")], 22 | ["ISO-8859-5", N_("Cyrillic")], 23 | ["ISO-8859-6", N_("Arabic")], 24 | ["ISO-8859-7", N_("Greek")], 25 | ["ISO-8859-8", N_("Hebrew Visual")], 26 | ["ISO-8859-8-I", N_("Hebrew")], 27 | ["ISO-8859-9", N_("Turkish")], 28 | ["ISO-8859-10", N_("Nordic")], 29 | ["ISO-8859-13", N_("Baltic")], 30 | ["ISO-8859-14", N_("Celtic")], 31 | ["ISO-8859-15", N_("Western")], 32 | ["ISO-8859-16", N_("Romanian")], 33 | ["UTF-8", N_("Unicode")], 34 | ["ARMSCII-8", N_("Armenian")], 35 | ["BIG5", N_("Chinese Traditional")], 36 | ["BIG5-HKSCS", N_("Chinese Traditional")], 37 | ["CP866", N_("Cyrillic/Russian")], 38 | ["EUC-JP", N_("Japanese")], 39 | ["EUC-KR", N_("Korean")], 40 | ["EUC-TW", N_("Chinese Traditional")], 41 | ["GB18030", N_("Chinese Simplified")], 42 | ["GB2312", N_("Chinese Simplified")], 43 | ["GBK", N_("Chinese Simplified")], 44 | ["GEORGIAN-PS", N_("Georgian")], 45 | ["IBM850", N_("Western")], 46 | ["IBM852", N_("Central European")], 47 | ["IBM855", N_("Cyrillic")], 48 | ["IBM857", N_("Turkish")], 49 | ["IBM862", N_("Hebrew")], 50 | ["IBM864", N_("Arabic")], 51 | ["ISO-2022-JP", N_("Japanese")], 52 | ["ISO-2022-KR", N_("Korean")], 53 | ["ISO-IR-111", N_("Cyrillic")], 54 | ["KOI8-R", N_("Cyrillic")], 55 | ["KOI8-U", N_("Cyrillic/Ukrainian")], 56 | ["MAC_ARABIC", N_("Arabic")], 57 | ["MAC_CE", N_("Central European")], 58 | ["MAC_CROATIAN", N_("Croatian")], 59 | ["MAC-CYRILLIC", N_("Cyrillic")], 60 | ["MAC_DEVANAGARI", N_("Hindi")], 61 | ["MAC_FARSI", N_("Persian")], 62 | ["MAC_GREEK", N_("Greek")], 63 | ["MAC_GUJARATI", N_("Gujarati")], 64 | ["MAC_GURMUKHI", N_("Gurmukhi")], 65 | ["MAC_HEBREW", N_("Hebrew")], 66 | ["MAC_ICELANDIC", N_("Icelandic")], 67 | ["MAC_ROMAN", N_("Western")], 68 | ["MAC_ROMANIAN", N_("Romanian")], 69 | ["MAC_TURKISH", N_("Turkish")], 70 | ["MAC_UKRAINIAN", N_("Cyrillic/Ukrainian")], 71 | ["SHIFT_JIS", N_("Japanese")], 72 | ["TCVN", N_("Vietnamese")], 73 | ["TIS-620", N_("Thai")], 74 | ["UHC", N_("Korean")], 75 | ["VISCII", N_("Vietnamese")], 76 | ["WINDOWS-1250", N_("Central European")], 77 | ["WINDOWS-1251", N_("Cyrillic")], 78 | ["WINDOWS-1252", N_("Western")], 79 | ["WINDOWS-1253", N_("Greek")], 80 | ["WINDOWS-1254", N_("Turkish")], 81 | ["WINDOWS-1255", N_("Hebrew")], 82 | ["WINDOWS-1256", N_("Arabic")], 83 | ["WINDOWS-1257", N_("Baltic")], 84 | ["WINDOWS-1258", N_("Vietnamese")] 85 | ]; 86 | 87 | static this() { 88 | foreach(encoding; encodings) { 89 | lookupEncoding[encoding[0]] = encoding[1]; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /source/gx/tilix/prefeditor/bookmarkeditor.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.prefeditor.bookmarkeditor; 6 | 7 | import std.experimental.logger; 8 | 9 | import gtk.Box; 10 | import gtk.Button; 11 | import gtk.ScrolledWindow; 12 | import gtk.TreeIter; 13 | import gtk.TreePath; 14 | import gtk.Window; 15 | 16 | import gx.i18n.l10n; 17 | 18 | import gx.gtk.util; 19 | 20 | import gx.tilix.bookmark.bmeditor; 21 | import gx.tilix.bookmark.bmtreeview; 22 | import gx.tilix.bookmark.manager; 23 | 24 | /** 25 | * Editor for globally managing bookmarks as part of the preferences dialog. Should not 26 | * be used outside this context. 27 | */ 28 | class GlobalBookmarkEditor: Box { 29 | 30 | private: 31 | BMTreeView tv; 32 | ScrolledWindow sw; 33 | 34 | Button btnEdit; 35 | Button btnDelete; 36 | Button btnUnselect; 37 | 38 | void createUI() { 39 | tv = new BMTreeView(false, false, true); 40 | tv.setActivateOnSingleClick(false); 41 | tv.setHeadersVisible(false); 42 | tv.getSelection().setMode(SelectionMode.SINGLE); 43 | tv.addOnCursorChanged(delegate(TreeView) { 44 | updateUI(); 45 | }); 46 | tv.addOnRowActivated(delegate(TreePath, TreeViewColumn, TreeView) { 47 | editBookmark(btnEdit); 48 | }); 49 | 50 | ScrolledWindow sw = new ScrolledWindow(tv); 51 | sw.setShadowType(ShadowType.ETCHED_IN); 52 | sw.setPolicy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); 53 | sw.setHexpand(true); 54 | sw.setVexpand(true); 55 | 56 | add(sw); 57 | 58 | Box bButtons = new Box(Orientation.HORIZONTAL, 0); 59 | bButtons.getStyleContext().addClass("linked"); 60 | 61 | Button btnAdd = new Button("list-add-symbolic", IconSize.BUTTON); 62 | btnAdd.setTooltipText(_("Add bookmark")); 63 | btnAdd.addOnClicked(&addBookmark); 64 | bButtons.add(btnAdd); 65 | 66 | btnEdit = new Button("input-tablet-symbolic", IconSize.BUTTON); 67 | btnEdit.setTooltipText(_("Edit bookmark")); 68 | btnEdit.addOnClicked(&editBookmark); 69 | bButtons.add(btnEdit); 70 | 71 | btnDelete = new Button("list-remove-symbolic", IconSize.BUTTON); 72 | btnDelete.setTooltipText(_("Delete bookmark")); 73 | btnDelete.addOnClicked(&deleteBookmark); 74 | bButtons.add(btnDelete); 75 | 76 | btnUnselect = new Button("edit-clear-symbolic", IconSize.BUTTON); 77 | btnUnselect.setTooltipText(_("Unselect bookmark")); 78 | btnUnselect.addOnClicked(&unselectBookmark); 79 | bButtons.add(btnUnselect); 80 | 81 | add(bButtons); 82 | 83 | updateUI(); 84 | } 85 | 86 | void updateUI() { 87 | TreeIter selected = tv.getSelectedIter(); 88 | btnEdit.setSensitive(selected !is null); 89 | btnDelete.setSensitive(selected !is null); 90 | btnUnselect.setSensitive(selected !is null); 91 | } 92 | 93 | void addBookmark(Button button) { 94 | BookmarkEditor be = new BookmarkEditor(cast(Window)getToplevel(), BookmarkEditorMode.ADD, null); 95 | scope(exit) { 96 | be.destroy(); 97 | } 98 | be.showAll(); 99 | if (be.run() == ResponseType.OK) { 100 | Bookmark bm = be.create(); 101 | tv.addBookmark(bm); 102 | } 103 | } 104 | 105 | void editBookmark(Button button) { 106 | Bookmark bm = tv.getSelectedBookmark(); 107 | if (bm is null) return; 108 | BookmarkEditor be = new BookmarkEditor(cast(Window)getToplevel(), BookmarkEditorMode.EDIT, bm); 109 | scope(exit) { 110 | be.destroy(); 111 | } 112 | be.showAll(); 113 | if (be.run() == ResponseType.OK) { 114 | be.update(bm); 115 | tv.updateBookmark(bm); 116 | } 117 | } 118 | 119 | void deleteBookmark(Button button) { 120 | tv.removeBookmark(); 121 | } 122 | 123 | void unselectBookmark(Button button) { 124 | tv.getSelection().unselectIter(tv.getSelectedIter()); 125 | } 126 | 127 | public: 128 | this() { 129 | super(Orientation.VERTICAL, 6); 130 | setAllMargins(this, 18); 131 | setMarginBottom(6); 132 | createUI(); 133 | } 134 | } -------------------------------------------------------------------------------- /source/gx/tilix/prefeditor/common.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.prefeditor.common; 6 | 7 | import std.format; 8 | import std.experimental.logger; 9 | 10 | import gio.Settings: GSettings = Settings; 11 | 12 | import gtk.Box; 13 | import gtk.Button; 14 | import gtk.Grid; 15 | import gtk.Label; 16 | import gtk.Window; 17 | import gtk.Version; 18 | 19 | import gx.gtk.vte; 20 | import gx.i18n.l10n; 21 | 22 | import gx.tilix.preferences; 23 | import gx.tilix.prefeditor.advdialog; 24 | 25 | 26 | /** 27 | * Creates the advanced UI (custom links, triggers) that is shared between 28 | * the preference and profile editor. 29 | * 30 | * Note need to use a delegate to get settings because in profile advdialog 31 | * the same UI is re-used but the profile settings object is switched. If we 32 | * don't use a delegate the references to the event handlers become pinned to 33 | * one object instance. 34 | */ 35 | void createAdvancedUI(Grid grid, ref uint row, GSettings delegate() scb, bool showTriggerLineSettings = false) { 36 | // Custom Links Section 37 | Label lblCustomLinks = new Label(format("%s", _("Custom Links"))); 38 | lblCustomLinks.setUseMarkup(true); 39 | lblCustomLinks.setHalign(Align.START); 40 | grid.attach(lblCustomLinks, 0, row, 3, 1); 41 | row++; 42 | 43 | string customLinksDescription = _("A list of user defined links that can be clicked on in the terminal based on regular expression definitions."); 44 | grid.attach(createDescriptionLabel(customLinksDescription), 0, row, 2, 1); 45 | 46 | Button btnEditLink = new Button(_("Edit")); 47 | btnEditLink.setHalign(Align.FILL); 48 | btnEditLink.setValign(Align.CENTER); 49 | 50 | btnEditLink.addOnClicked(delegate(Button) { 51 | GSettings gs = scb(); 52 | string[] links = gs.getStrv(SETTINGS_ALL_CUSTOM_HYPERLINK_KEY); 53 | EditCustomLinksDialog dlg = new EditCustomLinksDialog(cast(Window) grid.getToplevel(), links); 54 | scope (exit) { 55 | dlg.destroy(); 56 | } 57 | dlg.showAll(); 58 | if (dlg.run() == ResponseType.APPLY) { 59 | gs.setStrv(SETTINGS_ALL_CUSTOM_HYPERLINK_KEY, dlg.getLinks()); 60 | } 61 | }); 62 | grid.attach(btnEditLink, 2, row, 1, 1); 63 | row++; 64 | 65 | if (checkVTEFeature(TerminalFeature.EVENT_SCREEN_CHANGED)) { 66 | // Triggers Section 67 | Label lblTriggers = new Label(format("%s", _("Triggers"))); 68 | lblTriggers.setUseMarkup(true); 69 | lblTriggers.setHalign(Align.START); 70 | lblTriggers.setMarginTop(12); 71 | grid.attach(lblTriggers, 0, row, 3, 1); 72 | row++; 73 | 74 | string triggersDescription = _("Triggers are regular expressions that are used to check against output text in the terminal. When a match is detected the configured action is executed."); 75 | grid.attach(createDescriptionLabel(triggersDescription), 0, row, 2, 1); 76 | 77 | Button btnEditTriggers = new Button(_("Edit")); 78 | btnEditTriggers.setHalign(Align.FILL); 79 | btnEditTriggers.setValign(Align.CENTER); 80 | 81 | btnEditTriggers.addOnClicked(delegate(Button) { 82 | GSettings gs = scb(); 83 | EditTriggersDialog dlg = new EditTriggersDialog(cast(Window) grid.getToplevel(), gs, showTriggerLineSettings); 84 | scope (exit) { 85 | dlg.destroy(); 86 | } 87 | dlg.showAll(); 88 | if (dlg.run() == ResponseType.APPLY) { 89 | gs.setStrv(SETTINGS_ALL_TRIGGERS_KEY, dlg.getTriggers()); 90 | } 91 | }); 92 | grid.attach(btnEditTriggers, 2, row, 1, 1); 93 | row++; 94 | } 95 | } 96 | 97 | /** 98 | * Create a description label that handles long lines 99 | */ 100 | Label createDescriptionLabel(string desc) { 101 | Label lblDescription = new Label(desc); 102 | lblDescription.setUseMarkup(true); 103 | lblDescription.setSensitive(false); 104 | lblDescription.setLineWrap(true); 105 | lblDescription.setHalign(Align.START); 106 | if (Version.checkVersion(3, 16, 0).length == 0) { 107 | lblDescription.setXalign(0.0); 108 | } 109 | lblDescription.setMaxWidthChars(70); 110 | return lblDescription; 111 | } -------------------------------------------------------------------------------- /source/gx/tilix/prefeditor/titleeditor.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.prefeditor.titleeditor; 6 | 7 | import std.conv; 8 | import std.experimental.logger; 9 | import std.format; 10 | import std.signals; 11 | 12 | import gio.SimpleAction; 13 | import gio.SimpleActionGroup; 14 | import gio.Menu: GMenu = Menu; 15 | import gio.MenuItem : GMenuItem = MenuItem; 16 | 17 | import glib.Variant: GVariant = Variant; 18 | import glib.VariantType: GVariantType = VariantType; 19 | 20 | import gtk.Box; 21 | import gtk.Entry; 22 | import gtk.Image; 23 | import gtk.Main; 24 | import gtk.MenuButton; 25 | import gtk.MountOperation; 26 | import gtk.PopoverMenu; 27 | 28 | import gx.gtk.actions; 29 | 30 | import gx.i18n.l10n; 31 | 32 | import gx.tilix.common; 33 | import gx.tilix.constants; 34 | 35 | /** 36 | * Scope of the title to be edited 37 | */ 38 | enum TitleEditScope {WINDOW, SESSION, TERMINAL} 39 | 40 | /** 41 | * Wraps an entry into a box that includes other 42 | * helper widgets to edit the title. 43 | */ 44 | TitleEditBox createTitleEditHelper(Entry entry, TitleEditScope tes) { 45 | return new TitleEditBox(entry, tes); 46 | } 47 | 48 | 49 | /** 50 | * Wraps an entry with helpers for editing various titles 51 | * like terminal title, window title, etc where variables can be used. 52 | * 53 | * Note that this editor is not supported in GTK 3.14 so version check it 54 | * before using it. 55 | */ 56 | class TitleEditBox: Box { 57 | private: 58 | Entry entry; 59 | SimpleActionGroup sagVariables; 60 | 61 | enum ACTION_PREFIX = "variables"; 62 | 63 | void createUI(TitleEditScope tes) { 64 | sagVariables = new SimpleActionGroup(); 65 | this.insertActionGroup(ACTION_PREFIX, sagVariables); 66 | 67 | add(entry); 68 | 69 | MenuButton mbVariables = new MenuButton(); 70 | mbVariables.add(new Image("pan-down-symbolic", IconSize.MENU)); 71 | mbVariables.setFocusOnClick(false); 72 | mbVariables.setPopover(createPopover(tes)); 73 | add(mbVariables); 74 | } 75 | 76 | /** 77 | * Create menu items from array for each section (window, session, terminal) 78 | */ 79 | GMenu createItems(immutable(string[]) localized, immutable(string[]) values, string actionPrefix) { 80 | GMenu section = new GMenu(); 81 | foreach(index, variable; localized) { 82 | string actionName = format("%s-%02d", actionPrefix, index); 83 | SimpleAction action = new SimpleAction(actionName, null); 84 | action.addOnActivate(delegate(GVariant, SimpleAction sa) { 85 | string name = sa.getName(); 86 | int i = to!int("" ~ name[$-2 .. $]); 87 | int position = entry.getPosition(); 88 | string value = values[i]; 89 | entry.insertText(value, to!int(value.length), position); 90 | }); 91 | sagVariables.insert(action); 92 | section.append(_(variable), getActionDetailedName(ACTION_PREFIX, actionName)); 93 | } 94 | return section; 95 | } 96 | 97 | /** 98 | * Create all menu items in popover to help editing menu items 99 | */ 100 | PopoverMenu createPopover(TitleEditScope tes) { 101 | GMenu model = new GMenu(); 102 | 103 | // Terminal items 104 | GMenu terminalSection = createItems(VARIABLE_TERMINAL_LOCALIZED, VARIABLE_TERMINAL_VALUES, "terminal"); 105 | model.appendSection(_("Terminal"), terminalSection); 106 | 107 | //Session menu items 108 | if (tes == TitleEditScope.SESSION || tes == TitleEditScope.WINDOW) { 109 | GMenu sessionSection = createItems(VARIABLE_SESSION_LOCALIZED, VARIABLE_SESSION_VALUES, "session"); 110 | model.appendSection(_("Session"), sessionSection); 111 | } 112 | 113 | //App menu items 114 | if (tes == TitleEditScope.WINDOW) { 115 | GMenu windowSection = createItems(VARIABLE_WINDOW_LOCALIZED, VARIABLE_WINDOW_VALUES, "window"); 116 | model.appendSection(_("Window"), windowSection); 117 | } 118 | 119 | // Help Menu Item 120 | GMenu helpSection = new GMenu(); 121 | SimpleAction saHelp = new SimpleAction("help", null); 122 | saHelp.addOnActivate(delegate(GVariant, SimpleAction) { 123 | MountOperation.showUri(null, "https://gnunn1.github.io/tilix-web/manual/title/", Main.getCurrentEventTime()); 124 | }); 125 | sagVariables.insert(saHelp); 126 | helpSection.append(_("Help"), getActionDetailedName(ACTION_PREFIX, "help")); 127 | model.appendSection(_("Help"), helpSection); 128 | 129 | PopoverMenu pm = new PopoverMenu(); 130 | pm.addOnMap(delegate(Widget) { 131 | onPopoverShow.emit(); 132 | }); 133 | pm.addOnClosed(delegate(Widget) { 134 | entry.grabFocus(); 135 | onPopoverClosed.emit(); 136 | }, ConnectFlags.AFTER); 137 | 138 | pm.bindModel(model, null); 139 | return pm; 140 | } 141 | 142 | 143 | public: 144 | this(Entry entry, TitleEditScope tes) { 145 | super(Orientation.HORIZONTAL, 0); 146 | this.entry = entry; 147 | getStyleContext().addClass("linked"); 148 | setHexpand(true); 149 | createUI(tes); 150 | addOnDestroy(delegate(Widget) { 151 | sagVariables.destroy(); 152 | sagVariables = null; 153 | }); 154 | } 155 | 156 | GenericEvent!() onPopoverShow; 157 | 158 | GenericEvent!() onPopoverClosed; 159 | 160 | } -------------------------------------------------------------------------------- /source/gx/tilix/shortcuts.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.shortcuts; 6 | 7 | import std.algorithm; 8 | import std.experimental.logger; 9 | import std.path; 10 | 11 | import gio.Settings; 12 | 13 | import gobject.ObjectG; 14 | import gobject.Value; 15 | 16 | import gtkc.gobject; 17 | 18 | import gtk.Builder; 19 | import gtk.ShortcutsGroup; 20 | import gtk.ShortcutsShortcut; 21 | import gtk.ShortcutsWindow; 22 | 23 | import gx.gtk.actions; 24 | import gx.i18n.l10n; 25 | 26 | import gx.tilix.constants; 27 | import gx.tilix.preferences; 28 | 29 | public: 30 | 31 | ShortcutsWindow getShortcutWindow() { 32 | Builder builder = new Builder(); 33 | builder.setTranslationDomain(TILIX_DOMAIN); 34 | if (!builder.addFromResource(SHORTCUT_UI_RESOURCE)) { 35 | error("Could not load shortcuts from " ~ SHORTCUT_UI_RESOURCE); 36 | return null; 37 | } 38 | Settings gsShortcuts = new Settings(SETTINGS_KEY_BINDINGS_ID); 39 | string[] keys = gsShortcuts.listKeys(); 40 | foreach(key; keys) { 41 | ShortcutsShortcut ss = cast(ShortcutsShortcut) builder.getObject(key); 42 | if (ss !is null) { 43 | string accelName = gsShortcuts.getString(key); 44 | if (accelName == SHORTCUT_DISABLED) accelName.length = 0; 45 | ss.setProperty("accelerator", accelName); 46 | } else { 47 | trace("Could not find shortcut for " ~ key); 48 | } 49 | } 50 | 51 | // Add Profile shortcuts to window 52 | ShortcutsGroup sgProfile = cast(ShortcutsGroup) builder.getObject("profile"); 53 | if (sgProfile !is null) { 54 | string[] uuids = prfMgr.getProfileUUIDs(); 55 | foreach (uuid; uuids) { 56 | Settings gsProfile = prfMgr.getProfileSettings(uuid); 57 | if (gsProfile !is null) { 58 | string accelName = gsProfile.getString(SETTINGS_PROFILE_SHORTCUT_KEY); 59 | if (accelName == SHORTCUT_DISABLED) accelName.length = 0; 60 | trace("Create ShortcutShortcut"); 61 | ShortcutsShortcut ss = cast(ShortcutsShortcut) new ObjectG(ShortcutsShortcut.getType(), ["title","accelerator"], [new Value(gsProfile.getString(SETTINGS_PROFILE_VISIBLE_NAME_KEY)), new Value(accelName)]); 62 | if (ss !is null) { 63 | sgProfile.add(ss); 64 | } else { 65 | trace("Profile ShortcutShortcut is null"); 66 | } 67 | } 68 | } 69 | } else { 70 | trace("Didn't find profile ShortcutGroup"); 71 | } 72 | 73 | return cast(ShortcutsWindow) builder.getObject("shortcuts-tilix"); 74 | } -------------------------------------------------------------------------------- /source/gx/tilix/terminal/actions.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.terminal.actions; 6 | 7 | enum ACTION_PREFIX = "terminal"; 8 | enum ACTION_FIND = "find"; 9 | enum ACTION_FIND_PREVIOUS = "find-previous"; 10 | enum ACTION_FIND_NEXT = "find-next"; 11 | enum ACTION_LAYOUT = "layout"; 12 | enum ACTION_CLOSE = "close"; 13 | enum ACTION_MAXIMIZE = "maximize"; 14 | enum ACTION_ENCODING_SELECT = "encoding-select"; 15 | enum ACTION_PROFILE_PREFERENCE = "profile-preference"; 16 | enum ACTION_ENCODING_PREFERENCE = "encoding-preference"; 17 | enum ACTION_READ_ONLY = "read-only"; 18 | enum ACTION_RESET = "reset"; 19 | enum ACTION_RESET_AND_CLEAR = "reset-and-clear"; 20 | enum ACTION_COPY = "copy"; 21 | enum ACTION_COPY_AS_HTML = "copy-as-html"; 22 | enum ACTION_PASTE = "paste"; 23 | enum ACTION_PASTE_PRIMARY = "paste-primary"; 24 | enum ACTION_ADVANCED_PASTE = "advanced-paste"; 25 | enum ACTION_COPY_LINK = "copy-link"; 26 | enum ACTION_OPEN_LINK = "open-link"; 27 | enum ACTION_SELECT_ALL = "select-all"; 28 | enum ACTION_UNSELECT_ALL = "unselect-all"; 29 | enum ACTION_ZOOM_IN = "zoom-in"; 30 | enum ACTION_ZOOM_OUT = "zoom-out"; 31 | enum ACTION_ZOOM_NORMAL = "zoom-normal"; 32 | enum ACTION_SAVE = "save"; 33 | enum ACTION_SYNC_INPUT_OVERRIDE = "sync-input-override"; 34 | enum ACTION_INSERT_NUMBER = "insert-number"; 35 | enum ACTION_INSERT_PASSWORD = "insert-password"; 36 | enum ACTION_TITLE_STYLE = "title-style"; 37 | enum ACTION_SELECT_BOOKMARK = "select-bookmark"; 38 | enum ACTION_ADD_BOOKMARK = "add-bookmark"; 39 | enum ACTION_SCROLL_UP = "scroll-up"; 40 | enum ACTION_SCROLL_DOWN = "scroll-down"; 41 | enum ACTION_PAGE_UP = "page-up"; 42 | enum ACTION_PAGE_DOWN = "page-down"; 43 | enum ACTION_MONITOR_SILENCE = "monitor-silence"; 44 | enum ACTION_FILE_BROWSER = "file-browser"; 45 | enum ACTION_PREVIOUS_PROMPT = "previous-prompt"; 46 | enum ACTION_NEXT_PROMPT = "next-prompt"; 47 | enum ACTION_TOGGLE_MARGIN = "toggle-margin"; -------------------------------------------------------------------------------- /source/gx/tilix/terminal/activeprocess.d: -------------------------------------------------------------------------------- 1 | module gx.tilix.terminal.activeprocess; 2 | 3 | import core.sys.posix.unistd; 4 | import core.thread; 5 | 6 | import std.algorithm; 7 | import std.array; 8 | import std.conv; 9 | import std.experimental.logger; 10 | import std.file; 11 | import std.path; 12 | import std.string; 13 | 14 | 15 | /** 16 | * A stripped-down (plus extended) version of psutil's Process class. 17 | */ 18 | class Process { 19 | 20 | pid_t pid; 21 | string[] processStat; 22 | static Process[pid_t] processMap; 23 | static Process[][pid_t] sessionMap; 24 | 25 | this(pid_t p) 26 | { 27 | pid = p; 28 | processStat = parseStatFile(); 29 | } 30 | 31 | @property string name() { 32 | return processStat[0]; 33 | } 34 | 35 | @property pid_t ppid() { 36 | return to!pid_t(processStat[2]); 37 | } 38 | 39 | string[] parseStatFile() { 40 | try { 41 | string data = to!string(cast(char[])read(format("/proc/%d/stat", pid))); 42 | size_t rpar = data.lastIndexOf(")"); 43 | string name = data[data.indexOf("(") + 1..rpar]; 44 | string[] other = data[rpar + 2..data.length].split; 45 | return name ~ other; 46 | } catch (FileException fe) { 47 | warning(fe); 48 | } 49 | return "? 0 0 0 0 0 0".split; 50 | } 51 | 52 | /** 53 | * Foreground process has a controlling terminal and 54 | * process group id == terminal process group id. 55 | */ 56 | bool isForeground() { 57 | if (!Process.pidExists(pid)) { 58 | return false; 59 | } 60 | // Need updated version. 61 | string[] tempStat = parseStatFile(); 62 | long pgrp = to!long(tempStat[3]); 63 | long tty = to!long(tempStat[5]); 64 | long tpgid = to!long(tempStat[6]); 65 | return tty > 0 && pgrp == tpgid; 66 | } 67 | 68 | bool hasTTY() { 69 | return to!long(processStat[5]) > 0; 70 | } 71 | 72 | /** 73 | * Shell PID == session ID 74 | */ 75 | pid_t sessionID() { 76 | return to!pid_t(processStat[4]); 77 | } 78 | 79 | /** 80 | * Return true if this process has any foreground child process. 81 | * Note that `Process.sessionMap` contains foreground processes only. 82 | */ 83 | bool hasForegroundChildren() { 84 | foreach (p; Process.sessionMap.get(sessionID(), [])) { 85 | if (p.ppid == pid) { 86 | return true; 87 | } 88 | } 89 | return false; 90 | } 91 | 92 | /** 93 | * Get all running PIDs. 94 | */ 95 | static pid_t[] pids() { 96 | return std.file.dirEntries("/proc", SpanMode.shallow) 97 | .filter!(a => std.path.baseName(a.name).isNumeric) 98 | .map!(a => to!pid_t(std.path.baseName(a.name))) 99 | .array; 100 | } 101 | 102 | static bool pidExists(pid_t p) { 103 | return exists(format("/proc/%d", p)); 104 | } 105 | 106 | /** 107 | * Create `Process` object of all PIDs and store them in 108 | * `Process.processMap` and store foreground processes 109 | * in `Process.sessionMap` using session id as their key. 110 | */ 111 | static void updateMap() { 112 | 113 | Process add(pid_t p) { 114 | auto proc = new Process(p); 115 | Process.processMap[p] = proc; 116 | return proc; 117 | } 118 | 119 | void remove(pid_t p) { 120 | Process.processMap.remove(p); 121 | } 122 | 123 | auto pids = Process.pids().sort(); 124 | auto pmapKeys = Process.processMap.keys.sort(); 125 | auto gonePids = setDifference(pmapKeys, pids); 126 | 127 | foreach(p; gonePids) { 128 | remove(p); 129 | } 130 | 131 | Process.processMap.rehash; 132 | Process proc; 133 | Process.sessionMap.clear; 134 | 135 | foreach(p; pids) { 136 | if (p in Process.processMap) { 137 | proc = Process.processMap[p]; // Cached process. 138 | } else if (Process.pidExists(p)) { 139 | proc = add(p); // New Process. 140 | } 141 | // Taking advantages of short-circuit operator `&&` using `proc.hasTTY()` 142 | // to reduce calling on `proc.isForeground()`. 143 | if (proc !is null && proc.hasTTY() && proc.isForeground()) { 144 | Process.sessionMap[proc.sessionID()] ~= proc; 145 | } 146 | } 147 | } 148 | } 149 | 150 | 151 | /** 152 | * Get active process list of all terminals. 153 | * `Process.sessionMap` contains foreground processes of all 154 | * open terminals using session id (shell PID) as their key. We are 155 | * iterating through all processes for each session id and trying 156 | * to find their active process and finally returning all active process. 157 | * Returning all active process is very efficient when there are too 158 | * many open terminals comparing to find the active process of several 159 | * terminals one by one. 160 | */ 161 | Process[pid_t] getActiveProcessList() { 162 | // Update `Process.sessionMap` and `Process.processMap`. 163 | Process.updateMap(); 164 | Process[pid_t] ret; 165 | foreach(shellChild; Process.sessionMap.byValue()) { 166 | // The shell process has only one foreground 167 | // process, so, it is an active process. 168 | if (shellChild.length == 1) { 169 | auto proc = shellChild[0]; 170 | ret[proc.sessionID()] = proc; 171 | } else { 172 | // Probably, the last item is the active process. 173 | foreach_reverse(proc; shellChild) { 174 | // If a foreground process has no foreground 175 | // child process then it is an active process. 176 | if (!proc.hasForegroundChildren()) { 177 | ret[proc.sessionID()] = proc; 178 | break; 179 | } 180 | } 181 | } 182 | } 183 | return ret; 184 | } 185 | -------------------------------------------------------------------------------- /source/gx/tilix/terminal/advpaste.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.terminal.advpaste; 6 | 7 | import std.experimental.logger; 8 | import std.format; 9 | import std.string; 10 | 11 | import gdk.Event; 12 | import gdk.Keysyms; 13 | 14 | import gio.Settings: GSettings = Settings; 15 | 16 | import gtk.Box; 17 | import gtk.CheckButton; 18 | import gtk.Dialog; 19 | import gtk.Label; 20 | import gtk.SpinButton; 21 | import gtk.TextBuffer; 22 | import gtk.TextTagTable; 23 | import gtk.TextView; 24 | import gtk.ScrolledWindow; 25 | import gtk.Widget; 26 | import gtk.Window; 27 | 28 | import gx.i18n.l10n; 29 | 30 | import gx.tilix.preferences; 31 | 32 | string[3] getUnsafePasteMessage() { 33 | string[3] result = [_("This command is asking for Administrative access to your computer"), 34 | _("Copying commands from the internet can be dangerous. "), 35 | _("Be sure you understand what each part of this command does.")]; 36 | 37 | return result; 38 | } 39 | 40 | /** 41 | * A dialog that is shown to support advance paste. It allows the user 42 | * to review and edit the content as well as performing various transformations 43 | * before pasting. 44 | */ 45 | class AdvancedPasteDialog: Dialog { 46 | 47 | private: 48 | 49 | GSettings gsSettings; 50 | 51 | TextBuffer buffer; 52 | CheckButton cbTabsToSpaces; 53 | SpinButton sbTabWidth; 54 | 55 | CheckButton cbConvertCRLF; 56 | 57 | void createUI(string text, bool unsafe) { 58 | with (getContentArea()) { 59 | setMarginLeft(18); 60 | setMarginRight(18); 61 | setMarginTop(18); 62 | setMarginBottom(18); 63 | } 64 | 65 | Box b = new Box(Orientation.VERTICAL, 6); 66 | if (unsafe) { 67 | string[3] msg = getUnsafePasteMessage(); 68 | Label lblUnsafe = new Label("" ~ msg[0] ~ "\n" ~ msg[1] ~ "\n" ~ msg[2]); 69 | lblUnsafe.setUseMarkup(true); 70 | lblUnsafe.setLineWrap(true); 71 | b.add(lblUnsafe); 72 | getWidgetForResponse(ResponseType.APPLY).getStyleContext().addClass("destructive-action"); 73 | } 74 | 75 | buffer = new TextBuffer(new TextTagTable()); 76 | buffer.setText(text); 77 | TextView view = new TextView(buffer); 78 | view.addOnKeyPress(delegate(Event event, Widget w) { 79 | uint keyval; 80 | event.getKeyval(keyval); 81 | if (keyval == GdkKeysyms.GDK_Return && (event.key.state & GdkModifierType.CONTROL_MASK)) { 82 | response(GtkResponseType.APPLY); 83 | return true; 84 | } 85 | return false; 86 | }); 87 | ScrolledWindow sw = new ScrolledWindow(view); 88 | sw.setShadowType(ShadowType.ETCHED_IN); 89 | sw.setPolicy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC); 90 | sw.setHexpand(true); 91 | sw.setVexpand(true); 92 | sw.setSizeRequest(400, 140); 93 | 94 | b.add(sw); 95 | 96 | Label lblTransform = new Label(format("%s", _("Transform"))); 97 | lblTransform.setUseMarkup(true); 98 | lblTransform.setHalign(Align.START); 99 | lblTransform.setMarginTop(6); 100 | b.add(lblTransform); 101 | 102 | //Tabs to Spaces 103 | Box bTabs = new Box(Orientation.HORIZONTAL, 6); 104 | cbTabsToSpaces = new CheckButton(_("Convert spaces to tabs")); 105 | gsSettings.bind(SETTINGS_ADVANCED_PASTE_REPLACE_TABS_KEY, cbTabsToSpaces, "active", GSettingsBindFlags.DEFAULT); 106 | bTabs.add(cbTabsToSpaces); 107 | 108 | sbTabWidth = new SpinButton(0, 32, 1); 109 | gsSettings.bind(SETTINGS_ADVANCED_PASTE_SPACE_COUNT_KEY, sbTabWidth.getAdjustment(), "value", GSettingsBindFlags.DEFAULT); 110 | gsSettings.bind(SETTINGS_ADVANCED_PASTE_REPLACE_TABS_KEY, sbTabWidth, "sensitive", GSettingsBindFlags.DEFAULT); 111 | bTabs.add(sbTabWidth); 112 | 113 | b.add(bTabs); 114 | 115 | cbConvertCRLF = new CheckButton(_("Convert CRLF and CR to LF")); 116 | gsSettings.bind(SETTINGS_ADVANCED_PASTE_REPLACE_CRLF_KEY, cbConvertCRLF, "active", GSettingsBindFlags.DEFAULT); 117 | b.add(cbConvertCRLF); 118 | 119 | getContentArea().add(b); 120 | } 121 | 122 | string transform() { 123 | string text = buffer.getText(); 124 | if (gsSettings.getBoolean(SETTINGS_ADVANCED_PASTE_REPLACE_TABS_KEY)) { 125 | text = text.detab(gsSettings.getInt(SETTINGS_ADVANCED_PASTE_SPACE_COUNT_KEY)); 126 | } 127 | if (gsSettings.getBoolean(SETTINGS_ADVANCED_PASTE_REPLACE_CRLF_KEY)) { 128 | text = text.replace("\r\n", "\n"); 129 | text = text.replace("\r", "\n"); 130 | 131 | } 132 | return text; 133 | } 134 | 135 | public: 136 | this(Window parent, string text, bool unsafe) { 137 | super(_("Advanced Paste"), parent, GtkDialogFlags.MODAL + GtkDialogFlags.USE_HEADER_BAR, [_("Paste"), _("Cancel")], [GtkResponseType.APPLY, GtkResponseType.CANCEL]); 138 | setTransientFor(parent); 139 | setDefaultResponse(GtkResponseType.APPLY); 140 | gsSettings = new GSettings(SETTINGS_ID); 141 | createUI(text, unsafe); 142 | } 143 | 144 | @property string text() { 145 | return transform(); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /source/gx/tilix/terminal/layout.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.terminal.layout; 6 | 7 | import std.format; 8 | 9 | import gtk.Dialog; 10 | import gtk.Entry; 11 | import gtk.Grid; 12 | import gtk.Label; 13 | import gtk.Version; 14 | import gtk.Window; 15 | 16 | import gx.i18n.l10n; 17 | import gx.gtk.vte; 18 | 19 | import gx.tilix.prefeditor.titleeditor; 20 | 21 | /** 22 | * Dialog that enables the user to set the layout options for a terminal 23 | */ 24 | class LayoutDialog: Dialog { 25 | 26 | private: 27 | Entry eBadge; 28 | Entry eTitle; 29 | Entry eCommand; 30 | 31 | public: 32 | this(Window window) { 33 | super(_("Layout Options"), window, DialogFlags.MODAL + DialogFlags.USE_HEADER_BAR, [_("OK"), _("Cancel")], [ResponseType.OK, ResponseType.CANCEL]); 34 | setDefaultResponse(ResponseType.OK); 35 | setTransientFor(window); 36 | setDefaultSize(400, -1); 37 | 38 | Grid grid = new Grid(); 39 | grid.setMarginTop(18); 40 | grid.setMarginBottom(18); 41 | grid.setMarginLeft(18); 42 | grid.setMarginRight(18); 43 | grid.setColumnSpacing(12); 44 | grid.setRowSpacing(6); 45 | 46 | int row = 0; 47 | 48 | Label lblActive = new Label(format("%s", _("Active"))); 49 | lblActive.setUseMarkup(true); 50 | lblActive.setHalign(Align.START); 51 | grid.attach(lblActive, 0, row, 2, 1); 52 | row++; 53 | 54 | Label lblTitle = new Label(_("Title")); 55 | lblTitle.setHalign(Align.END); 56 | grid.attach(lblTitle, 0, row, 1, 1); 57 | eTitle = new Entry(); 58 | eTitle.setWidthChars(20); 59 | eTitle.setHexpand(true); 60 | if (Version.checkVersion(3,16, 0).length == 0) { 61 | grid.attach(createTitleEditHelper(eTitle, TitleEditScope.TERMINAL), 1, row, 1, 1); 62 | } else { 63 | grid.attach(eTitle, 1, row, 1, 1); 64 | } 65 | row++; 66 | 67 | if (checkVTEFeature(TerminalFeature.DISABLE_BACKGROUND_DRAW)) { 68 | Label lblBadge = new Label(_("Badge")); 69 | lblBadge.setHalign(Align.END); 70 | grid.attach(lblBadge, 0, row, 1, 1); 71 | eBadge = new Entry(); 72 | eBadge.setHexpand(true); 73 | eBadge.setWidthChars(20); 74 | if (Version.checkVersion(3,16, 0).length == 0) { 75 | grid.attach(createTitleEditHelper(eBadge, TitleEditScope.TERMINAL), 1, row, 1, 1); 76 | } else { 77 | grid.attach(eBadge, 1, row, 1, 1); 78 | } 79 | row++; 80 | } 81 | 82 | Label lblLoad = new Label(format("%s", _("Session Load"))); 83 | lblLoad.setUseMarkup(true); 84 | lblLoad.setHalign(Align.START); 85 | lblLoad.setMarginTop(6); 86 | grid.attach(lblLoad, 0, row, 2, 1); 87 | row++; 88 | 89 | Label lblCommand = new Label(_("Command")); 90 | lblCommand.setHalign(Align.END); 91 | 92 | grid.attach(lblCommand, 0, row, 1, 1); 93 | eCommand = new Entry(); 94 | eCommand.setWidthChars(20); 95 | grid.attach(eCommand, 1, row, 1, 1); 96 | row++; 97 | 98 | Label lblInfo = new Label(_("Active options are always in effect and apply immediately.\nSession Load options only apply when loading a session file.")); 99 | lblInfo.setSensitive(false); 100 | lblInfo.setMarginTop(6); 101 | lblInfo.setLineWrap(true); 102 | grid.attach(lblInfo, 0, row, 2, 1); 103 | row++; 104 | 105 | getContentArea().add(grid); 106 | } 107 | 108 | @property string title() { 109 | return eTitle.getText(); 110 | } 111 | 112 | @property void title(string value) { 113 | if (value.length > 0) { 114 | eTitle.setText(value); 115 | } 116 | } 117 | 118 | @property string badge() { 119 | if (!checkVTEFeature(TerminalFeature.DISABLE_BACKGROUND_DRAW)) return ""; 120 | return eBadge.getText(); 121 | } 122 | 123 | @property void badge(string value) { 124 | if (checkVTEFeature(TerminalFeature.DISABLE_BACKGROUND_DRAW) && value.length > 0) { 125 | eBadge.setText(value); 126 | } 127 | } 128 | 129 | @property string command() { 130 | return eCommand.getText(); 131 | } 132 | 133 | @property void command(string value) { 134 | if (value.length > 0) { 135 | eCommand.setText(value); 136 | } 137 | } 138 | } -------------------------------------------------------------------------------- /source/gx/tilix/terminal/monitor.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.terminal.monitor; 6 | 7 | import core.sys.posix.unistd; 8 | import core.thread; 9 | 10 | import std.concurrency; 11 | import std.datetime; 12 | import std.experimental.logger; 13 | import std.parallelism; 14 | 15 | import vtec.vtetypes; 16 | 17 | import gx.i18n.l10n; 18 | import gx.gtk.threads; 19 | 20 | import gx.tilix.common; 21 | import gx.tilix.constants; 22 | import gx.tilix.terminal.activeprocess; 23 | 24 | import gx.tilix.application; 25 | 26 | enum MonitorEventType { 27 | NONE, 28 | STARTED, 29 | CHANGED, 30 | FINISHED 31 | }; 32 | 33 | /** 34 | * Class that monitors processes to see if new child processes have been 35 | * started or finished and raises an event if detected. This class uses 36 | * a separate thread to monitor the processes and a timeoutDelegate to 37 | * trigger the actual events to the terminals. 38 | */ 39 | class ProcessMonitor { 40 | private: 41 | Tid tid; 42 | bool running = false; 43 | 44 | bool fireEvents() { 45 | synchronized { 46 | foreach(process; processes) { 47 | if (process.eventType != MonitorEventType.NONE) { 48 | onChildProcess.emit(process.eventType, process.gpid, process.activePid, process.activeName); 49 | process.eventType = MonitorEventType.NONE; 50 | } 51 | } 52 | } 53 | return running; 54 | } 55 | 56 | static ProcessMonitor _instance; 57 | 58 | public: 59 | this() { 60 | 61 | } 62 | 63 | ~this() { 64 | stop(); 65 | } 66 | 67 | void start() { 68 | running = true; 69 | tid = spawn(&monitorProcesses, SLEEP_CONSTANT_MS, thisTid); 70 | threadsAddTimeoutDelegate(SLEEP_CONSTANT_MS, &fireEvents); 71 | trace("Started process monitoring"); 72 | } 73 | 74 | void stop() { 75 | if (running) tid.send(true); 76 | running = false; 77 | trace("Stopped process monitoring"); 78 | } 79 | 80 | /** 81 | * Add a process for monitoring 82 | */ 83 | void addProcess(GPid gpid) { 84 | synchronized { 85 | if (gpid !in processes) { 86 | shared ProcessStatus status = new shared(ProcessStatus)(gpid); 87 | processes[gpid] = status; 88 | } 89 | } 90 | if (!running) start(); 91 | } 92 | 93 | /** 94 | * Remove a process for monitoring 95 | */ 96 | void removeProcess(GPid gpid) { 97 | synchronized { 98 | if (gpid in processes) { 99 | processes.remove(gpid); 100 | if (running && processes.length == 0) stop(); 101 | } 102 | } 103 | } 104 | 105 | /** 106 | * When a process changes inform children 107 | */ 108 | GenericEvent!(MonitorEventType, GPid, pid_t, string) onChildProcess; 109 | 110 | static @property ProcessMonitor instance() { 111 | if (!tilix.processMonitor) { 112 | warningf(_("Process monitoring is not enabled, this should never be called")); 113 | } 114 | if (_instance is null) { 115 | _instance = new ProcessMonitor(); 116 | } 117 | return _instance; 118 | } 119 | } 120 | 121 | private: 122 | 123 | /** 124 | * Constant used for sleep time between checks. 125 | */ 126 | enum SLEEP_CONSTANT_MS = 300; 127 | 128 | /** 129 | * List of processes being monitored. 130 | */ 131 | shared ProcessStatus[GPid] processes; 132 | 133 | void monitorProcesses(int sleep, Tid tid) { 134 | bool abort = false; 135 | while (!abort) { 136 | synchronized { 137 | // At this point we have a list of active processes of 138 | // all open terminals. We need to get these using shell 139 | // PID and will store them to raise events for each terminal. 140 | auto activeProcesses = getActiveProcessList(); 141 | foreach(process; processes) { 142 | auto activeProcess = activeProcesses.get(process.gpid, null); 143 | // No need to raise event for same process. 144 | if (activeProcess !is null && activeProcess.pid != process.activePid) { 145 | process.activeName = activeProcess.name; 146 | process.activePid = activeProcess.pid; 147 | process.eventType = MonitorEventType.STARTED; 148 | } 149 | } 150 | } 151 | receiveTimeout(dur!("msecs")( sleep ), 152 | (bool msg) { 153 | if (msg) abort = true; 154 | } 155 | ); 156 | } 157 | } 158 | 159 | /** 160 | * Status of a single process 161 | */ 162 | shared class ProcessStatus { 163 | GPid gpid; 164 | pid_t activePid = -1; 165 | string activeName = ""; 166 | MonitorEventType eventType = MonitorEventType.NONE; 167 | 168 | this(GPid gpid) { 169 | this.gpid = gpid; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /source/gx/tilix/terminal/util.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.tilix.terminal.util; 6 | 7 | import std.conv; 8 | import std.experimental.logger; 9 | import std.file; 10 | import std.process; 11 | import std.uuid; 12 | 13 | //Cribbed from Gnome Terminal 14 | immutable string[] shells = [/* Note that on some systems shells can also 15 | * be installed in /usr/bin */ 16 | "/bin/bash", "/usr/bin/bash", "/bin/zsh", "/usr/bin/zsh", "/bin/tcsh", "/usr/bin/tcsh", "/bin/ksh", "/usr/bin/ksh", "/bin/csh", "/bin/sh"]; 17 | 18 | string getUserShell(string shell) { 19 | import std.file : exists; 20 | import core.sys.posix.pwd : getpwuid, passwd; 21 | import core.sys.posix.unistd: getuid; 22 | 23 | if (shell.length > 0 && exists(shell)) 24 | return shell; 25 | 26 | // Try environment variable next 27 | try { 28 | shell = environment["SHELL"]; 29 | if (shell.length > 0) { 30 | tracef("Using shell %s from SHELL environment variable", shell); 31 | return shell; 32 | } 33 | } 34 | catch (Exception e) { 35 | trace("No SHELL environment variable found"); 36 | } 37 | 38 | //Try to get shell from getpwuid 39 | passwd* pw = getpwuid(getuid()); 40 | if (pw && pw.pw_shell) { 41 | string pw_shell = to!string(pw.pw_shell); 42 | if (exists(pw_shell)) { 43 | tracef("Using shell %s from getpwuid",pw_shell); 44 | return pw_shell; 45 | } 46 | } 47 | 48 | //Try known shells 49 | foreach (s; shells) { 50 | if (exists(s)) { 51 | tracef("Found shell %s, using that", s); 52 | return s; 53 | } 54 | } 55 | error("No shell found, defaulting to /bin/sh"); 56 | return "/bin/sh"; 57 | } 58 | 59 | bool isFlatpak() { 60 | return "/.flatpak-info".exists; 61 | } -------------------------------------------------------------------------------- /source/gx/util/array.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.util.array; 6 | 7 | import std.algorithm; 8 | import std.array; 9 | 10 | /** 11 | * Removes the specified element from the array (once). 12 | * 13 | * Params: 14 | * array = The array to remove the item from. 15 | * element = The item to look for and remove. 16 | * 17 | * Adapted from grestful, modified to explicitly check index 18 | */ 19 | void remove(T)(ref T[] array, T element) { 20 | auto index = array.countUntil(element); 21 | while (index >= 0) { 22 | array[index] = null; 23 | array = std.algorithm.remove(array, index); 24 | index = array.countUntil(element); 25 | } 26 | } 27 | 28 | unittest { 29 | string[] test = ["test1", "test2", "test3"]; 30 | 31 | remove(test, "test1"); 32 | assert(test == ["test2", "test3"]); 33 | remove(test, "test4"); 34 | assert(test == ["test2", "test3"]); 35 | } 36 | -------------------------------------------------------------------------------- /source/gx/util/path.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | module gx.util.path; 6 | 7 | import std.path; 8 | import std.process; 9 | import std.string; 10 | 11 | /** 12 | * Resolves the path by converting tilde and environment 13 | * variables in the path. 14 | */ 15 | string resolvePath(string path) { 16 | string result = expandTilde(path); 17 | string[string] env = environment.toAA(); 18 | foreach(name; env.keys) { 19 | result = result.replace('$' ~ name, env[name]); 20 | result = result.replace("${" ~ name ~ "}", env[name]); 21 | } 22 | return result; 23 | } 24 | -------------------------------------------------------------------------------- /source/gx/util/string.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not 3 | * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | */ 5 | 6 | module gx.util.string; 7 | 8 | import std.string; 9 | 10 | /** 11 | * Escape a string to include a CSV according to the rules expected 12 | * by std.csv. 13 | */ 14 | string escapeCSV(string value) { 15 | if (value.length == 0) return value; 16 | value = value.replace("\"", "\"\""); 17 | if (value.indexOf('\n') >= 0 || value.indexOf(',') >= 0 || value.indexOf("\"\"") >= 0) { 18 | value = "\"" ~ value ~ "\""; 19 | } 20 | return value; 21 | } 22 | 23 | unittest { 24 | assert(escapeCSV("test") == "test"); 25 | assert(escapeCSV("gedit \"test\"") == "\"gedit \"\"test\"\"\""); 26 | assert(escapeCSV("test,this is") == "\"test,this is\""); 27 | } -------------------------------------------------------------------------------- /source/secret/SchemaAttribute.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of gtkD. 3 | * 4 | * gtkD is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License 6 | * as published by the Free Software Foundation; either version 3 7 | * of the License, or (at your option) any later version, with 8 | * some exceptions, please read the COPYING file. 9 | * 10 | * gtkD is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with gtkD; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 | */ 19 | 20 | // generated automatically - do not change 21 | // find conversion definition on APILookup.txt 22 | // implement new conversion functionalities on the wrap.utils pakage 23 | 24 | 25 | module secret.SchemaAttribute; 26 | 27 | private import secretc.secret; 28 | public import secretc.secrettypes; 29 | 30 | 31 | /** 32 | * An attribute in a #SecretSchema. 33 | */ 34 | public struct SchemaAttribute 35 | { 36 | 37 | /** */ 38 | public static GType getType() 39 | { 40 | return secret_schema_attribute_get_type(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /source/secret/Value.d: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of gtkD. 3 | * 4 | * gtkD is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU Lesser General Public License 6 | * as published by the Free Software Foundation; either version 3 7 | * of the License, or (at your option) any later version, with 8 | * some exceptions, please read the COPYING file. 9 | * 10 | * gtkD is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with gtkD; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 | */ 19 | 20 | // generated automatically - do not change 21 | // find conversion definition on APILookup.txt 22 | // implement new conversion functionalities on the wrap.utils pakage 23 | 24 | 25 | module secret.Value; 26 | 27 | private import glib.ConstructionException; 28 | private import glib.Str; 29 | private import gobject.ObjectG; 30 | private import secretc.secret; 31 | public import secretc.secrettypes; 32 | 33 | 34 | /** 35 | * A secret value, like a password or other binary secret. 36 | */ 37 | public class Value 38 | { 39 | /** the main Gtk struct */ 40 | protected SecretValue* secretValue; 41 | protected bool ownedRef; 42 | 43 | /** Get the main Gtk struct */ 44 | public SecretValue* getValueStruct() 45 | { 46 | return secretValue; 47 | } 48 | 49 | /** the main Gtk struct as a void* */ 50 | protected void* getStruct() 51 | { 52 | return cast(void*)secretValue; 53 | } 54 | 55 | /** 56 | * Sets our main struct and passes it to the parent class. 57 | */ 58 | public this (SecretValue* secretValue, bool ownedRef = false) 59 | { 60 | this.secretValue = secretValue; 61 | this.ownedRef = ownedRef; 62 | } 63 | 64 | 65 | /** */ 66 | public static GType getType() 67 | { 68 | return secret_value_get_type(); 69 | } 70 | 71 | /** 72 | * Create a #SecretValue for the secret data passed in. The secret data is 73 | * copied into non-pageable 'secure' memory. 74 | * 75 | * If the length is less than zero, then @secret is assumed to be 76 | * null-terminated. 77 | * 78 | * Params: 79 | * secret = the secret data 80 | * length = the length of the data 81 | * contentType = the content type of the data 82 | * 83 | * Return: the new #SecretValue 84 | * 85 | * Throws: ConstructionException GTK+ fails to create the object. 86 | */ 87 | public this(string secret, ptrdiff_t length, string contentType) 88 | { 89 | auto p = secret_value_new(Str.toStringz(secret), length, Str.toStringz(contentType)); 90 | 91 | if(p is null) 92 | { 93 | throw new ConstructionException("null returned by new"); 94 | } 95 | 96 | this(cast(SecretValue*) p); 97 | } 98 | 99 | /** 100 | * Create a #SecretValue for the secret data passed in. The secret data is 101 | * not copied, and will later be freed with the @destroy function. 102 | * 103 | * If the length is less than zero, then @secret is assumed to be 104 | * null-terminated. 105 | * 106 | * Params: 107 | * secret = the secret data 108 | * length = the length of the data 109 | * contentType = the content type of the data 110 | * destroy = function to call to free the secret data 111 | * 112 | * Return: the new #SecretValue 113 | * 114 | * Throws: ConstructionException GTK+ fails to create the object. 115 | */ 116 | public this(string secret, ptrdiff_t length, string contentType, GDestroyNotify destroy) 117 | { 118 | auto p = secret_value_new_full(Str.toStringz(secret), length, Str.toStringz(contentType), destroy); 119 | 120 | if(p is null) 121 | { 122 | throw new ConstructionException("null returned by new_full"); 123 | } 124 | 125 | this(cast(SecretValue*) p); 126 | } 127 | 128 | /** 129 | * Get the secret data in the #SecretValue. The value is not necessarily 130 | * null-terminated unless it was created with secret_value_new() or a 131 | * null-terminated string was passed to secret_value_new_full(). 132 | * 133 | * Return: the secret data 134 | */ 135 | public string get() 136 | { 137 | size_t length; 138 | 139 | return Str.toString(secret_value_get(secretValue, &length)); 140 | } 141 | 142 | /** 143 | * Get the content type of the secret value, such as 144 | * text/plain. 145 | * 146 | * Return: the content type 147 | */ 148 | public string getContentType() 149 | { 150 | return Str.toString(secret_value_get_content_type(secretValue)); 151 | } 152 | 153 | /** 154 | * Get the secret data in the #SecretValue if it contains a textual 155 | * value. The content type must be text/plain. 156 | * 157 | * Return: the content type 158 | */ 159 | public string getText() 160 | { 161 | return Str.toString(secret_value_get_text(secretValue)); 162 | } 163 | 164 | /** 165 | * Add another reference to the #SecretValue. For each reference 166 | * secret_value_unref() should be called to unreference the value. 167 | * 168 | * Return: the value 169 | */ 170 | public Value doref() 171 | { 172 | auto p = secret_value_ref(secretValue); 173 | 174 | if(p is null) 175 | { 176 | return null; 177 | } 178 | 179 | return ObjectG.getDObject!(Value)(cast(SecretValue*) p, true); 180 | } 181 | 182 | /** 183 | * Unreference a #SecretValue. When the last reference is gone, then 184 | * the value will be freed. 185 | */ 186 | public void unref() 187 | { 188 | secret_value_unref(secretValue); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /source/x11/README.md: -------------------------------------------------------------------------------- 1 | ## Notice 2 | 3 | This is an extract of some specific files from the [x11](https://github.com/nomad-software/x11) repository. This was done instead of linking to it via DUB because DUB isn't well supported by Linux distro's so add adding dub libraries is problematic. 4 | 5 | Longer term this solution obviously does not scale, the hope is that DUB becomes better supported or an alternate build system like meson could be adapted to fit the bill. 6 | -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | if [ -z "$1" ]; then 4 | export PREFIX=/usr 5 | # Make sure only root can run our script 6 | if [ "$(id -u)" != "0" ]; then 7 | echo "This script must be run as root" 1>&2 8 | exit 1 9 | fi 10 | else 11 | export PREFIX=$1 12 | fi 13 | 14 | echo "Uninstalling from prefix ${PREFIX}" 15 | 16 | rm ${PREFIX}/bin/tilix 17 | rm ${PREFIX}/share/glib-2.0/schemas/com.gexperts.Tilix.gschema.xml 18 | glib-compile-schemas ${PREFIX}/share/glib-2.0/schemas/ 19 | rm -rf ${PREFIX}/share/tilix 20 | 21 | find ${PREFIX}/share/locale -type f -name "tilix.mo" -delete 22 | find ${PREFIX}/share/icons/hicolor -type f -name "com.gexperts.Tilix.png" -delete 23 | find ${PREFIX}/share/icons/hicolor -type f -name "com.gexperts.Tilix*.svg" -delete 24 | rm ${PREFIX}/share/nautilus-python/extensions/open-tilix.py 25 | rm ${PREFIX}/share/dbus-1/services/com.gexperts.Tilix.service 26 | rm ${PREFIX}/share/applications/com.gexperts.Tilix.desktop 27 | rm ${PREFIX}/share/metainfo/com.gexperts.Tilix.appdata.xml 28 | rm ${PREFIX}/share/man/man1/tilix.1.gz 29 | rm ${PREFIX}/share/man/*/man1/tilix.1.gz 30 | --------------------------------------------------------------------------------