Repository: dabisu/sakura Branch: master Commit: adf670c49bdd Files: 31 Total size: 273.6 KB Directory structure: gitextract_cun7s59m/ ├── .gitignore ├── AUTHORS ├── CMakeLists.txt ├── LICENSE ├── README.md ├── po/ │ ├── CMakeLists.txt │ ├── POTFILES.in │ ├── ca.po │ ├── cs.po │ ├── de.po │ ├── en_GB.po │ ├── es.po │ ├── fr.po │ ├── he.po │ ├── hr.po │ ├── hu.po │ ├── it.po │ ├── ja.po │ ├── ka.po │ ├── ko.po │ ├── pl.po │ ├── pt.po │ ├── pt_BR.po │ ├── ru.po │ ├── sv.po │ ├── tr.po │ ├── uk.po │ └── zh_CN.po ├── sakura.desktop ├── sakura.pod └── src/ └── sakura.c ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ cmake_install.cmake CMakeFiles CMakeCache.txt Makefile build/ *.gmo *.mo po/sakura.pot install_manifest.txt src/sakura sakura.1 ================================================ FILE: AUTHORS ================================================ Main author ============ David Gómez Espinosa Contributors ============ Tom Adams Fábio Antunes Szervác Attila Mattia Bertoni Mario Blättermann Iain Bucław Kang Bundo Tim Bynum Costin Chirvasuta Isratine Citizen Álex Cornejo Fabio Cobianchi Eric Davis Fabio Di Matteo Nicola Fontana Aleksey Frolov atommixz@gmail.com Dávid Gábor Bodor Thibaut Girka Josh Glover Grindhold Stefan Haller Jen Yee Hong Itn Jordi Jané Cardo David Jensen Adam Juraszek Lado Kumsiashvili Daniel Kondor Lukáš Lommer Torbjörn Lönnemark Yannick LM Michał Łuszczyk Calvin M Enric Morales Thorsten Mühlfelder Rafał Mużyło Dmitry N. Shilov Erik Nelson Raúl Núñez de Arenas Coronado Dražen Odobašić Marc-Antoine Perennou Kalle Raiskila Sebastian Reichel Páder Rezső Aurélien Riviere Andreas Rönnquist Ildar Sagdejev Iñigo Serna Andrew Starr-Bochicchio Tenzing Sergey Tominov Fabrice Thiroux Hiroshi Utumi Pável Varela Rodríguez Evgenij Vdovin Jesper Wallin Aron Xu Yuanyelele Chidambar Zinnoury Artwork ======= Terminal icon was created by the Tango Desktop Project: http://tango.freedesktop.org If you're not here, cry loud and send me an email ;) : ================================================ FILE: CMakeLists.txt ================================================ CMAKE_MINIMUM_REQUIRED (VERSION 3.15 FATAL_ERROR) CMAKE_POLICY(SET CMP0005 NEW) PROJECT (sakura) SET (AUTHOR "David Gómez Espinosa" INTERNAL "Author") SET (VERSION "3.8.9") INCLUDE (FindPkgConfig) IF (NOT PKG_CONFIG_FOUND) MESSAGE (FATAL_ERROR "pkg-config not found...") ENDIF (NOT PKG_CONFIG_FOUND) pkg_check_modules (GLIB REQUIRED glib-2.0>=2.40) IF (NOT GLIB_FOUND) MESSAGE(FATAL_ERROR "You don't seem to have glib >= 2.40 development libraries installed...") ENDIF (NOT GLIB_FOUND) pkg_check_modules (GLIB REQUIRED gio-unix-2.0) IF (NOT GLIB_FOUND) MESSAGE(FATAL_ERROR "You don't seem to have glib >= 2.40 development libraries installed...") ENDIF (NOT GLIB_FOUND) pkg_check_modules (GTK REQUIRED gtk+-3.0>=3.20) IF (NOT GTK_FOUND) MESSAGE(FATAL_ERROR "You don't seem to have gtk >= 3.20 development libraries installed...") ENDIF (NOT GTK_FOUND) pkg_check_modules (VTE REQUIRED vte-2.91>=0.50) IF (NOT VTE_FOUND) MESSAGE(FATAL_ERROR "You don't seem to have vte >= 0.50 development libraries installed...") ENDIF (NOT VTE_FOUND) pkg_check_modules (X11 REQUIRED x11) IF (NOT X11_FOUND) MESSAGE(FATAL_ERROR "You don't seem to have x11 development libraries installed...") ENDIF (NOT X11_FOUND) FIND_PROGRAM(POD2MAN pod2man) MESSAGE ("pod2man executable is" ${POD2MAN}) ADD_DEFINITIONS (-DVERSION="${VERSION}") ADD_DEFINITIONS (-DDATADIR="${CMAKE_INSTALL_PREFIX}/share") ADD_DEFINITIONS (-DBUILDTYPE="${CMAKE_BUILD_TYPE}") IF (${CMAKE_BUILD_TYPE} MATCHES "Debug") SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") ELSE (${CMAKE_BUILD_TYPE} NOT MATCHES "Debug") SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -Wno-deprecated-declarations") ENDIF (${CMAKE_BUILD_TYPE} MATCHES "Debug") INCLUDE_DIRECTORIES (. ${GTK_INCLUDE_DIRS} ${VTE_INCLUDE_DIRS}) LINK_DIRECTORIES (${GTK_LIBRARY_DIRS} ${VTE_LIBRARY_DIRS} ${X11_LIBRARY_DIRS}) LINK_LIBRARIES (${GTK_LIBRARIES} ${VTE_LIBRARIES} ${X11_LIBRARIES} m) ADD_EXECUTABLE (sakura src/sakura.c) ADD_SUBDIRECTORY (po) INSTALL (TARGETS sakura RUNTIME DESTINATION bin) INSTALL (FILES sakura.desktop DESTINATION share/applications) INSTALL (FILES terminal-tango.svg DESTINATION share/pixmaps) IF (POD2MAN) INSTALL (FILES ${sakura_BINARY_DIR}/sakura.1 DESTINATION share/man/man1) ENDIF (POD2MAN) INSTALL (FILES README.md DESTINATION share/doc/sakura) FILE (GLOB MO_FILES po/*.mo) SET_DIRECTORY_PROPERTIES (PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${MO_FILES};po/sakura.pot") SET (EXECUTABLE_OUTPUT_PATH src) ADD_CUSTOM_TARGET (distclean rm -f Makefile cmake_install.cmake CMakeCache.txt install_manifest.txt sakura.1 COMMAND rm -f po/*.mo po/sakura.pot po/Makefile po/cmake_install.cmake COMMAND rm -rf CMakeFiles po/CMakeFiles) IF (POD2MAN) ADD_CUSTOM_TARGET(man ALL COMMAND ${POD2MAN} -u --section=1 --release=${VERSION} --center '' ${sakura_SOURCE_DIR}/sakura.pod sakura.1) ENDIF (POD2MAN) ================================================ FILE: LICENSE ================================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. ================================================ FILE: README.md ================================================ [![Sponsor sakura!!](https://github.com/sponsors/dabisu/card)](https://github.com/sponsors/dabisu) # sakura **sakura** is a simple [gtk](http://www.gtk.org) and [vte](https://gitlab.gnome.org/GNOME/vte) based terminal emulator. It uses tabs to provide several terminals in one window and allows to change configuration options via a contextual menu. No more no less. ## Installation How to compile and install this beast ? ```bash $ cmake . $ make $ sudo make install ``` **sakura** now uses the CMake building system (RIP our old system MOBS, we'll remember you ;)). To install **sakura** with a different prefix, cmake needs to be invoked with the proper environment variables, so for example, to install sakura in `/usr`, you must type: ```bash $ cmake -DCMAKE_INSTALL_PREFIX=/usr . ``` Use CMAKE_BUILD_TYPE=Debug if you need debug symbols. Default type is "Release". Make sure your distribution sources the vte script for OSC 7 support in no login shells. If not, please add the following line to you .bashrc: ```bash . /etc/profile.d/vte-2.91.sh ``` ## Usage **sakura** has several command line options. Run `sakura --help` for a full list. ## Keybindings **sakura** supports keyboard bindings in its config file (`~/.config/sakura/sakura.conf`), but there's no GUI to edit them, so please use your favourite editor to change the following values. Keybindings are a combination of an accelerator+key. ### Accelerators Accelerators can be set to any _GdkModifierType_ mask value. The full list of _GdkModifierType_ values is available [here](http://gtk.php.net/manual/en/html/gdk/gdk.enum.modifiertype.html) Mask values can be combined by ORing them. For example, to set the delete tab accelerator to Ctrl+Shift, change the option "del_tab_accelerator" value to "5". This number comes from ORing GDK_SHIFT_MASK and GDK_CONTROL_MASK. I realise that this configuration is not user-friendly, but... :-P Quick reference: Shift(1), Cps-Lock(2), Ctrl(4), Alt(8), Ctrl-S(5), Ctrl-A(12), Ctrl-A-S(13) ### Keys To change default keys, set the key value you want to modify to your desired key. For example, if you want to use the "D" key instead of the "W" key to delete a tab, set "del_tab_key" to "D" in the config file. ### Default keybindings Ctrl + Shift + T -> New tab Ctrl + Shift + O -> New window Ctrl + Shift + W -> Close current tab Ctrl + Shift + C -> Copy selected text Ctrl + Shift + V -> Paste selected text Ctrl + Shift + N -> Set tab name Alt + Left cursor -> Previous tab Alt + Right cursor -> Next tab Alt + Shift + Left cursor -> Move tab to the left Alt + Shift + Right cursor -> Move tab to the right Ctrl + [1-9] -> Switch to tab N (1-9) Ctrl + Shift + S -> Toggle/Untoggle scrollbar Ctrl + Shift + Mouse left button -> Open link F11 -> Fullscreen Shift + PageUp -> Move up through scrollback by page Shift + PageDown -> Move down through scrollback by page Ctrl + Shift + Up -> Move up through scrollback by line Ctrl + Shift + Down -> Move down through scrollback by line Ctrl + Shift + [F1-F6] -> Select the colorset for the current tab You can also increase and decrease the font size in the GTK standard way: Ctrl + '+' -> Increase font size Ctrl + '-' -> Decrease font size By default, mouse buttons are bound to the following: Button1 -> No action Button2 -> Paste Button3 -> Context menu Behavior can be changed with the following config settings: copy_on_select -> set to true to automatically copy selected text paste_button -> set to desired mouse button (default: 2) menu_button -> set to desired mouse button (default: 3) ## Contributing Pull requests are welcome. But please, create first a bug report in [Launchpad](https://bugs.launchpad.net/sakura), particularly if you plan to make major changes, to make sure your patch will be merged into **sakura**. If you'd like to contribute with translations, use the translations framework in [Launchpad](https://translations.launchpad.net/sakura) or send [me](mailto:dabisu@gmail.com) directly the translated po file. ## License [GPL 2.0](https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) \ Enjoy **sakura**! ================================================ FILE: po/CMakeLists.txt ================================================ # Localization FIND_PROGRAM(XGETTEXT xgettext) FIND_PROGRAM(MSGFMT msgfmt) FIND_PROGRAM(MSGMERGE msgmerge) IF(NOT MSGFMT) MESSAGE( "------ NOTE: msgfmt not found. Translations will *not* be installed ------") ELSE(NOT MSGFMT) SET(catalogname sakura) FILE (GLOB PO_FILES *.po) FILE (GLOB SOURCES ../src/*.c) ADD_CUSTOM_TARGET(translations ALL) ADD_CUSTOM_COMMAND(TARGET translations COMMAND ${XGETTEXT} -o sakura.pot --keyword=_ --keyword=N_ --no-location --from-code=utf-8 ${SOURCES} DEPENDS ${_poFile}) FOREACH(_poFile ${PO_FILES}) GET_FILENAME_COMPONENT(_lang ${_poFile} NAME_WE) SET(_moFile ${_lang}.mo) ADD_CUSTOM_COMMAND(TARGET translations COMMAND ${MSGMERGE} -q -U ${_poFile} --backup=none sakura.pot COMMAND ${MSGFMT} --check -o ${_moFile} ${_poFile} DEPENDS ${_poFile}) INSTALL(FILES ${CMAKE_BINARY_DIR}/po/${_moFile} DESTINATION share/locale/${_lang}/LC_MESSAGES/ RENAME ${catalogname}.mo) ENDFOREACH(_poFile ${PO_FILES}) ENDIF(NOT MSGFMT) ================================================ FILE: po/POTFILES.in ================================================ src/sakura.c ================================================ FILE: po/ca.po ================================================ # Copyright (C) 2006 # This file is distributed under the same license as the sakura package. # David Gómez msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2019-09-30 05:43+0000\n" "Last-Translator: Adolfo Jayme \n" "Language-Team: Jordi Jané Cardo \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Imprimir el número de versió" msgid "Set window title" msgstr "Definir el nom de la finestra" msgid "Select initial terminal font" msgstr "Sel·leccionar el tipus de font inicial" msgid "Select initial number of tabs" msgstr "Sel·leccionar el número inicial de pestanyes" msgid "Set working directory" msgstr "Definir el directori actual" msgid "Execute command" msgstr "Executa l'ordre" msgid "Execute command (last option in the command line)" msgstr "" msgid "Login shell" msgstr "Entrada d'usuari en Shell" msgid "Set window icon" msgstr "Definir el nom de la icona" msgid "Set columns number" msgstr "Definir el nombre de columnes" msgid "Set rows number" msgstr "Definir el nombre de linies" msgid "Hold window after execute command" msgstr "Mantenir la finestra després de l'execució del comandament" msgid "Maximize window" msgstr "Maximitza la finestra" msgid "Fullscreen mode" msgstr "Pantalla complèta" msgid "Use alternate configuration file" msgstr "Utilitzeu un fitxer de configuració alternatiu" msgid "Select initial colorset" msgstr "Sel·leccionar grupo de colors inicial" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Hi ha processos executant-se.\n" "\n" "Realment desitgeu tancar Sakura?" msgid "Select font" msgstr "Sel·leccioni font" msgid "Set tab name" msgstr "" msgid "_Cancel" msgstr "_Cancel·la" msgid "_Apply" msgstr "_Aplica" msgid "New text" msgstr "Nou text" msgid "Select colors" msgstr "Sel·leccionar color" msgid "_Select" msgstr "_Selecciona" msgid "Colorset" msgstr "Grup de colors" msgid "Color scheme" msgstr "Esquema de colors" msgid "Foreground color" msgstr "Color de font" msgid "Background color" msgstr "Color de fons" msgid "Cursor color" msgstr "Color del cursor" msgid "Opacity level (%)" msgstr "Nivell d'opacitat (%)" msgid "Palette" msgstr "Paleta" msgid "Use bright colors for bold text" msgstr "Utilitzeu colors brillants per al text en negreta" msgid "New window title" msgstr "Definiu el nom de la finestra" msgid "Open mail" msgstr "Obrir correu" msgid "Open link" msgstr "Obrir enllaç" msgid "Copy link" msgstr "Copia enllaç" msgid "New tab" msgstr "Nova pestanya" msgid "Set tab name..." msgstr "Definir el nom de pestanya..." msgid "Close tab" msgstr "Tancar pestanya" msgid "Full screen" msgstr "Pantalla complèta" msgid "Copy" msgstr "Copiar" msgid "Paste" msgstr "Enganxar" msgid "Options" msgstr "Opcions" msgid "Select font..." msgstr "Sel·leccionar font..." msgid "Select colors..." msgstr "Sel·leccionar colors..." msgid "Show tab bar" msgstr "Mostra la barra de pestanyes" msgid "Always" msgstr "Sempre" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "" msgid "Tabs at bottom" msgstr "Pestanyes a la part baixa." msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Mostrar la barra de desplaçament" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Definir la senyal urgent" msgid "Set audible bell" msgstr "Definir la senyal acústica" msgid "Set blinking cursor" msgstr "Definir el cursor" msgid "Disable numbered tabswitch" msgstr "" msgid "Set cursor type" msgstr "Definir el tipus de cursor" msgid "Block" msgstr "Bloc" msgid "Underline" msgstr "Subratllat" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "Cerca" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "Hi ha processos en marxa en aquest terminal.\n" "\n" "Realment desitgeu tarncar-la?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "" msgid "Error message" msgstr "Missatge d'error" #, c-format msgid "Cannot change working directory\n" msgstr "No es pot cambiar el directori actual\n" msgid "- vte-based terminal emulator" msgstr "- emulador de terminal basat en libvte" #, c-format msgid "sakura version is %s\n" msgstr "La versió de sakura és %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Mostrar el botó de tancament de pestanya" #~ msgid "Enable focus fade" #~ msgstr "Activar atenuació de focus" ================================================ FILE: po/cs.po ================================================ # Czech translation of sakura. # Copyright (C) 2006 THE sakura'S COPYRIGHT HOLDER # This file is distributed under the same license as the sakura package. # Lucas Lommer , 2006, 2009, 2010. # msgid "" msgstr "" "Project-Id-Version: sakura 2.3.8\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-05-03 16:14+0000\n" "Last-Translator: David Gómez \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Vytiskne informaci o verzi" msgid "Set window title" msgstr "Nastaví titulek okna" msgid "Select initial terminal font" msgstr "Volba výchozího písma terminálu" msgid "Select initial number of tabs" msgstr "Výchozí počet karet" msgid "Set working directory" msgstr "Nastavit pracovní složku" msgid "Execute command" msgstr "Spustit příkaz" msgid "Execute command (last option in the command line)" msgstr "" msgid "Login shell" msgstr "Přihlašovací shell" msgid "Set window icon" msgstr "Nastavit ikonu okna" msgid "Set columns number" msgstr "Nastaví počet sloupců" msgid "Set rows number" msgstr "Nastaví počet řádek" msgid "Hold window after execute command" msgstr "Zachovat okno po vykonání příkazu" msgid "Maximize window" msgstr "Maximalizovat okno" msgid "Fullscreen mode" msgstr "Na celou obrazovku" msgid "Use alternate configuration file" msgstr "Použít alternativní soubor s nastaveními" msgid "Select initial colorset" msgstr "Vybrat počáteční sadu barev" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Aplikace obsahuje běžící procesy.\n" "\n" "Opravdu chcete ukončit aplikaci Sakura?" msgid "Select font" msgstr "Zvolte písmo" msgid "Set tab name" msgstr "Nastavit název panelu" msgid "_Cancel" msgstr "_Storno" msgid "_Apply" msgstr "_Použít" msgid "New text" msgstr "Nový text" msgid "Select colors" msgstr "Vybrat barvy" msgid "_Select" msgstr "_Vybrat" msgid "Colorset" msgstr "Barevné sada" msgid "Color scheme" msgstr "Barevné schéma" msgid "Foreground color" msgstr "Barva popředí" msgid "Background color" msgstr "Barva pozadí" msgid "Cursor color" msgstr "Barva kurzoru" msgid "Opacity level (%)" msgstr "Úroveň průhlednosti (%):" msgid "Palette" msgstr "Paletu" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "Název nového okna" msgid "Open mail" msgstr "Otevřít e-mail" msgid "Open link" msgstr "Otevřít odkaz" msgid "Copy link" msgstr "Zkopírovat odkaz" msgid "New tab" msgstr "Nová karta" msgid "Set tab name..." msgstr "Nastavit název panelu…" msgid "Close tab" msgstr "Zavřít kartu" msgid "Full screen" msgstr "Celá obrazovka" msgid "Copy" msgstr "Kopírovat" msgid "Paste" msgstr "Vložit" msgid "Options" msgstr "Volby" msgid "Select font..." msgstr "Zvolte písmo…" msgid "Select colors..." msgstr "Zvolte barvy…" msgid "Show tab bar" msgstr "Zobrazit lištu karet" msgid "Always" msgstr "Vždy" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "" msgid "Tabs at bottom" msgstr "Panely dole" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Zobrazit posuvník" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Nastavit naléhavý zvon" msgid "Set audible bell" msgstr "Nastavit akustické zvon" msgid "Set blinking cursor" msgstr "Nastavit blikající kurzor" msgid "Disable numbered tabswitch" msgstr "" msgid "Set cursor type" msgstr "Nastavit typ kurzoru" msgid "Block" msgstr "Blokový" msgid "Underline" msgstr "Podtržítko" msgid "IBeam" msgstr "Svislá čára" msgid "Search" msgstr "Hledat" #, c-format msgid "Terminal %d" msgstr "Terminál %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "V tomto terminálu běží proces.\n" "\n" "Opravdu jej chcete uzavřít?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "" msgid "Error message" msgstr "Chybové hlášení" #, c-format msgid "Cannot change working directory\n" msgstr "Nepodařilo se změnit pracovní složku\n" msgid "- vte-based terminal emulator" msgstr "- emulátor terminálu založený na VTE" #, c-format msgid "sakura version is %s\n" msgstr "sakura verze %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Zobrazovat na panelech zavírací tlačítko" ================================================ FILE: po/de.po ================================================ # German translation for Sakura. # Copyright (C) 2008 David Gómez # This file is distributed under the same license as the Sakura package. # Mario Blättermann , 2008. # Milo Ivir , 2020. # msgid "" msgstr "" "Project-Id-Version: Sakura 2.3.4\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2020-05-06 05:00+0000\n" "Last-Translator: Milo Ivir \n" "Language-Team: Deutsch \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Versionsnummer anzeigen" msgid "Set window title" msgstr "Fenstertitel wählen" msgid "Select initial terminal font" msgstr "Terminal-Schrift auswählen" msgid "Select initial number of tabs" msgstr "Anzahl der Reiter auswählen" msgid "Set working directory" msgstr "Arbeitsverzeichnis setzen" msgid "Execute command" msgstr "Befehl ausführen" msgid "Execute command (last option in the command line)" msgstr "Befehl ausführen (letzte Option in der Befehlszeile)" msgid "Login shell" msgstr "Login-Shell" msgid "Set window icon" msgstr "Fenstertitel-Symbol" msgid "Set columns number" msgstr "Spaltennummer wählen" msgid "Set rows number" msgstr "Zeilennummer wählen" msgid "Hold window after execute command" msgstr "Fenster nach Ausführen des Befehls nicht schließen" msgid "Maximize window" msgstr "Fenster miximieren" msgid "Fullscreen mode" msgstr "Vollbildmodus" msgid "Use alternate configuration file" msgstr "Benutze alternative Konfigurationsdatei" msgid "Select initial colorset" msgstr "Farbengruppe auswählen" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Es laufen noch Prozesse.\n" "\n" "Sakura wirklich beenden?" msgid "Select font" msgstr "Schrift auswählen" msgid "Set tab name" msgstr "Reiternamen setzen" msgid "_Cancel" msgstr "A_bbrechen" msgid "_Apply" msgstr "_Anwenden" msgid "New text" msgstr "Neuer Text" msgid "Select colors" msgstr "Farben auswählen" msgid "_Select" msgstr "A_uswählen" msgid "Colorset" msgstr "Farbengruppe" msgid "Color scheme" msgstr "Farbschema" msgid "Foreground color" msgstr "Vordergrundfarbe" msgid "Background color" msgstr "Hintergrundfarbe" msgid "Cursor color" msgstr "Cursorfarbe" msgid "Opacity level (%)" msgstr "Opazitätsgrad (%)" msgid "Palette" msgstr "Palette" msgid "Use bright colors for bold text" msgstr "Verwenden Sie helle Farben für fetten Text" msgid "New window title" msgstr "Fenstertitel wählen" msgid "Open mail" msgstr "E-Mail öffnen" msgid "Open link" msgstr "Verweis öffnen" msgid "Copy link" msgstr "Verweis kopieren" msgid "New tab" msgstr "Neuer Reiter" msgid "Set tab name..." msgstr "Reiternamen setzen …" msgid "Close tab" msgstr "Reiter schließen" msgid "Full screen" msgstr "Vollbild" msgid "Copy" msgstr "Kopieren" msgid "Paste" msgstr "Einfügen" msgid "Options" msgstr "Optionen" msgid "Select font..." msgstr "Schrift auswählen …" msgid "Select colors..." msgstr "Farben auswählen …" msgid "Show tab bar" msgstr "Reiterleiste anzeigen" msgid "Always" msgstr "Immer" msgid "When there's more than one tab" msgstr "Wenn es mehrere sind" msgid "Never" msgstr "Niemals" msgid "Tabs at bottom" msgstr "Reiter unten" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Bildlaufleiste anzeigen" msgid "Fewer questions at exit time" msgstr "Weniger Fragen bei Beenden des Programms" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Dringender Alarm" msgid "Set audible bell" msgstr "Hörbarer Alarm" msgid "Set blinking cursor" msgstr "Blinkender Cursor" msgid "Disable numbered tabswitch" msgstr "Den Umschalter für nummerierte Reiter deaktivieren" msgid "Set cursor type" msgstr "Cusror-Art setzen" msgid "Block" msgstr "Rechteck" msgid "Underline" msgstr "Unterstreichen" msgid "IBeam" msgstr "Senkrechter Strich" msgid "Search" msgstr "Suchen" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "In diesem Terminal läuft noch ein Prozess.\n" "\n" "Soll er wirklich beendet werden?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "" "Die Konfiguration wurde durch einen anderen Prozess geändert. Šberschreiben?" msgid "Error message" msgstr "Fehlermeldung" #, c-format msgid "Cannot change working directory\n" msgstr "Das Arbeitsverzeichnis kann nicht verändert serden\n" msgid "- vte-based terminal emulator" msgstr "- vte-basierter Terminal-Emulator" #, c-format msgid "sakura version is %s\n" msgstr "Sakura-Version ist %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Schließen-Knopf auf Reitern anzeigen" #~ msgid "Enable focus fade" #~ msgstr "Langsames Einblenden aktivieren" ================================================ FILE: po/en_GB.po ================================================ # English (United Kingdom) translation for sakura # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the sakura package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2019-08-12 16:54+0000\n" "Last-Translator: David Gómez \n" "Language-Team: English (United Kingdom) \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Print version number" msgid "Set window title" msgstr "Set window title" msgid "Select initial terminal font" msgstr "Select initial terminal font" msgid "Select initial number of tabs" msgstr "Select initial number of tabs" msgid "Set working directory" msgstr "Set working directory" msgid "Execute command" msgstr "Execute command" msgid "Execute command (last option in the command line)" msgstr "Execute command (last option in the command line)" msgid "Login shell" msgstr "Login shell" msgid "Set window icon" msgstr "Set window icon" msgid "Set columns number" msgstr "Set columns number" msgid "Set rows number" msgstr "Set rows number" msgid "Hold window after execute command" msgstr "Hold window after execute command" msgid "Maximize window" msgstr "Maximise window" msgid "Fullscreen mode" msgstr "Full screen mode" msgid "Use alternate configuration file" msgstr "Use alternate configuration file" msgid "Select initial colorset" msgstr "Select initial colourset" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgid "Select font" msgstr "Select font" msgid "Set tab name" msgstr "Set tab name" msgid "_Cancel" msgstr "_Cancel" msgid "_Apply" msgstr "_Apply" msgid "New text" msgstr "New text" msgid "Select colors" msgstr "Select colours" msgid "_Select" msgstr "_Select" msgid "Colorset" msgstr "Colourset" msgid "Color scheme" msgstr "Colour scheme" msgid "Foreground color" msgstr "Foreground colour" msgid "Background color" msgstr "Background colour" msgid "Cursor color" msgstr "Cursor colour" msgid "Opacity level (%)" msgstr "Opacity level (%)" msgid "Palette" msgstr "Palette" msgid "Use bright colors for bold text" msgstr "Use bright colours for bold text" msgid "New window title" msgstr "New window title" msgid "Open mail" msgstr "Open mail" msgid "Open link" msgstr "Open link" msgid "Copy link" msgstr "Copy link" msgid "New tab" msgstr "New tab" msgid "Set tab name..." msgstr "Set tab name..." msgid "Close tab" msgstr "Close tab" msgid "Full screen" msgstr "Full screen" msgid "Copy" msgstr "Copy" msgid "Paste" msgstr "Paste" msgid "Options" msgstr "Options" msgid "Select font..." msgstr "Select font..." msgid "Select colors..." msgstr "Select colours..." msgid "Show tab bar" msgstr "Show tab bar" msgid "Always" msgstr "Always" msgid "When there's more than one tab" msgstr "When there's more than one tab" msgid "Never" msgstr "Never" msgid "Tabs at bottom" msgstr "Tabs at bottom" msgid "New tab after current tab" msgstr "New tab after current tab" msgid "Show scrollbar" msgstr "Show scrollbar" msgid "Fewer questions at exit time" msgstr "Fewer questions at exit time" msgid "Automatically copy selected text" msgstr "Automatically copy selected text" msgid "Set urgent bell" msgstr "Set urgent bell" msgid "Set audible bell" msgstr "Set audible bell" msgid "Set blinking cursor" msgstr "Set blinking cursor" msgid "Disable numbered tabswitch" msgstr "Disable numbered tabswitch" msgid "Set cursor type" msgstr "Set cursor type" msgid "Block" msgstr "Block" msgid "Underline" msgstr "Underline" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "Search" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "Configuration has been modified by another process. Overwrite?" msgid "Error message" msgstr "Error message" #, c-format msgid "Cannot change working directory\n" msgstr "Cannot change working directory\n" msgid "- vte-based terminal emulator" msgstr "- vte-based terminal emulator" #, c-format msgid "sakura version is %s\n" msgstr "sakura version is %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Show close button on tabs" #~ msgid "Enable focus fade" #~ msgstr "Enable focus fade" ================================================ FILE: po/es.po ================================================ # Copyright (C) 2006 # This file is distributed under the same license as the sakura package. # David Gómez msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2019-08-12 16:53+0000\n" "Last-Translator: David Gómez \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Imprimir número de versión" msgid "Set window title" msgstr "Establecer nombre de ventana" msgid "Select initial terminal font" msgstr "Seleccionar el tipo de fuente inicial" msgid "Select initial number of tabs" msgstr "Seleccionar el número inicial de pestañas" msgid "Set working directory" msgstr "Establecer directorio actual" msgid "Execute command" msgstr "Ejecutar orden" msgid "Execute command (last option in the command line)" msgstr "Ejecutar comando (última opción en la linea de comandos)" msgid "Login shell" msgstr "Shell de login" msgid "Set window icon" msgstr "Establecer icono de ventana" msgid "Set columns number" msgstr "Establecer número de columnas" msgid "Set rows number" msgstr "Establecer número de líneas" msgid "Hold window after execute command" msgstr "Mantener la ventana tras el final del comando" msgid "Maximize window" msgstr "Maximizar ventana" msgid "Fullscreen mode" msgstr "Modo de pantalla completa" msgid "Use alternate configuration file" msgstr "Usar fichero de configuración alternativo" msgid "Select initial colorset" msgstr "Seleccionar grupo de colores inicial" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Hay procesos en ejecución.\n" "\n" "¿Confirma que quiere cerrar Sakura?" msgid "Select font" msgstr "Seleccionar tipo de letra" msgid "Set tab name" msgstr "Establecer nombre de pestaña" msgid "_Cancel" msgstr "_Cancelar" msgid "_Apply" msgstr "_Aplicar" msgid "New text" msgstr "Texto nuevo" msgid "Select colors" msgstr "Seleccionar colores" msgid "_Select" msgstr "_Seleccionar" msgid "Colorset" msgstr "Grupo de colores" msgid "Color scheme" msgstr "Esquema de colores" msgid "Foreground color" msgstr "Color de primer plano" msgid "Background color" msgstr "Color de fondo" msgid "Cursor color" msgstr "Color del cursor" msgid "Opacity level (%)" msgstr "Nivel de opacidad (%)" msgid "Palette" msgstr "Paleta" msgid "Use bright colors for bold text" msgstr "Usar colores brillantes para texto en negrita" msgid "New window title" msgstr "Título nuevo de la ventana" msgid "Open mail" msgstr "Abrir correo" msgid "Open link" msgstr "Abrir enlace" msgid "Copy link" msgstr "Copiar enlace" msgid "New tab" msgstr "Pestaña nueva" msgid "Set tab name..." msgstr "Establecer nombre de pestaña..." msgid "Close tab" msgstr "Cerrar pestaña" msgid "Full screen" msgstr "Pantalla completa" msgid "Copy" msgstr "Copiar" msgid "Paste" msgstr "Pegar" msgid "Options" msgstr "Opciones" msgid "Select font..." msgstr "Seleccionar tipo de letra…" msgid "Select colors..." msgstr "Seleccionar colores..." msgid "Show tab bar" msgstr "Mostrar la barra de pestañas" msgid "Always" msgstr "Siempre" msgid "When there's more than one tab" msgstr "Cuando hay más de una pestaña" msgid "Never" msgstr "Nunca" msgid "Tabs at bottom" msgstr "Pestañas en la parte inferior" msgid "New tab after current tab" msgstr "Nueva pestaña tras la pestaña actual" msgid "Show scrollbar" msgstr "Mostrar barra de desplazamiento" msgid "Fewer questions at exit time" msgstr "Menos preguntas al cerrar" msgid "Automatically copy selected text" msgstr "Copiar automáticamente el texto seleccionado" msgid "Set urgent bell" msgstr "Activar campana de urgencia" msgid "Set audible bell" msgstr "Activar campana audible" msgid "Set blinking cursor" msgstr "Activar parpadeo del cursor" msgid "Disable numbered tabswitch" msgstr "Desactivar números para cambio de pestañas" msgid "Set cursor type" msgstr "Establecer tipo de cursor" msgid "Block" msgstr "Bloque" msgid "Underline" msgstr "Subrayado" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "Buscar" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "Hay procesos en ejecución en este terminal.\n" "\n" "¿Confirma que quiere cerrarlo?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "La configuración ha sido modificada por otro proceso. ¿Sobreescribir?" msgid "Error message" msgstr "Mensaje de error" #, c-format msgid "Cannot change working directory\n" msgstr "No se puede cambiar el directorio actual\n" msgid "- vte-based terminal emulator" msgstr "- emulador de terminal basado en libvte" #, c-format msgid "sakura version is %s\n" msgstr "La versión de sakura es %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Mostrar botón de cerrar en las pestañas" #~ msgid "Enable focus fade" #~ msgstr "Activar atenuación de foco" ================================================ FILE: po/fr.po ================================================ # This file is distributed under the same license as the sakura package. # Fabrice Thiroux , 2008. # # msgid "" msgstr "" "Project-Id-Version: sakura 1.2.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: David Gómez \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Afficher le numéro de version" msgid "Set window title" msgstr "Définir le titre de la fenêtre" msgid "Select initial terminal font" msgstr "Sélectionner la police de caractères à utiliser au démarrage" msgid "Select initial number of tabs" msgstr "Sélectionner le nombre d'onglets au démarrage" msgid "Set working directory" msgstr "Définir le répertoire de travail" msgid "Execute command" msgstr "Exécuter une commande" msgid "Execute command (last option in the command line)" msgstr "Exécuter une commande (dernière option sur la ligne de commande)" msgid "Login shell" msgstr "Shell de connexion" msgid "Set window icon" msgstr "Définir l'icône de fenêtre" msgid "Set columns number" msgstr "Définir le nombre de colonnes" msgid "Set rows number" msgstr "Définir le nombre de lignes" msgid "Hold window after execute command" msgstr "Conserver la fenêtre après l'exécution d'une commande" msgid "Maximize window" msgstr "Agrandir la fenêtre" msgid "Fullscreen mode" msgstr "Mode plein écran" msgid "Use alternate configuration file" msgstr "Utiliser un fichier de configuration alternatif" msgid "Select initial colorset" msgstr "Sélectionner le jeu de couleurs initial" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Il y a des processus actifs dans ce terminal.\n" "\n" "Voulez-vous vraiment le fermer ?" msgid "Select font" msgstr "Sélectionner une police de caractères" msgid "Set tab name" msgstr "Définir le titre de l'onglet" msgid "_Cancel" msgstr "Ann_uler" msgid "_Apply" msgstr "_Appliquer" msgid "New text" msgstr "Nouveau texte" msgid "Select colors" msgstr "Sélectionner les couleurs" msgid "_Select" msgstr "_Sélectionner" msgid "Colorset" msgstr "Jeu de couleurs" msgid "Color scheme" msgstr "Schéma de couleur" msgid "Foreground color" msgstr "Couleur d'avant plan" msgid "Background color" msgstr "Couleur d'arrière-plan" msgid "Cursor color" msgstr "Couleur du curseur" msgid "Opacity level (%)" msgstr "Niveau d'opacité (%)" msgid "Palette" msgstr "Palette" msgid "Use bright colors for bold text" msgstr "Utilisez des couleurs vives pour le text en gras" msgid "New window title" msgstr "Définir le titre de la fenêtre" msgid "Open mail" msgstr "Ouvrir le courrier" msgid "Open link" msgstr "Ouvrir le lien" msgid "Copy link" msgstr "Copier le lien" msgid "New tab" msgstr "Nouvel onglet" msgid "Set tab name..." msgstr "Définir le titre de l'onglet..." msgid "Close tab" msgstr "Fermer l'onglet" msgid "Full screen" msgstr "Plein écran" msgid "Copy" msgstr "Copier" msgid "Paste" msgstr "Coller" msgid "Options" msgstr "Options" msgid "Select font..." msgstr "Sélectionner la police de caractères..." msgid "Select colors..." msgstr "Sélectionner les couleurs..." msgid "Show tab bar" msgstr "Afficher la barre d'onglets" msgid "Always" msgstr "Toujours " msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "Rien" msgid "Tabs at bottom" msgstr "Onglets en bas" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Afficher la barre de défilement" msgid "Fewer questions at exit time" msgstr "Moins de questions au moment de la sortie" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Définir un avertissement d'urgence" msgid "Set audible bell" msgstr "Définir un avertissement audio" msgid "Set blinking cursor" msgstr "Définir un curseur clignotant" msgid "Disable numbered tabswitch" msgstr "Désactiver les nombres pour le changement d'onglet" msgid "Set cursor type" msgstr "Définir le type de curseur" msgid "Block" msgstr "Bloc" msgid "Underline" msgstr "Souligner" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "Chercher" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "Il y a un processus actif dans ce terminal.\n" "\n" "Voulez-vous vraiment le fermer ?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "La configuration a été modifié par un autre processus. L'écraser ?" msgid "Error message" msgstr "Message d'erreur" #, c-format msgid "Cannot change working directory\n" msgstr "Impossible de changer le répertoire de travail\n" msgid "- vte-based terminal emulator" msgstr "Émulateur de terminal utilisant VTE" #, c-format msgid "sakura version is %s\n" msgstr "Sakura version %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Afficher le bouton fermer sur les onglets" #~ msgid "Enable focus fade" #~ msgstr "Activer le fondu de la mise au point" ================================================ FILE: po/he.po ================================================ # Hebrew translation for Sakura. # Copyright (C) 2008 David Gómez # This file is distributed under the same license as the sakura package. # Isratine Citizen , 2012. # msgid "" msgstr "" "Project-Id-Version: sakura 3.1.4\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: David Gómez \n" "Language-Team: Rahut \n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" "X-Language: he\n" "X-Source-Language: en\n" "X-Poedit-Language: Hebrew\n" # CLI: Do not translate! msgid "Print version number" msgstr "Print version number" # CLI: Do not translate! msgid "Set window title" msgstr "Set window title" # CLI: Do not translate! msgid "Select initial terminal font" msgstr "Select initial terminal font" # CLI: Do not translate! msgid "Select initial number of tabs" msgstr "Select initial number of tabs" # CLI: Do not translate! msgid "Set working directory" msgstr "Set working directory" # CLI: Do not translate! msgid "Execute command" msgstr "Execute command" # CLI: Do not translate! msgid "Execute command (last option in the command line)" msgstr "Execute command (last option in the command line)" # CLI: Do not translate! msgid "Login shell" msgstr "Login shell" # CLI: Do not translate! #, fuzzy msgid "Set window icon" msgstr "Set window title" # CLI: Do not translate! msgid "Set columns number" msgstr "Set columns number" # CLI: Do not translate! msgid "Set rows number" msgstr "Set rows number" # CLI: Do not translate! msgid "Hold window after execute command" msgstr "Hold window after execute command" # CLI: Do not translate! msgid "Maximize window" msgstr "Maximize window" # CLI: Do not translate! msgid "Fullscreen mode" msgstr "Fullscreen mode" # CLI: Do not translate! msgid "Use alternate configuration file" msgstr "Use alternate configuration file" #, fuzzy msgid "Select initial colorset" msgstr "בחר צבע" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "קיימים תהליכים אשר כעת מורצים.\n" "\n" "האם אתה בטוח כי ברצונך לסגור את Sakura?" msgid "Select font" msgstr "בחירת גופן" msgid "Set tab name" msgstr "קביעת שם כרטיסייה" msgid "_Cancel" msgstr "_ביטול" msgid "_Apply" msgstr "_החל" msgid "New text" msgstr "תמליל חדש" #, fuzzy msgid "Select colors" msgstr "בחר צבע" msgid "_Select" msgstr "ב_חר" #, fuzzy msgid "Colorset" msgstr "חוג צבעים לעריכה" #, fuzzy msgid "Color scheme" msgstr "חוג צבעים לעריכה" msgid "Foreground color" msgstr "צבע קדמה" msgid "Background color" msgstr "צבע רקע" msgid "Cursor color" msgstr "צבע סמן" msgid "Opacity level (%)" msgstr "רמת העמימות (%)" msgid "Palette" msgstr "לוח צבעים" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "כותרת חלון חדשה" #, fuzzy msgid "Open mail" msgstr "פתח קישור" msgid "Open link" msgstr "פתח קישור" msgid "Copy link" msgstr "העתק קישור" msgid "New tab" msgstr "כרטיסייה חדשה" msgid "Set tab name..." msgstr "קבע שם כרטיסייה..." msgid "Close tab" msgstr "סגור כרטיסייה" msgid "Full screen" msgstr "מסך מלא" msgid "Copy" msgstr "העתק" msgid "Paste" msgstr "הדבק" msgid "Options" msgstr "אפשרויות" msgid "Select font..." msgstr "בחר גופן..." msgid "Select colors..." msgstr "בחר צבעים..." # msgstr "הצג תמיד סרגל כרטיסיות" msgid "Show tab bar" msgstr "" msgid "Always" msgstr "" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "" msgid "Tabs at bottom" msgstr "כרטיסיות בתחתית" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "הצג פס גלילה" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" #, fuzzy msgid "Set urgent bell" msgstr "קבע פעמון שמיע" msgid "Set audible bell" msgstr "קבע פעמון שמיע" msgid "Set blinking cursor" msgstr "קבע סמן מהבהב" msgid "Disable numbered tabswitch" msgstr "" msgid "Set cursor type" msgstr "קבע טיפוס סמן" msgid "Block" msgstr "קטע" msgid "Underline" msgstr "קו תחתון" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "" #, c-format msgid "Terminal %d" msgstr "מסוף %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "קיים תהליך אשר כעת מורץ בתוך מסוף זה.\n" "\n" "האם אתה בטוח כי ברצונך לסגור אותו?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "תצורה השתנתה על ידי תהליך אחר. להחליפו?" msgid "Error message" msgstr "הודעת שגיאה" #, c-format msgid "Cannot change working directory\n" msgstr "אין אפשרות לשנות מדור עבודה\n" # CLI: Do not translate! # - אמולטור מסוף מבוסס vte msgid "- vte-based terminal emulator" msgstr "- vte-based terminal emulator" # CLI: Do not translate! #, c-format msgid "sakura version is %s\n" msgstr "sakura version is %s\n" #~ msgid "Show close button on tabs" #~ msgstr "הצג לחצן סגירה על כרטיסיות" ================================================ FILE: po/hr.po ================================================ # Croatian translation for Sakura. # Copyright (C) 2008 David Gómez # This file is distributed under the same license as the Sakura package. # gogo , 2018. # Milo Ivir , 2020. # msgid "" msgstr "" "Project-Id-Version: Sakura 2.3.4\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2020-05-06 05:00+0000\n" "Last-Translator: Milo Ivir \n" "Language-Team: \n" "Language: hr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Ispiši broj verzije" msgid "Set window title" msgstr "Postavi naslov prozora" msgid "Select initial terminal font" msgstr "Odaberi font terminala" msgid "Select initial number of tabs" msgstr "Odaberi broj kartica" msgid "Set working directory" msgstr "Postavi radnu mapu" msgid "Execute command" msgstr "Izvrši naredbu" msgid "Execute command (last option in the command line)" msgstr "Izvrši naredbu (zadnja opcija u naredbenom retku)" msgid "Login shell" msgstr "Ljuska prijave" msgid "Set window icon" msgstr "Postavi ikonu prozora" msgid "Set columns number" msgstr "Postavi broj stupaca" msgid "Set rows number" msgstr "Postavi broj redaka" msgid "Hold window after execute command" msgstr "Zadrži prozor nakon izvršavanja naredbe" msgid "Maximize window" msgstr "Raširi prozor maksimalno" msgid "Fullscreen mode" msgstr "Cjeloekranski prikaz" msgid "Use alternate configuration file" msgstr "Koristi alternativnu konfiguracijsku datoteku" msgid "Select initial colorset" msgstr "Odaberi skup boja" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Postoje aktivni procesi.\n" "\n" "Stvarno zatvoriti Sakura?" msgid "Select font" msgstr "Odaberi font" msgid "Set tab name" msgstr "Postavi ime kartice" msgid "_Cancel" msgstr "_Odustani" msgid "_Apply" msgstr "_Primijeni" msgid "New text" msgstr "Novi tekst" msgid "Select colors" msgstr "Odaberi boje" msgid "_Select" msgstr "_Odaberi" msgid "Colorset" msgstr "Skup boja" msgid "Color scheme" msgstr "Shema boja" msgid "Foreground color" msgstr "Prednja boja" msgid "Background color" msgstr "Stražnja boja" msgid "Cursor color" msgstr "Boja pokazivača" msgid "Opacity level (%)" msgstr "Razina neporozirnosti (%)" msgid "Palette" msgstr "Paleta" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "Naslov novog prozora" msgid "Open mail" msgstr "Otvori e-poštu" msgid "Open link" msgstr "Otvori poveznicu" msgid "Copy link" msgstr "Kopiraj poveznicu" msgid "New tab" msgstr "Nova kartica" msgid "Set tab name..." msgstr "Postavi ime kartice …" msgid "Close tab" msgstr "Zatvori karticu" msgid "Full screen" msgstr "Cjeloekranski prikaz" msgid "Copy" msgstr "Kopiraj" msgid "Paste" msgstr "Paste" msgid "Options" msgstr "Mogućnosti" msgid "Select font..." msgstr "Odaberi font …" msgid "Select colors..." msgstr "Odaberi boje …" msgid "Show tab bar" msgstr "Prikaži traku s karticama" msgid "Always" msgstr "Uvijek" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "" msgid "Tabs at bottom" msgstr "Kartice dolje" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Prikaži kliznu traku" msgid "Fewer questions at exit time" msgstr "Manje pitanja pri zatvaranju programa" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Postavi hitno zvono" msgid "Set audible bell" msgstr "Postavi zvučno zvono" msgid "Set blinking cursor" msgstr "Postavi treperenje pokazivača" msgid "Disable numbered tabswitch" msgstr "Deaktiviraj prekidač numeriranih kartica" msgid "Set cursor type" msgstr "Postavi vrstu pokazivača" msgid "Block" msgstr "Pravokutnik" msgid "Underline" msgstr "Podvučeno" msgid "IBeam" msgstr "Okomita crta" msgid "Search" msgstr "Traži" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "U ovom terminalu postoji jedan aktivan proces.\n" "\n" "Stvarno zatvoriti terminal?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "Jedan drugi proces je promijenio konfiguraciju. Prepisati?" msgid "Error message" msgstr "Poruka greške" #, c-format msgid "Cannot change working directory\n" msgstr "Radna mapa se ne može promijeniti\n" msgid "- vte-based terminal emulator" msgstr "- emulator terminala temeljen na vte-u" #, c-format msgid "sakura version is %s\n" msgstr "sakura verzija je %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Prikaži gumb zatvaranja na karticama" #~ msgid "Enable focus fade" #~ msgstr "Aktiviraj postupni prijelaz" #~ msgid "More" #~ msgstr "Više" #~ msgid "Set window title..." #~ msgstr "Postavi naslov prozora …" #~ msgid "Stop tab cycling at end tabs" #~ msgstr "Zaustavi prelaženje na kartice pomoću tabulatora na zadnjoj kartici" #~ msgid "Enable bold font" #~ msgstr "Dozvoli podebljani font" #~ msgid "X geometry specification" #~ msgstr "Specifikacija X-geometrije" #~ msgid "Configuration has been modified. Save?" #~ msgstr "Konfiguracija je promijenjena. Spremiti?" #~ msgid "Don't show exit dialog" #~ msgstr "Ne prikazuj dijalog za zatvaranje programa" #~ msgid "Use focus fading" #~ msgstr "Koristi postupan prijelaz fokusa" ================================================ FILE: po/hu.po ================================================ # Copyright (C) 2006 # This file is distributed under the same license as the sakura package. # David Gómez msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: David Gómez \n" "Language-Team: hu\n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Verziószám kiírása" msgid "Set window title" msgstr "Ablak címének beállítása" msgid "Select initial terminal font" msgstr "Alapértelmezett terminál font beállítása" msgid "Select initial number of tabs" msgstr "Fülek alapértelmezett számának beállítása" msgid "Set working directory" msgstr "Munkakönyvtár beállítása" msgid "Execute command" msgstr "Parancs végrehajtása" msgid "Execute command (last option in the command line)" msgstr "Parancs végrehajtása (utolsó opció a parancssorban)" msgid "Login shell" msgstr "Bejelentkező shell" msgid "Set window icon" msgstr "Ablak ikonjának beállítása" msgid "Set columns number" msgstr "Oszlopok számának beállítása" msgid "Set rows number" msgstr "Sorok számának beállítása" msgid "Hold window after execute command" msgstr "Ablak megtartása a parancs végrehajtása után" msgid "Maximize window" msgstr "Ablak maximalizálása" msgid "Fullscreen mode" msgstr "Teljes képernyős mód" msgid "Use alternate configuration file" msgstr "Alternatív konfigurációs fájl beállítása" msgid "Select initial colorset" msgstr "Alapértelmezett színek beállítása" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Még van futó folyamat.\n" "\n" "Valóban be akarja zárni a Sakura-t?" msgid "Select font" msgstr "Betűkészlet kiválasztása" msgid "Set tab name" msgstr "Fül nevének beállítása" msgid "_Cancel" msgstr "_Mégse" msgid "_Apply" msgstr "_Alkalmaz" msgid "New text" msgstr "Új szöveg" msgid "Select colors" msgstr "Színek kiválasztása" msgid "_Select" msgstr "_Kiválasztás" msgid "Colorset" msgstr "Színek" #, fuzzy msgid "Color scheme" msgstr "Színek" msgid "Foreground color" msgstr "Előtér színe" msgid "Background color" msgstr "Háttér színe" msgid "Cursor color" msgstr "Kurzor színe" msgid "Opacity level (%)" msgstr "Átlátszóság mértéke (%)" #, fuzzy msgid "Palette" msgstr "Paletta beállítása" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "Új ablakcím" #, fuzzy msgid "Open mail" msgstr "Link megnyitása" msgid "Open link" msgstr "Link megnyitása" msgid "Copy link" msgstr "Link másolása" msgid "New tab" msgstr "Új fül" msgid "Set tab name..." msgstr "Fül nevének beállítása..." msgid "Close tab" msgstr "Lap bezárása" msgid "Full screen" msgstr "Teljes képernyő" msgid "Copy" msgstr "Másolás" msgid "Paste" msgstr "Beillesztés" msgid "Options" msgstr "Beállítások" msgid "Select font..." msgstr "Betűkészlet kiválasztása..." msgid "Select colors..." msgstr "Színek kiválasztása..." msgid "Show tab bar" msgstr "Jelenjen meg a fülsáv" msgid "Always" msgstr "Mindig" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "" msgid "Tabs at bottom" msgstr "Fülek alul" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Görgetősáv megjelenítése" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Sürgős jelzés beállítása" msgid "Set audible bell" msgstr "Hang lejátszása" msgid "Set blinking cursor" msgstr "Villogó kurzor beállítása" msgid "Disable numbered tabswitch" msgstr "Gyorsbillentyűs fülváltás tiltása" msgid "Set cursor type" msgstr "Kurzor típusának beállítása" msgid "Block" msgstr "Blokk" msgid "Underline" msgstr "Aláhúzás" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "" #, c-format msgid "Terminal %d" msgstr "Terminál %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "A terminálban még van futó folyamat.\n" "\n" "Valóban be akarja zárni?" #, fuzzy msgid "Configuration has been modified by another process. Overwrite?" msgstr "A konfigurációt egy másik folyamat módosította. Felülírja?" msgid "Error message" msgstr "Hibaüzenet" #, c-format msgid "Cannot change working directory\n" msgstr "A munkakönyvtár nem módosítható\n" msgid "- vte-based terminal emulator" msgstr "- vte alapú terminálemulátor" #, c-format msgid "sakura version is %s\n" msgstr "sakura verzió: %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Bezárás gomb megjelenítése a füleken" #, fuzzy #~ msgid "Enable focus fade" #~ msgstr "Vastag betű engedélyezése" ================================================ FILE: po/it.po ================================================ # Copyright (C) 2006 # This file is distributed under the same license as the sakura package. # Fontana Nicola msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: David Gómez \n" "Language-Team: sakura-it \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" "X-Poedit-Country: ITALY\n" "X-Poedit-Language: Italian\n" "X-Poedit-SourceCharset: utf-8\n" msgid "Print version number" msgstr "Stampa il numero di versione" msgid "Set window title" msgstr "Imposta il titolo della finestra" msgid "Select initial terminal font" msgstr "Seleziona il font iniziale" msgid "Select initial number of tabs" msgstr "Seleziona il numero di schede iniziali" msgid "Set working directory" msgstr "Imposta la directory di lavoro" msgid "Execute command" msgstr "Esegui il comando" msgid "Execute command (last option in the command line)" msgstr "Esegui il comando (l'ultima scelta nella riga di comando)" msgid "Login shell" msgstr "Shell di login" msgid "Set window icon" msgstr "Imposta l'icona della finestra" msgid "Set columns number" msgstr "Imposta il numero di colonne" msgid "Set rows number" msgstr "Imposta il numero di righe" msgid "Hold window after execute command" msgstr "Blocca la finestra dopo l'esecuzione di un comando" msgid "Maximize window" msgstr "Massimizza finestra" msgid "Fullscreen mode" msgstr "Modalità a schermo intero" msgid "Use alternate configuration file" msgstr "Usa un file di configurazione alternativo" msgid "Select initial colorset" msgstr "Seleziona insieme iniziale di colori" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Ci sono dei processi in esecuzione.\n" "\n" "Vuoi davvero chiudere Sakura?" msgid "Select font" msgstr "Seleziona il font" msgid "Set tab name" msgstr "Imposta il nome della scheda" msgid "_Cancel" msgstr "_Annulla" msgid "_Apply" msgstr "_Applica" msgid "New text" msgstr "Nuovo testo" msgid "Select colors" msgstr "Seleziona i colori" msgid "_Select" msgstr "_Seleziona" msgid "Colorset" msgstr "Insieme di colori" msgid "Color scheme" msgstr "Schema di colori" msgid "Foreground color" msgstr "Colore del testo" msgid "Background color" msgstr "Colore dello sfondo" msgid "Cursor color" msgstr "Colore del cursore" msgid "Opacity level (%)" msgstr "Livello di opacità (%)" msgid "Palette" msgstr "Tavolozza" msgid "Use bright colors for bold text" msgstr "Usa colori vivaci per il testo in grassetto" msgid "New window title" msgstr "Nuovo titolo della finestra" msgid "Open mail" msgstr "Apri posta" msgid "Open link" msgstr "Apri collegamento" msgid "Copy link" msgstr "Copia collegamento" msgid "New tab" msgstr "Nuova scheda" msgid "Set tab name..." msgstr "Imposta il nome di la scheda" msgid "Close tab" msgstr "Chiudi la scheda" msgid "Full screen" msgstr "Schermo intero" msgid "Copy" msgstr "Copia" msgid "Paste" msgstr "Incolla" msgid "Options" msgstr "Opzioni" msgid "Select font..." msgstr "Seleziona il font..." msgid "Select colors..." msgstr "Seleziona i colori..." msgid "Show tab bar" msgstr "Mostra la barra delle schede" msgid "Always" msgstr "Sempre" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "" msgid "Tabs at bottom" msgstr "Schede in basso" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Visualizza la barra di scorrimento" msgid "Fewer questions at exit time" msgstr "Meno domande al momento dell'uscita" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Imposta l'avviso urgente" msgid "Set audible bell" msgstr "Imposta l'avviso acustico" msgid "Set blinking cursor" msgstr "Imposta il cursore lampeggiante" msgid "Disable numbered tabswitch" msgstr "Disabilitare i numeri per cambiare scheda" msgid "Set cursor type" msgstr "Imposta il modello di cursore" msgid "Block" msgstr "Blocco" msgid "Underline" msgstr "Sottolineato" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "Ricerca" #, c-format msgid "Terminal %d" msgstr "Terminale %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "C'è un processo in esecuzione in questo terminale.\n" "\n" "Vuoi davvero chiudere Sakura?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "" "La configurazione è stata modificata da un altro processo. Sovrascrivere?" msgid "Error message" msgstr "Messaggio d'errore" #, c-format msgid "Cannot change working directory\n" msgstr "Non è possibile modificare la directory di lavoro\n" msgid "- vte-based terminal emulator" msgstr "- emulatore di terminale basato su VTE" #, c-format msgid "sakura version is %s\n" msgstr "La versione di sakura è %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Mostra il pulsante di chiusura sulle schede" #~ msgid "Enable focus fade" #~ msgstr "Abilitare il dimmer della messa a fuoco" ================================================ FILE: po/ja.po ================================================ # translation of ja.po to Japanese # UTUMI Hirosi , 2006, 2008. msgid "" msgstr "" "Project-Id-Version: ja\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2019-08-12 16:55+0000\n" "Last-Translator: David Gómez \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "バージョン番号を表示" msgid "Set window title" msgstr "ウィンドウタイトルを設定" msgid "Select initial terminal font" msgstr "ターミナルのフォントを選択" msgid "Select initial number of tabs" msgstr "タブの数を選択" msgid "Set working directory" msgstr "作業ディレクトリを設定" msgid "Execute command" msgstr "コマンドを実行" msgid "Execute command (last option in the command line)" msgstr "コマンドを実行(コマンド行の最終オプション)" msgid "Login shell" msgstr "ログインシェル" msgid "Set window icon" msgstr "ウィンドウアイコンを設定" msgid "Set columns number" msgstr "列数を設定" msgid "Set rows number" msgstr "行数を設定" msgid "Hold window after execute command" msgstr "実行コマンドの後ウインドウ食い止める" msgid "Maximize window" msgstr "ウィンドウを最大化" msgid "Fullscreen mode" msgstr "フルスクリーンモード" msgid "Use alternate configuration file" msgstr "別の設定ファイルを使用する" msgid "Select initial colorset" msgstr "初カラーセットを選択" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "実行中のプロセスがあります。\n" "\n" "本当にsakuraを終了しますか?" msgid "Select font" msgstr "フォントを選択" msgid "Set tab name" msgstr "タブの名前を設定" msgid "_Cancel" msgstr "キャンセル(_C)" msgid "_Apply" msgstr "適用(_A)" msgid "New text" msgstr "新規テキスト" msgid "Select colors" msgstr "色を選択" msgid "_Select" msgstr "選択(_S)" msgid "Colorset" msgstr "カラーセット" msgid "Color scheme" msgstr "カラースキーム" msgid "Foreground color" msgstr "前景色" msgid "Background color" msgstr "背景色" msgid "Cursor color" msgstr "カーソルの色" msgid "Opacity level (%)" msgstr "不透過率 (%)" msgid "Palette" msgstr "パレット" msgid "Use bright colors for bold text" msgstr "太字のテキストには明るい色を使用する" msgid "New window title" msgstr "新しいウィンドウタイトル" msgid "Open mail" msgstr "メールを開く" msgid "Open link" msgstr "リンクを開く" msgid "Copy link" msgstr "リンクをコピー" msgid "New tab" msgstr "新規タブ" msgid "Set tab name..." msgstr "タブの名前を設定..." msgid "Close tab" msgstr "タブを閉じる" msgid "Full screen" msgstr "フルスクリーン" msgid "Copy" msgstr "コピー" msgid "Paste" msgstr "貼り付け" msgid "Options" msgstr "設定" msgid "Select font..." msgstr "フォントを選択..." msgid "Select colors..." msgstr "色を選択..." msgid "Show tab bar" msgstr "タブバーを表示" msgid "Always" msgstr "常に" msgid "When there's more than one tab" msgstr "複数のタブがある時" msgid "Never" msgstr "一度もない" msgid "Tabs at bottom" msgstr "タブを下に表示" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "スクロールバーを表示" msgid "Fewer questions at exit time" msgstr "終了時の質問が少なくする" msgid "Automatically copy selected text" msgstr "選択したテキストを自動的にコーピーする" msgid "Set urgent bell" msgstr "救急ベルを有効にする" msgid "Set audible bell" msgstr "ベル音を有効にする" msgid "Set blinking cursor" msgstr "カーソルの点滅を有効にする" msgid "Disable numbered tabswitch" msgstr "番号のタブ切り替えを無効にする" msgid "Set cursor type" msgstr "カーソルタイプを設定" msgid "Block" msgstr "四角" msgid "Underline" msgstr "アンダーライン" msgid "IBeam" msgstr "Iビーム" msgid "Search" msgstr "探索" #, c-format msgid "Terminal %d" msgstr "ターミナル %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "この端末には実行中のプロセスがあります。\n" "\n" "本当に閉じますか?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "別のプロセスに設定が変更された。上書き?" msgid "Error message" msgstr "エラー・メッセージ" #, c-format msgid "Cannot change working directory\n" msgstr "作業ディレクトリを変更することはできません\n" msgid "- vte-based terminal emulator" msgstr "- vte ベースのターミナル・エミュレータ" #, c-format msgid "sakura version is %s\n" msgstr "sakura のバージョンは %s です\n" #~ msgid "Show close button on tabs" #~ msgstr "タブに閉じるボタンを表示" #~ msgid "Enable focus fade" #~ msgstr "フォーカスフェードを有効にする" ================================================ FILE: po/ka.po ================================================ # Georgian translation for sakura. # Copyright (C) 2026 sakura's authors. # This file is distributed under the same license as the sakura package. # Ekaterine Papava , 2026. # msgid "" msgstr "" "Project-Id-Version: sakura git\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-04-27 12:22+0200\n" "PO-Revision-Date: 2026-04-13 15:28+0200\n" "Last-Translator: Temuri Doghonadze \n" "Language-Team: Georgian <(nothing)>\n" "Language: ka\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 3.9\n" #: src/sakura.c:560 msgid "Print version number" msgstr "ვერსიის ნომრის გამოტანა" #: src/sakura.c:561 src/sakura.c:1552 msgid "Set window title" msgstr "ფანჯრის სათაურის შეცვლა" #: src/sakura.c:562 msgid "Select initial terminal font" msgstr "აირჩიეთ ტერმინალის საწყისი ფონტი" #: src/sakura.c:563 msgid "Select initial number of tabs" msgstr "აირჩიეთ ჩანართების საწყისი რაოდენობა" #: src/sakura.c:564 msgid "Set working directory" msgstr "სამუშაო საქაღალდის დაყენება" #: src/sakura.c:565 msgid "Execute command" msgstr "ბრძანების შესრულება" #: src/sakura.c:566 msgid "Execute command (last option in the command line)" msgstr "ბრძანების შესრულება (ბრძანების სტრიქონის ბოლო პარამეტრი)" #: src/sakura.c:568 msgid "Login shell" msgstr "შესვლს გარსი" #: src/sakura.c:569 msgid "Set window icon" msgstr "ფანჯრის ხატულას დაყენება" #: src/sakura.c:570 msgid "Set columns number" msgstr "სვეტების რაოდენობის დაყენება" #: src/sakura.c:571 msgid "Set rows number" msgstr "მწკრივების რაოდენობის დაყენება" #: src/sakura.c:572 msgid "Hold window after execute command" msgstr "ფანჯრის შენარჩუნება ბრძანების შესრულების შემდეგ" #: src/sakura.c:573 msgid "Maximize window" msgstr "ფანჯრის გადიდება" #: src/sakura.c:574 msgid "Fullscreen mode" msgstr "სრული ეკრანის რეჟიმი" #: src/sakura.c:575 msgid "Use alternate configuration file" msgstr "ალტერნატიული კონფიგურაციის ფაილის გამოყენება" #: src/sakura.c:576 msgid "Select initial colorset" msgstr "საწყისი ფერთა ნაკრების არჩევა" #: src/sakura.c:1178 msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "პროცესები ჯერ კიდევ გაშვებულია.\n" "\n" "მართლა გნებავთ Sakura-ის დახურვა?" #: src/sakura.c:1217 msgid "Select font" msgstr "აირჩიეთ ფონტი" #: src/sakura.c:1248 msgid "Set tab name" msgstr "ჩანართის სახელის დაყენება" #: src/sakura.c:1251 src/sakura.c:1380 src/sakura.c:1555 src/sakura.c:2673 msgid "_Cancel" msgstr "გაუ_ქმება" #: src/sakura.c:1252 src/sakura.c:1556 src/sakura.c:2674 msgid "_Apply" msgstr "გ_ადატარება" #: src/sakura.c:1264 msgid "New text" msgstr "ახალი ტექსტი" #: src/sakura.c:1378 msgid "Select colors" msgstr "ფერების არჩევა" #: src/sakura.c:1380 msgid "_Select" msgstr "_მონიშვნა" #: src/sakura.c:1389 msgid "Colorset" msgstr "ფერების ნაკრები" #: src/sakura.c:1400 msgid "Color scheme" msgstr "ფერების სქემა" #: src/sakura.c:1411 msgid "Foreground color" msgstr "წინა პლანის ფერი" #: src/sakura.c:1412 msgid "Background color" msgstr "ფონის ფერი" #: src/sakura.c:1413 msgid "Cursor color" msgstr "კურსორის ფერი" #: src/sakura.c:1422 msgid "Opacity level (%)" msgstr "გაუმჭვირვალობის დონე (%)" #: src/sakura.c:1426 msgid "Palette" msgstr "პალიტრა" #: src/sakura.c:1435 msgid "Use bright colors for bold text" msgstr "კაშკაშა ფერები სქელი ტექსტისთვის" #: src/sakura.c:1565 msgid "New window title" msgstr "ფანჯრის ახალი სათაური" #: src/sakura.c:2448 msgid "Open mail" msgstr "ელფოსტის გახსნა" #: src/sakura.c:2449 msgid "Open link" msgstr "ბმულის გახსნა" #: src/sakura.c:2450 msgid "Copy link" msgstr "ბმულის კოპირება" #: src/sakura.c:2451 msgid "New tab" msgstr "ახალი ჩანართი" #: src/sakura.c:2452 msgid "Set tab name..." msgstr "ჩანართის სახელის დაყენება..." #: src/sakura.c:2453 msgid "Close tab" msgstr "ჩანართის დახურვა" #: src/sakura.c:2454 msgid "Full screen" msgstr "სრულ ეკრანზე" #: src/sakura.c:2455 msgid "Copy" msgstr "კოპირება" #: src/sakura.c:2456 msgid "Paste" msgstr "ჩასმა" #: src/sakura.c:2458 msgid "Options" msgstr "მორგება" #: src/sakura.c:2460 msgid "Select font..." msgstr "ფონტის არჩევა..." #: src/sakura.c:2461 msgid "Select colors..." msgstr "ფერების არჩევა..." #: src/sakura.c:2462 msgid "Show tab bar" msgstr "ჩანართის ზოლის ჩვენება" #: src/sakura.c:2463 msgid "Always" msgstr "ყოველთვის" #: src/sakura.c:2465 msgid "When there's more than one tab" msgstr "როცა არსებობს ერთზე მეტი ჩანართი" #: src/sakura.c:2467 msgid "Never" msgstr "არასდროს" #: src/sakura.c:2468 msgid "Tabs at bottom" msgstr "ჩანართები ქვემოთ" #: src/sakura.c:2469 msgid "New tab after current tab" msgstr "ახალი ჩანართი მიმდინარე ჩანართის შემდეგ" #: src/sakura.c:2470 msgid "Show scrollbar" msgstr "ჩოჩიის ჩვენება" #: src/sakura.c:2471 msgid "Fewer questions at exit time" msgstr "ნაკლები კითხვა გასვლისას" #: src/sakura.c:2472 msgid "Automatically copy selected text" msgstr "მონიშნული ტექსტის ავტომატური კოპირება" #: src/sakura.c:2473 msgid "Set urgent bell" msgstr "სასწრაფოობის ზარის დაყენება" #: src/sakura.c:2474 msgid "Set audible bell" msgstr "გასაგონი ზარის დაყენება" #: src/sakura.c:2475 msgid "Set blinking cursor" msgstr "მოციმციმე კურსორის დაყენება" #: src/sakura.c:2476 msgid "Disable numbered tabswitch" msgstr "დანომრილი ჩანართების გადართვის გამორთვა" #: src/sakura.c:2478 msgid "Set cursor type" msgstr "კურსორის ტიპის დაყენება" #: src/sakura.c:2479 msgid "Block" msgstr "ბლოკი" #: src/sakura.c:2480 msgid "Underline" msgstr "ხაზგასმული" #: src/sakura.c:2481 msgid "IBeam" msgstr "IBeam" #: src/sakura.c:2670 src/sakura.c:2683 msgid "Search" msgstr "ძებნა" #: src/sakura.c:3009 #, c-format msgid "Terminal %d" msgstr "ტერმინალი %d" #: src/sakura.c:3341 msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "ამ ტერმინალში არსებობს გაშვებული პროცესი.\n" "\n" "მართლა გნებავთ მისი დახურვა?" #: src/sakura.c:3492 msgid "Configuration has been modified by another process. Overwrite?" msgstr "კონფიგურაცია შეიცვალა სხვა პროცესის მიერ. გადავაწერო თავზე?" #: src/sakura.c:3543 msgid "Error message" msgstr "შეცდომის შეტყობინება" #: src/sakura.c:3744 src/sakura.c:3814 #, c-format msgid "Cannot change working directory\n" msgstr "სამუშაო საქაღალდის შეცვლა შეუძლებელია\n" #: src/sakura.c:3800 msgid "- vte-based terminal emulator" msgstr "- vte-ზე დაფუძნებული ტერმინალის ემულატორი" #: src/sakura.c:3819 #, c-format msgid "sakura version is %s\n" msgstr "sakura-ის ვერსიაა %s\n" ================================================ FILE: po/ko.po ================================================ # Korean translation for sakura # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the sakura package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2019-09-30 05:48+0000\n" "Last-Translator: Minho Park \n" "Language-Team: Korean \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "버전 보기" msgid "Set window title" msgstr "창 제목 설정" msgid "Select initial terminal font" msgstr "터미널 초기 글꼴 선택" msgid "Select initial number of tabs" msgstr "탭 초기 갯수 선택" msgid "Set working directory" msgstr "작업 디렉토리 설정" msgid "Execute command" msgstr "명령 실행" msgid "Execute command (last option in the command line)" msgstr "명령어 실행 (명령어 줄에 마지막 설정)" msgid "Login shell" msgstr "로그인 쉘" msgid "Set window icon" msgstr "창 아이콘 설정" msgid "Set columns number" msgstr "열 번호 설정" msgid "Set rows number" msgstr "줄 번호 설정" msgid "Hold window after execute command" msgstr "명령어 실행 후 창 유지" msgid "Maximize window" msgstr "창 최대화" msgid "Fullscreen mode" msgstr "전체화면 모드" msgid "Use alternate configuration file" msgstr "대체 설정 파일 사용" msgid "Select initial colorset" msgstr "초기 색상 세트 선댁" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "실행되는 프로세스가 있습니다.\n" "\n" "정말로 사쿠라를 닫을까요?" msgid "Select font" msgstr "글꼴 선택" msgid "Set tab name" msgstr "탭 이름 설정" msgid "_Cancel" msgstr "취소(_C)" msgid "_Apply" msgstr "적용(_A)" msgid "New text" msgstr "새 글" msgid "Select colors" msgstr "색상 선댁" msgid "_Select" msgstr "선택(_S)" msgid "Colorset" msgstr "색상 세트" msgid "Color scheme" msgstr "색 구성표" msgid "Foreground color" msgstr "글자색" msgid "Background color" msgstr "배경색" msgid "Cursor color" msgstr "커서색" msgid "Opacity level (%)" msgstr "불투명도 (%)" msgid "Palette" msgstr "파레트" msgid "Use bright colors for bold text" msgstr "굵은 텍스트에 밝은 색상 사용" msgid "New window title" msgstr "새 창 제목" msgid "Open mail" msgstr "메일열기" msgid "Open link" msgstr "링크 열기" msgid "Copy link" msgstr "링크 복사" msgid "New tab" msgstr "새 탭" msgid "Set tab name..." msgstr "탭 이름 설정..." msgid "Close tab" msgstr "탭 닫기" msgid "Full screen" msgstr "전체 화면" msgid "Copy" msgstr "복사" msgid "Paste" msgstr "붙여넣기" msgid "Options" msgstr "설정" msgid "Select font..." msgstr "글꼴 선택..." msgid "Select colors..." msgstr "색상 선택..." msgid "Show tab bar" msgstr "탭바 보기" msgid "Always" msgstr "항상" msgid "When there's more than one tab" msgstr "하나 이상의 탭이 있는 경우" msgid "Never" msgstr "절대" msgid "Tabs at bottom" msgstr "탭을 아래에 표시" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "스크롤바 보기" msgid "Fewer questions at exit time" msgstr "종료 시 적은 질문" msgid "Automatically copy selected text" msgstr "선택한 텍스트를 자동으로 복사" msgid "Set urgent bell" msgstr "긴급 종 설정" msgid "Set audible bell" msgstr "종 소리 설정" msgid "Set blinking cursor" msgstr "커서 깜빡임 설정" msgid "Disable numbered tabswitch" msgstr "번호 탭 스위치 사용 안 함" msgid "Set cursor type" msgstr "커서 종류 설정" msgid "Block" msgstr "블럭" msgid "Underline" msgstr "밑줄" msgid "IBeam" msgstr "I기둥" msgid "Search" msgstr "검색" #, c-format msgid "Terminal %d" msgstr "터미널 %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "이 터미널에 실행되는 프로세스가 있습니다.\n" "\n" "정말로 닫을까요?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "다른 프로세스에서 설정을 수정했습니다. 덮어쓸까요?" msgid "Error message" msgstr "오류 메시지" #, c-format msgid "Cannot change working directory\n" msgstr "작업 디렉토리를 변경할 수 없습니다\n" msgid "- vte-based terminal emulator" msgstr "- vte 기반의 터미널 에뮬레이터" #, c-format msgid "sakura version is %s\n" msgstr "sakura 버전은 %s 입니다\n" #~ msgid "Show close button on tabs" #~ msgstr "탭에 닫기 단추 보기" #~ msgid "Enable focus fade" #~ msgstr "초점 페이드 사용" ================================================ FILE: po/pl.po ================================================ # Polish translation for sakura # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the sakura package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: David Gómez \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Pokaż wersję" msgid "Set window title" msgstr "Ustaw tytuł okna" msgid "Select initial terminal font" msgstr "Wybierz domyślną czcionkę" msgid "Select initial number of tabs" msgstr "Wybierz domyślną ilość zakładek" msgid "Set working directory" msgstr "Ustaw katalog roboczy" msgid "Execute command" msgstr "Wykonaj polecenie" msgid "Execute command (last option in the command line)" msgstr "Wykonaj komendę (ostatnia opcja w wierszu poleceń" msgid "Login shell" msgstr "Powłoka logowania" msgid "Set window icon" msgstr "Ustaw ikonę okna" msgid "Set columns number" msgstr "Ustaw liczbę kolumn" msgid "Set rows number" msgstr "Ustaw liczbę wierszy" msgid "Hold window after execute command" msgstr "Nie wyłączaj okna po wykonaniu polecenia" msgid "Maximize window" msgstr "Maksymalizuj okno" msgid "Fullscreen mode" msgstr "Tryb pełnoekranowy" msgid "Use alternate configuration file" msgstr "Użyj alternatywnego pliku konfiguracyjnego" msgid "Select initial colorset" msgstr "Wybierz domyślny schemat kolorów" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Dalej działają uruchomione procesy.\n" "\n" "Czy na pewno chcesz zamknąć Sakura?" msgid "Select font" msgstr "Wybierz czcionkę" msgid "Set tab name" msgstr "Wybierz nazwę zakładki" msgid "_Cancel" msgstr "_Anuluj" msgid "_Apply" msgstr "_Zastosuj" msgid "New text" msgstr "Nowy tekst" msgid "Select colors" msgstr "Wybierz kolory" msgid "_Select" msgstr "_Wybierz" msgid "Colorset" msgstr "Schemat kolorów" #, fuzzy msgid "Color scheme" msgstr "Schemat kolorów" msgid "Foreground color" msgstr "Kolor pierwszoplanowy" msgid "Background color" msgstr "Kolor tła" msgid "Cursor color" msgstr "Kolor kursora" msgid "Opacity level (%)" msgstr "Nieprzezroczystość" #, fuzzy msgid "Palette" msgstr "Ustaw paletę" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "Nowy tytuł okna" #, fuzzy msgid "Open mail" msgstr "Otwórz link..." msgid "Open link" msgstr "Otwórz odnośnik" msgid "Copy link" msgstr "Kopiuj odnośnik" msgid "New tab" msgstr "Nowa zakładka" msgid "Set tab name..." msgstr "Ustaw nazwę karty..." msgid "Close tab" msgstr "Zamknij zakładkę" msgid "Full screen" msgstr "Pełny ekran" msgid "Copy" msgstr "Kopiuj" msgid "Paste" msgstr "Wklej" msgid "Options" msgstr "Ustawienia" msgid "Select font..." msgstr "Wybierz czcionkę..." msgid "Select colors..." msgstr "Wybierz kolory..." msgid "Show tab bar" msgstr "Wyświetlaj pasek kart" msgid "Always" msgstr "Zawsze" msgid "When there's more than one tab" msgstr "Kiedy jest więcej niż jeden" msgid "Never" msgstr "Nigdy" msgid "Tabs at bottom" msgstr "Karty na dole" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Pokaż pasek przesuwania" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" #, fuzzy msgid "Set urgent bell" msgstr "Dźwiękowy sygnał" msgid "Set audible bell" msgstr "Dźwiękowy sygnał" msgid "Set blinking cursor" msgstr "Migający kursor" msgid "Disable numbered tabswitch" msgstr "" msgid "Set cursor type" msgstr "Wybierz typ kursora" msgid "Block" msgstr "Blokuj" msgid "Underline" msgstr "Podkreślenie" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "W tym terminalu dalej działa proces.\n" "\n" "Czy na pewno chcesz go zamknąć?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "" msgid "Error message" msgstr "Komunikat o błędzie" #, c-format msgid "Cannot change working directory\n" msgstr "Nie można zmienić katalogu roboczego\n" msgid "- vte-based terminal emulator" msgstr "- emulator terminala oparty na vte" #, c-format msgid "sakura version is %s\n" msgstr "wersja sakura to %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Pokaż przyciski zamykania na kartach" ================================================ FILE: po/pt.po ================================================ # Portuguese translation for sakura # Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013 # This file is distributed under the same license as the sakura package. # FIRST AUTHOR , 2013. # msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: David Gómez \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Mostrar número da versão" msgid "Set window title" msgstr "Definir título da janela" msgid "Select initial terminal font" msgstr "Escolha o tipo inicial de letra do terminal" msgid "Select initial number of tabs" msgstr "Escolha o número inicial de separadores" msgid "Set working directory" msgstr "Definir diretório de trabalho" msgid "Execute command" msgstr "Executar comando" msgid "Execute command (last option in the command line)" msgstr "Executar comando (última opção da linha de comandos)" msgid "Login shell" msgstr "" msgid "Set window icon" msgstr "Definir ícone de janela" msgid "Set columns number" msgstr "Definir número de colunas" msgid "Set rows number" msgstr "Definir número de linhas" msgid "Hold window after execute command" msgstr "" msgid "Maximize window" msgstr "Maximizar janela" msgid "Fullscreen mode" msgstr "Ecrã completo" msgid "Use alternate configuration file" msgstr "Utilizar ficheiro alternativo de configurações" msgid "Select initial colorset" msgstr "Escolha conjunto de cores inicial" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Existem processos em curso.\n" "\n" "Quer mesmo fechar o Sakura?" msgid "Select font" msgstr "Escolha o tipo de letra" msgid "Set tab name" msgstr "Definir nome do separador" msgid "_Cancel" msgstr "_Cancelar" msgid "_Apply" msgstr "_Aplicar" msgid "New text" msgstr "Novo texto" msgid "Select colors" msgstr "Escolha a cor" msgid "_Select" msgstr "_Selecionar" msgid "Colorset" msgstr "Conjunto de cores" msgid "Color scheme" msgstr "Esquema de cores" msgid "Foreground color" msgstr "Cor de primeiro plano" msgid "Background color" msgstr "Cor de fundo" msgid "Cursor color" msgstr "Cor do cursor" msgid "Opacity level (%)" msgstr "Nivel de opacidade (%)" msgid "Palette" msgstr "Palete" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "Título da nova janela" msgid "Open mail" msgstr "Abrir correio" msgid "Open link" msgstr "Abrir ligação" msgid "Copy link" msgstr "Copiar ligação" msgid "New tab" msgstr "Novo separador" msgid "Set tab name..." msgstr "Definir nome do separador" msgid "Close tab" msgstr "Fechar separador" msgid "Full screen" msgstr "Ecrã completo" msgid "Copy" msgstr "Copiar" msgid "Paste" msgstr "Colar" msgid "Options" msgstr "Opções" msgid "Select font..." msgstr "Escolha o tipo de letra..." msgid "Select colors..." msgstr "Escolha as cores..." msgid "Show tab bar" msgstr "Mostrar barra de separadores" msgid "Always" msgstr "Sempre" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "Nunca" msgid "Tabs at bottom" msgstr "Separadores em baixo" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Mostrar barra de deslocação" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Definir sinal urgente" msgid "Set audible bell" msgstr "Definir sinal sonoro" msgid "Set blinking cursor" msgstr "Definir cursor intermitente" msgid "Disable numbered tabswitch" msgstr "" msgid "Set cursor type" msgstr "Definir tipo de cursor" msgid "Block" msgstr "Bloco" msgid "Underline" msgstr "Sublinhado" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "Pesquisar" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "Ainda existem processos em curso neste terminal.\n" "\n" "Quer mesmo fechar o terminal?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "A configuração foi modificada por outro processo. Substituir?" msgid "Error message" msgstr "Mensagem de erro" #, c-format msgid "Cannot change working directory\n" msgstr "Não pode mudar o diretório de trabalho\n" msgid "- vte-based terminal emulator" msgstr "- Emulador de terminal vte-based" #, c-format msgid "sakura version is %s\n" msgstr "A versão do sakura é a %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Mostrar botão para fechar separadores" #~ msgid "Enable focus fade" #~ msgstr "Habilitar enfranquecimiento do foco" ================================================ FILE: po/pt_BR.po ================================================ msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: David Gómez \n" "Language-Team: fabio.antunes@hotmail.com \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Mostrar número da versão" msgid "Set window title" msgstr "Definir título da janela" msgid "Select initial terminal font" msgstr "Selecionar fonte inicial do terminal" msgid "Select initial number of tabs" msgstr "Selecionar número inicial de abas" #, fuzzy msgid "Set working directory" msgstr "Ativar cursor piscando" msgid "Execute command" msgstr "Executar comando" msgid "Execute command (last option in the command line)" msgstr "Executar comando (última opção da linha de comando)" msgid "Login shell" msgstr "Login shell" #, fuzzy msgid "Set window icon" msgstr "Definir título da janela" msgid "Set columns number" msgstr "Definir número de colunas" msgid "Set rows number" msgstr "Definir número de linhas" msgid "Hold window after execute command" msgstr "Mostrar a janela depois de executar o comando" msgid "Maximize window" msgstr "Maximizar janela" msgid "Fullscreen mode" msgstr "Tela cheia" msgid "Use alternate configuration file" msgstr "Usar arquivo de configuração alternativo" #, fuzzy msgid "Select initial colorset" msgstr "Selecionar cor" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Existem processos sendo executados.\n" "\n" "Tem certeza que deseja fechar Sakura?" msgid "Select font" msgstr "Selecionar fonte" msgid "Set tab name" msgstr "Definir nome da aba" msgid "_Cancel" msgstr "_Cancelar" msgid "_Apply" msgstr "_Aplicar" msgid "New text" msgstr "Novo texto" msgid "Select colors" msgstr "Selecionar cor" msgid "_Select" msgstr "_Selecionar" msgid "Colorset" msgstr "" msgid "Color scheme" msgstr "" msgid "Foreground color" msgstr "Cor de primeiro plano" msgid "Background color" msgstr "Cor de fundo" msgid "Cursor color" msgstr "Cor do cursor" msgid "Opacity level (%)" msgstr "Nível de opacidade (%):" msgid "Palette" msgstr "Paleta" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "Definir título da janela" #, fuzzy msgid "Open mail" msgstr "Abrir link..." msgid "Open link" msgstr "Abrir link..." msgid "Copy link" msgstr "Copiar link..." msgid "New tab" msgstr "Nova aba" msgid "Set tab name..." msgstr "Definir nome da aba..." msgid "Close tab" msgstr "Fechar aba" msgid "Full screen" msgstr "Tela cheia" msgid "Copy" msgstr "Copiar" msgid "Paste" msgstr "Colar" msgid "Options" msgstr "Opções" msgid "Select font..." msgstr "Selecionar fonte..." msgid "Select colors..." msgstr "Selecionar cores..." msgid "Show tab bar" msgstr "Mostrar a barra de abas" msgid "Always" msgstr "Sempre" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "Nunca" msgid "Tabs at bottom" msgstr "Abas em baixo" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Mostra barra de rolagem" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" #, fuzzy msgid "Set urgent bell" msgstr "Ativar aviso sonoro" msgid "Set audible bell" msgstr "Ativar aviso sonoro" msgid "Set blinking cursor" msgstr "Ativar cursor piscando" msgid "Disable numbered tabswitch" msgstr "" msgid "Set cursor type" msgstr "Definir tipo de cursor" msgid "Block" msgstr "Bloquear" msgid "Underline" msgstr "Sublinhar" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "Existem processos sendo executados nesse terminal.\n" "\n" "Tem certeza que deseja fechar ele?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "A configuração foi modificada por outro processo. Sobrescrever?" msgid "Error message" msgstr "Mensagem de erro" #, fuzzy, c-format msgid "Cannot change working directory\n" msgstr "Ativar cursor piscando" msgid "- vte-based terminal emulator" msgstr "- emulador de terminal baseado no vte" #, c-format msgid "sakura version is %s\n" msgstr "sakura versão %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Exibir o botão fechar nas abas" ================================================ FILE: po/ru.po ================================================ msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: ManDrive \n" "Language-Team: Evgenij Vdovin \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Вывести номер версии" msgid "Set window title" msgstr "Изменение заголовка окна" msgid "Select initial terminal font" msgstr "Выбрать начальный шрифт терминала" msgid "Select initial number of tabs" msgstr "Выбрать начальное число вкладок" msgid "Set working directory" msgstr "Установить рабочую директорию" msgid "Execute command" msgstr "Выполнить команду" msgid "Execute command (last option in the command line)" msgstr "Выполнить команду (последнюю опцию в командной строке)" msgid "Login shell" msgstr "Логин shell" msgid "Set window icon" msgstr "Установить иконку окна" msgid "Set columns number" msgstr "Установить число столбцов" msgid "Set rows number" msgstr "Установить число строк" msgid "Hold window after execute command" msgstr "Удерживать окно после выполнения команды" msgid "Maximize window" msgstr "Максимальный размер окна" msgid "Fullscreen mode" msgstr "Полноэкранный режим" msgid "Use alternate configuration file" msgstr "Использовать альтернативный файл конфигурации" msgid "Select initial colorset" msgstr "Выбрать начальную цветовую палитру" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Имеются запущенные процессы.\n" "\n" "Вы уверены, что хотите закрыть Sakura?" msgid "Select font" msgstr "Выбрать шрифт" msgid "Set tab name" msgstr "Установить заголовок вкладки" msgid "_Cancel" msgstr "_Отменить" msgid "_Apply" msgstr "_Применить" msgid "New text" msgstr "Новый текст" msgid "Select colors" msgstr "Выбрать цвета" msgid "_Select" msgstr "_Выбрать" msgid "Colorset" msgstr "Цветовой набор" msgid "Color scheme" msgstr "Цветовой нсхема" msgid "Foreground color" msgstr "Цвет текста" msgid "Background color" msgstr "Цвет фона" msgid "Cursor color" msgstr "Цвет курсора" msgid "Opacity level (%)" msgstr "Уровень прозрачности (%)" msgid "Palette" msgstr "Палитра" msgid "Use bright colors for bold text" msgstr "Изображать толстый шрифт яркими цветами" msgid "New window title" msgstr "Новый заголовок окна:" msgid "Open mail" msgstr "Открыть почта" msgid "Open link" msgstr "Открыть ссылку" msgid "Copy link" msgstr "Копировать ссылку" msgid "New tab" msgstr "Новая вкладка" msgid "Set tab name..." msgstr "Установить заголовок вкладки..." msgid "Close tab" msgstr "Закрыть вкладку" msgid "Full screen" msgstr "Полноэкранный режим" msgid "Copy" msgstr "Копировать" msgid "Paste" msgstr "Вставить" msgid "Options" msgstr "Настройки" msgid "Select font..." msgstr "Выбрать шрифт..." msgid "Select colors..." msgstr "Выбрать цвета..." msgid "Show tab bar" msgstr "Показывать панель вкладок" msgid "Always" msgstr "Всегда" msgid "When there's more than one tab" msgstr "Если имеется более чем одна" msgid "Never" msgstr "Никогда" msgid "Tabs at bottom" msgstr "Панель вкладок внизу" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Показать линейку прокрутки" msgid "Fewer questions at exit time" msgstr "Меньше вопросов при выходе" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Установить срочный звонок" msgid "Set audible bell" msgstr "Звуковое оповещение" msgid "Set blinking cursor" msgstr "Мигающий курсор" msgid "Disable numbered tabswitch" msgstr "Отключить нумерованный переключатель вкладок" msgid "Set cursor type" msgstr "Установить вид курсора" msgid "Block" msgstr "Блочный" msgid "Underline" msgstr "_-образный" msgid "IBeam" msgstr "I-образный" msgid "Search" msgstr "Поиск" #, c-format msgid "Terminal %d" msgstr "Терминал %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "Не все процессы завершены в этом терминале.\n" "\n" "Вы уверены, что хотите выйти закрыть его?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "Настройки были изменены другим процессом. Перезаписать?" msgid "Error message" msgstr "Сообщение об ошибке" #, c-format msgid "Cannot change working directory\n" msgstr "Не удалось сменить рабочую директорию\n" msgid "- vte-based terminal emulator" msgstr "- эмулятор терминала, основанный на VTE" #, c-format msgid "sakura version is %s\n" msgstr "Версия sakura %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Показывать кнопку закрытия на вкладке" #~ msgid "Enable focus fade" #~ msgstr "Включение фокусировки замирания" ================================================ FILE: po/sv.po ================================================ # Swedish translation for sakura # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the sakura package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2019-08-12 16:27+0000\n" "Last-Translator: Andreas Rönnquist \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Skriv ut versionsnummer" msgid "Set window title" msgstr "Sätt fönstertitel" msgid "Select initial terminal font" msgstr "Välj initialt terminaltypsnitt" msgid "Select initial number of tabs" msgstr "Välj initialt antal flikar" msgid "Set working directory" msgstr "Sätt arbetskatalog" msgid "Execute command" msgstr "Kör kommando" msgid "Execute command (last option in the command line)" msgstr "Kör kommando (Sista alternativet på kommandoraden)" msgid "Login shell" msgstr "Inloggningsskal" msgid "Set window icon" msgstr "Sätt fönsterikon" msgid "Set columns number" msgstr "Sätt antal kolumner" msgid "Set rows number" msgstr "Sätt antal rader" msgid "Hold window after execute command" msgstr "Håll kvar fönster efter kommandokörning" msgid "Maximize window" msgstr "Maximera fönster" msgid "Fullscreen mode" msgstr "Helskärmsläge" msgid "Use alternate configuration file" msgstr "Använd alternativ konfigurationsfil" msgid "Select initial colorset" msgstr "Välj initial färguppsättning" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Det finns processer som fortfarande är igång.\n" "\n" "Vill du verkligen avsluta sakura?" msgid "Select font" msgstr "Välj typsnitt" msgid "Set tab name" msgstr "Sätt fliknamn" msgid "_Cancel" msgstr "_Avbryt" msgid "_Apply" msgstr "_Verkställ" msgid "New text" msgstr "Ny text" msgid "Select colors" msgstr "Välj färger" msgid "_Select" msgstr "_Välj" msgid "Colorset" msgstr "Färguppsättning" msgid "Color scheme" msgstr "Färgschema" msgid "Foreground color" msgstr "Förgrundsfärg" msgid "Background color" msgstr "Bakgrundsfärg" msgid "Cursor color" msgstr "Markörfärg" msgid "Opacity level (%)" msgstr "Opacitetsnivå (%)" msgid "Palette" msgstr "Palett" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "Ny fönstertitel" msgid "Open mail" msgstr "Öppna e-post" msgid "Open link" msgstr "Öppna länk" msgid "Copy link" msgstr "Kopiera länk" msgid "New tab" msgstr "Ny flik" msgid "Set tab name..." msgstr "Sätt fliknamn..." msgid "Close tab" msgstr "Stäng flik" msgid "Full screen" msgstr "Helskärm" msgid "Copy" msgstr "Kopiera" msgid "Paste" msgstr "Klistra in" msgid "Options" msgstr "Alternativ" msgid "Select font..." msgstr "Välj typsnitt..." msgid "Select colors..." msgstr "Välj färger..." msgid "Show tab bar" msgstr "Visa flikfältet" msgid "Always" msgstr "Alltid" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "Aldrig" msgid "Tabs at bottom" msgstr "Flikar nederst" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Visa rullningslist" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "Sätt larmsignal" msgid "Set audible bell" msgstr "Sätt hörbar signal" msgid "Set blinking cursor" msgstr "Sätt blinkande markör" msgid "Disable numbered tabswitch" msgstr "Inaktivera numrerad flikväxlare" msgid "Set cursor type" msgstr "Sätt markörtyp" msgid "Block" msgstr "Block" msgid "Underline" msgstr "Understreck" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "Sök" #, c-format msgid "Terminal %d" msgstr "Terminal %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "Det finns en process igång i denna terminal.\n" "\n" "Vill du verkligen avsluta den?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "Konfigurationen har ändrats av en annan process. Skriv över?" msgid "Error message" msgstr "Felmeddelande" #, c-format msgid "Cannot change working directory\n" msgstr "Kan inte ändra arbetskatalog\n" msgid "- vte-based terminal emulator" msgstr "- vte-baserad terminalemulator" #, c-format msgid "sakura version is %s\n" msgstr "sakura-versionen är %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Visa stängningsknapp på flikar" #~ msgid "Enable focus fade" #~ msgstr "Aktivera fokustoning" ================================================ FILE: po/tr.po ================================================ # # Eyyüb Akçaer , 2022. # # madanadam , 2023. # msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2022-11-11 17:45+0300\n" "Last-Translator: Eyyüb Akçaer \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Gtranslator 3.38.0\n" msgid "Print version number" msgstr "Sürüm numarasını yazdır" msgid "Set window title" msgstr "Pencere başlığını ayarla" msgid "Select initial terminal font" msgstr "Uçbirim yazı tipini seç" msgid "Select initial number of tabs" msgstr "Başlangıç sekme sayısını seç" msgid "Set working directory" msgstr "Çalışma dizinini ayarla" msgid "Execute command" msgstr "Komut çalıştır" msgid "Execute command (last option in the command line)" msgstr "Komut çalıştır (komut satırındaki son seçenek)" msgid "Login shell" msgstr "Açılış kabuğu" msgid "Set window icon" msgstr "Pencere simgesini ayarla" msgid "Set columns number" msgstr "Sütun sayısını ayarla" msgid "Set rows number" msgstr "Satır sayısını ayarla" msgid "Hold window after execute command" msgstr "Komut çalıştırmadan sonra pencereyi tut" msgid "Maximize window" msgstr "Pencereyi büyüt" msgid "Fullscreen mode" msgstr "Tam ekran kipi" msgid "Use alternate configuration file" msgstr "Alternatif yapılandırma dosyası kullan" msgid "Select initial colorset" msgstr "Başlangıç renk setini seç" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Devam eden süreçler var.\n" "\n" "Sakura'yı gerçekten kapatmak istiyor musunuz?" msgid "Select font" msgstr "Yazı tipini seç" msgid "Set tab name" msgstr "Sekme adını ayarla" msgid "_Cancel" msgstr "_İptal" msgid "_Apply" msgstr "_Uygula" msgid "New text" msgstr "Yeni metin" msgid "Select colors" msgstr "Renkleri seç" msgid "_Select" msgstr "_Seç" msgid "Colorset" msgstr "Renk seti" msgid "Color scheme" msgstr "Renk şeması" msgid "Foreground color" msgstr "Önplan rengi" msgid "Background color" msgstr "Arkaplan rengi" msgid "Cursor color" msgstr "İmleç rengi" msgid "Opacity level (%)" msgstr "Opaklık düzeyi (%)" msgid "Palette" msgstr "Renk paleti" msgid "Use bright colors for bold text" msgstr "Kalın yazı için parlak renk kullan" msgid "New window title" msgstr "Yeni pencere başlığı" msgid "Open mail" msgstr "Posta aç" msgid "Open link" msgstr "Bağlantı aç" msgid "Copy link" msgstr "Bağlantı kopyala" msgid "New tab" msgstr "Yeni sekme" msgid "Set tab name..." msgstr "Sekme adını ayarla..." msgid "Close tab" msgstr "Sekmeyi kapat" msgid "Full screen" msgstr "Tam ekran" msgid "Copy" msgstr "Kopyala" msgid "Paste" msgstr "Yapıştır" msgid "Options" msgstr "Seçenekler" msgid "Select font..." msgstr "Yazı tipini seç..." msgid "Select colors..." msgstr "Renkleri seç..." msgid "Show tab bar" msgstr "Sekme çubuğunu göster" msgid "Always" msgstr "Daima" msgid "When there's more than one tab" msgstr "Birden çoksa" msgid "Never" msgstr "Asla" msgid "Tabs at bottom" msgstr "Sekmeler altta" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Kaydırma çubuğunu göster" msgid "Fewer questions at exit time" msgstr "Çıkış süresinde daha az soru" msgid "Automatically copy selected text" msgstr "Seçilen yazıyı otomatik kopyala" msgid "Set urgent bell" msgstr "Acil zilini ayarla" msgid "Set audible bell" msgstr "Duyulabilir zili ayarla" msgid "Set blinking cursor" msgstr "Yanıp sönen imleci ayarla" msgid "Disable numbered tabswitch" msgstr "Numaralandırılmış sekme-geçişini devre dışı bırak" msgid "Set cursor type" msgstr "İmleç türünü ayarla" msgid "Block" msgstr "Blok" msgid "Underline" msgstr "Alt çizgi" msgid "IBeam" msgstr "I Işın" msgid "Search" msgstr "Ara" #, c-format msgid "Terminal %d" msgstr "Uçbirim %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "Bu uçbirimde devam eden bir süreç var.\n" "\n" "Onu gerçekten kapatmak istiyor musunuz?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "" "Yapılandırma, başka bir süreç tarafından değiştirilmiş. Üzerine yazılsın mı?" msgid "Error message" msgstr "Hata iletisi" #, c-format msgid "Cannot change working directory\n" msgstr "Çalışma dizini değiştirilemez\n" msgid "- vte-based terminal emulator" msgstr "- vte- tabanlı uçbirim öykünücüsü" #, c-format msgid "sakura version is %s\n" msgstr "sakura sürümü: %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Sekmelerde kapatma butonunu göster" #~ msgid "Enable focus fade" #~ msgstr "Odak kaybını etkinleştir" #~ msgid "More" #~ msgstr "Daha fazla" #~ msgid "Set window title..." #~ msgstr "Pencere başlığını ayarla..." #~ msgid "Stop tab cycling at end tabs" #~ msgstr "Sekme döngüsünü son sekmelerde bitir" ================================================ FILE: po/uk.po ================================================ # Ukrainian translation for sakura # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the sakura package. # FIRST AUTHOR , 2012. # msgid "" msgstr "" "Project-Id-Version: sakura\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2018-04-29 13:18+0000\n" "Last-Translator: Andriy Nezhivy \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "Показати версію" msgid "Set window title" msgstr "Встановити заголовок вікна" msgid "Select initial terminal font" msgstr "Оберіть початкаовий шрифт терміналу" msgid "Select initial number of tabs" msgstr "Оберіть початкову кількість вкладок терміналу" #, fuzzy msgid "Set working directory" msgstr "Встановити мерехтіння курсора" msgid "Execute command" msgstr "Виконати команду" msgid "Execute command (last option in the command line)" msgstr "Виконати команду (остання опція в командному рядку)" msgid "Login shell" msgstr "Оболонка входу" #, fuzzy msgid "Set window icon" msgstr "Встановити заголовок вікна" msgid "Set columns number" msgstr "Встановити кількість стовпців" msgid "Set rows number" msgstr "Встановити кількість рядків" msgid "Hold window after execute command" msgstr "Тримати вікно після виконання команди" msgid "Maximize window" msgstr "" #, fuzzy msgid "Fullscreen mode" msgstr "Повноекранний режим" msgid "Use alternate configuration file" msgstr "Використати інший файл конфігурації" #, fuzzy msgid "Select initial colorset" msgstr "Обрати колір" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "Є запущені процеси.\n" "Ви дійсно хочете закрити Sakura?" msgid "Select font" msgstr "Обрати шрифт" msgid "Set tab name" msgstr "Вказати ім'я вкладки" msgid "_Cancel" msgstr "" msgid "_Apply" msgstr "" msgid "New text" msgstr "Новий текст" #, fuzzy msgid "Select colors" msgstr "Обрати колір" #, fuzzy msgid "_Select" msgstr "Обрати шрифт" msgid "Colorset" msgstr "" msgid "Color scheme" msgstr "" #, fuzzy msgid "Foreground color" msgstr "Оберіть колір:" #, fuzzy msgid "Background color" msgstr "Оберіть колір тла:" #, fuzzy msgid "Cursor color" msgstr "Оберіть колір тла:" #, fuzzy msgid "Opacity level (%)" msgstr "Рівень прозорості (%):" #, fuzzy msgid "Palette" msgstr "Оберіть палітру" msgid "Use bright colors for bold text" msgstr "" msgid "New window title" msgstr "Новий заголовок вікна" #, fuzzy msgid "Open mail" msgstr "Відкрити посилання..." msgid "Open link" msgstr "Відкрити посилання..." msgid "Copy link" msgstr "Копіювати посилання..." msgid "New tab" msgstr "Нова вкладка" msgid "Set tab name..." msgstr "Встановити нове ім'я вкладки..." msgid "Close tab" msgstr "Закрити вкладку" msgid "Full screen" msgstr "Повноекранний режим" msgid "Copy" msgstr "Копіювати" msgid "Paste" msgstr "Вставити" msgid "Options" msgstr "Параметри" msgid "Select font..." msgstr "Обрати шрифт..." msgid "Select colors..." msgstr "Обрати кольори..." msgid "Show tab bar" msgstr "Показувати панель вкладок" msgid "Always" msgstr "Завжди" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "Ніколи" msgid "Tabs at bottom" msgstr "Вкладки знизу" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "Показувати скроллбар" msgid "Fewer questions at exit time" msgstr "" msgid "Automatically copy selected text" msgstr "" #, fuzzy msgid "Set urgent bell" msgstr "Встановити звуковий сигнал" msgid "Set audible bell" msgstr "Встановити звуковий сигнал" msgid "Set blinking cursor" msgstr "Встановити мерехтіння курсора" msgid "Disable numbered tabswitch" msgstr "" msgid "Set cursor type" msgstr "Оберіть тип курсора" msgid "Block" msgstr "Блок" msgid "Underline" msgstr "Підкреслення" msgid "IBeam" msgstr "IBeam" msgid "Search" msgstr "" #, c-format msgid "Terminal %d" msgstr "Термінал %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "В цьому терміналі є запущені процеси.\n" "\n" "Ви хочете закрити його?" #, fuzzy msgid "Configuration has been modified by another process. Overwrite?" msgstr "Конфігурація була змінена іншим процесом. Переписати?" msgid "Error message" msgstr "Повідомлення про помилку" #, fuzzy, c-format msgid "Cannot change working directory\n" msgstr "Встановити мерехтіння курсора" msgid "- vte-based terminal emulator" msgstr "Термінальний емулятор базований на vte" #, c-format msgid "sakura version is %s\n" msgstr "версія Sakura %s\n" #~ msgid "Show close button on tabs" #~ msgstr "Показувати кнопки закриття на вкладках" ================================================ FILE: po/zh_CN.po ================================================ # Chinese/Simplified translation of sakura. # Copyright (C) 2006 THE sakura'S COPYRIGHT HOLDER # This file is distributed under the same license as the sakura package. # yanghong , 2006. # msgid "" msgstr "" "Project-Id-Version: sakura 1.0.4\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-10 19:15+0200\n" "PO-Revision-Date: 2019-08-12 17:06+0000\n" "Last-Translator: David Gómez \n" "Language-Team: Chinese/Simplified \n" "Language: zh\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2020-05-06 05:44+0000\n" "X-Generator: Launchpad (build fbdff7602bd10fb883bf7e2ddcc7fd5a16f60398)\n" msgid "Print version number" msgstr "显示版本号" msgid "Set window title" msgstr "设置窗口标题" msgid "Select initial terminal font" msgstr "选择初始终端字体" msgid "Select initial number of tabs" msgstr "选择初始标签数" msgid "Set working directory" msgstr "设置工作目录" msgid "Execute command" msgstr "执行命令" msgid "Execute command (last option in the command line)" msgstr "执行命令(命令行结束前执行)" msgid "Login shell" msgstr "登录 shell" msgid "Set window icon" msgstr "设置窗口图标" msgid "Set columns number" msgstr "设置列数" msgid "Set rows number" msgstr "设置行数" msgid "Hold window after execute command" msgstr "运行后保留窗口" msgid "Maximize window" msgstr "最大化窗口" msgid "Fullscreen mode" msgstr "全屏模式" msgid "Use alternate configuration file" msgstr "使用其他配置文件" msgid "Select initial colorset" msgstr "选择初始颜色设置" msgid "" "There are running processes.\n" "\n" "Do you really want to close Sakura?" msgstr "" "有进程正在运行。\n" "\n" "您真的要关闭 Sakura 吗?" msgid "Select font" msgstr "选择字体" msgid "Set tab name" msgstr "设置标签页名称" msgid "_Cancel" msgstr "取消" msgid "_Apply" msgstr "应用" msgid "New text" msgstr "新文本" msgid "Select colors" msgstr "选择颜色" msgid "_Select" msgstr "选择" msgid "Colorset" msgstr "色彩集" msgid "Color scheme" msgstr "颜色方案" msgid "Foreground color" msgstr "前景色" msgid "Background color" msgstr "背景色" msgid "Cursor color" msgstr "光标色" msgid "Opacity level (%)" msgstr "不透明度(%)" msgid "Palette" msgstr "调色板" msgid "Use bright colors for bold text" msgstr "为了粗体字使用鲜艳的色彩" msgid "New window title" msgstr "新窗口标题" msgid "Open mail" msgstr "打开邮件" msgid "Open link" msgstr "打开链接" msgid "Copy link" msgstr "复制链接" msgid "New tab" msgstr "新建标签" msgid "Set tab name..." msgstr "设置标签页名称..." msgid "Close tab" msgstr "关闭标签" msgid "Full screen" msgstr "全屏" msgid "Copy" msgstr "复制" msgid "Paste" msgstr "粘贴" msgid "Options" msgstr "选项" msgid "Select font..." msgstr "选择字体..." msgid "Select colors..." msgstr "选择颜色..." # msgstr "总是显示第一个标签页" msgid "Show tab bar" msgstr "" msgid "Always" msgstr "" msgid "When there's more than one tab" msgstr "" msgid "Never" msgstr "" msgid "Tabs at bottom" msgstr "标签页在底部" msgid "New tab after current tab" msgstr "" msgid "Show scrollbar" msgstr "显示滚动条" msgid "Fewer questions at exit time" msgstr "退出时的问题较少" msgid "Automatically copy selected text" msgstr "" msgid "Set urgent bell" msgstr "设定紧急铃" msgid "Set audible bell" msgstr "设定蜂鸣铃" msgid "Set blinking cursor" msgstr "设置闪烁光标" msgid "Disable numbered tabswitch" msgstr "禁用编号标签开关" msgid "Set cursor type" msgstr "设置光标类型" msgid "Block" msgstr "方块" msgid "Underline" msgstr "下划线" msgid "IBeam" msgstr "竖线" msgid "Search" msgstr "搜索" #, c-format msgid "Terminal %d" msgstr "终端 %d" msgid "" "There is a running process in this terminal.\n" "\n" "Do you really want to close it?" msgstr "" "终端中有进程正在执行。\n" "\n" "您确定要关闭它吗?" msgid "Configuration has been modified by another process. Overwrite?" msgstr "配置已被另一个进程修改。覆盖?" msgid "Error message" msgstr "错误消息" #, c-format msgid "Cannot change working directory\n" msgstr "不能改变工作目录\n" msgid "- vte-based terminal emulator" msgstr "- 基于 vte 的终端模拟器" #, c-format msgid "sakura version is %s\n" msgstr "sakura 版本是 %s\n" #~ msgid "Show close button on tabs" #~ msgstr "在标签上显示关闭按钮" #~ msgid "Enable focus fade" #~ msgstr "启动焦点淡化" ================================================ FILE: sakura.desktop ================================================ [Desktop Entry] Name=Sakura GenericName=Terminal GenericName[af]=Terminaal GenericName[ar]=طرفيّة GenericName[as]=টাৰ্মিনেল GenericName[be@latin]=Terminał GenericName[bg]=Терминал GenericName[bn]=টার্মিনাল GenericName[bn_IN]=টার্মিন্যাল GenericName[cs]=Terminál GenericName[el]=Τερματικό GenericName[eo]=Terminalo GenericName[eu]=Terminala GenericName[fi]=Pääteikkuna GenericName[ga]=Teirminéal GenericName[gu]=ટર્મિનલ GenericName[he]=מסוף GenericName[hi]=टर्मिनल GenericName[hne]=टर्मिनल GenericName[hu]=Terminál GenericName[is]=Skjáhermir GenericName[it]=Terminale GenericName[ja]=ターミナル GenericName[ka]=ტერმინალი GenericName[kk]=Терминал GenericName[ko]=터미널 GenericName[ku]=Termînal GenericName[lt]=Terminalas GenericName[lv]=Terminālis GenericName[mai]=टर्मिनल GenericName[mk]=Терминал GenericName[ml]=ടെര്മിനല് GenericName[mr]=टर्मिनल GenericName[nds]=Konsool GenericName[or]=ଟର୍ମିନାଲ GenericName[pa]=ਟਰਮੀਨਲ GenericName[ru]=Терминал GenericName[si]=අග්රය GenericName[sk]=Terminál GenericName[sr]=Терминал GenericName[sr@ijekavian]=Терминал GenericName[ta]=முனையம் GenericName[tg]=Терминал GenericName[th]=เทอร์มินัล GenericName[tr]=Uçbirim GenericName[ug]=تېرمىنال GenericName[uk]=Термінал GenericName[uz@cyrillic]=Терминал GenericName[wa]=Terminå GenericName[zh_CN]=终端 GenericName[zh_TW]=終端機 Comment=Use the command line Comment[ru]=Использовать командную строку Comment[am]=የትእዛዝ መስመሩን መጠቀሚያ Comment[bg]=Използване на команден ред Comment[ca]=Utilitza la línia d'ordres Comment[cs]=Použít příkazový řádek Comment[da]=Brug kommandolinjen Comment[de]=Die Befehlszeile verwenden Comment[el]=Χρήση της γραμμής εντολών Comment[eo]=Uzi komandlinion Comment[es]=Usar la línea de órdenes Comment[et]=Käsurea kasutamine Comment[eu]=Erabili komando-lerroa Comment[fi]=Käytä komentoriviä Comment[fr]=Utiliser la ligne de commande Comment[gl]=Usar a liña de ordes Comment[hi]=कमांड लाइन का प्रयोग करें Comment[hr]=Koristiti naredbeni redak Comment[hu]=Parancssor használata Comment[id]=Gunakan baris perintah Comment[it]=Usa la riga di comando Comment[ja]=コマンドラインを利用する Comment[ko]=명령줄 사용하기 Comment[ms]=Guna baris perintah Comment[nb]=Bruk kommandolinjen Comment[nl]=Opdrachtregel gebruiken Comment[pl]=Umożliwia korzystanie z wiersza poleceń Comment[pt]=Utilizar a linha de comandos Comment[pt_BR]=Usar a linha de comando Comment[ro]=Folosiți linia de comandă Comment[rue]=Використати командний рядок Comment[sl]=Uporabi ukazno vrstico Comment[sr]=Користите командну линију Comment[sv]=Använd kommandoraden Comment[sw]=Tumia komand Comment[tr]=Komut satırını kullan Comment[uk]=Використати командну лінію Comment[vi]=Sử dụng dòng lệnh Comment[zh_CN]=使用命令行 Comment[zh_TW]=使用指令列 TryExec=sakura Exec=sakura Icon=terminal-tango Type=Application Categories=GTK;Utility;TerminalEmulator;System; Keywords=terminal; StartupNotify=true X-Ubuntu-Gettext-Domain=sakura ================================================ FILE: sakura.pod ================================================ =encoding utf8 =head1 NAME sakura - A simple but powerful libvte-based terminal emulator. =head1 SYNOPSIS sakura [options...] =head1 DESCRIPTION sakura is a terminal emulator based on GTK+ and VTE. It's a terminal emulator with few dependencies, so you don't need a full GNOME desktop installed to have a decent terminal emulator. =head1 HELP OPTIONS =over 8 =item B<-?, --help> Show help options. =item B<--help-all> Show all help options =item B<--help-gtk> Show GTK+ Options =back =head1 APPLICATION OPTIONS =over 8 =item B<-v, --version> Print version number =item B<-f, --font> Select initial terminal font =item B<-n, --ntabs> Select initial number of tabs =item B<-x, --execute> Execute command =item B<-e, --xterm-execute> Execute command (compatible with xterm's -e option) =item B<-l, --login> Login shell =item B<-c, --columns> Set columns number =item B<-r, --rows> Set rows number =item B<-h, --hold> Hold window after execute command =item B<-d, --working-directory> Set working directory =item B<-m, --maximize> Maximize window =item B<-s, --fullscreen> Fullscreen mode =item B<--display=DISPLAY> X display to use =item B<--config-file=FILENAME> Use alternate configuration file. Path is relative to the sakura config dir. (Example: ~/.config/sakura/FILENAME). =back =head1 GTK+ OPTIONS =over 8 =item B<--class=CLASS> Program class as used by the window manager =item B<--name=NAME> Program name as used by the window manager =item B<--screen=SCREEN> X screen to use =item B<--sync> Make X calls synchronous =item B<--gtk-module=MODULES> Load additional GTK+ modules =item B<--g-fatal-warnings> Make all warnings fatal =back =head1 CONFIGURATION =over 8 =item show_tab_bar=[always | multiple | never] This list of options is currently incomplete. =back =head1 KEYBINDINGS SUPPORT B supports keyboard bindings. They are configurable by setting the following properties in your sakura config file (~/.config/sakura/sakura.conf). =head2 ACCELERATORS Accelerators can be set to any mask value from the GdkModifierType in gdktypes.h; see: http://gtk.php.net/manual/en/html/gdk/gdk.enum.modifiertype.html Mask values can be combined by ORing them. For example, to set the delete tab accelerator to Ctrl + Shift: del_tab_accelerator=5 because GDK_SHIFT_MASK has a value of 1 (1 << 0), and GDK_CONTROL_MASK has a value of 4 (1 << 2); ORing them together, you get 5. I realise that this configuration is not so friendly to non-programmers, but it is a start. :) =head2 KEYS For example, to set the add tab key to 'T': add_tab_key=T Before sakura used keycodes instead of strings. They're still valid. =head2 DEFAULTS Ctrl + Shift + T -> New tab Ctrl + Shift + W -> Close current tab Ctrl + Shift + C -> Copy selected text Ctrl + Shift + V -> Paste selected text Ctrl + Left cursor -> Previous tab Ctrl + Right cursor -> Next tab Ctrl + [1-9] -> Switch to tab N (1-9) Ctrl + Shift + S -> Toggle scrollbar Ctrl + Shift + Mouse left button -> Open link F11 -> Fullscreen Shift + PageUp -> Move up through scrollback by page Shift + PageDown -> Move down through scrollback by page Ctrl + Shift + Up -> Move up through scrollback by line Ctrl + Shift + Down -> Move down through scrollback by line You can also increase and decrease the font size in the GTK+ standard way (not configurable): Ctrl + '+' -> Increase font size Ctrl + '-' -> Decrease font size =head1 BUGS B is hosted on Launchpad. Bugs can be filed at: https://bugs.launchpad.net/sakura =head1 AUTHORS B was written by David Gómez . This manual page was written by Andrew Starr-Bochicchio . Both are released under the GNU General Public License, version 2 or later. =cut ================================================ FILE: src/sakura.c ================================================ /******************************************************************************* * Filename: sakura.c * Description: VTE-based terminal emulator * * Copyright (C) 2006-2021 David Gómez * Copyright (C) 2008 Hong Jen Yee (PCMan) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _(String) gettext(String) #define N_(String) (String) #define GETTEXT_PACKAGE "sakura" #define SAY(format,...) do {\ if (strcmp("Debug", BUILDTYPE)==0) {\ fprintf(stderr, "[%d] ", getpid());\ fprintf(stderr, "[%s] ", __FUNCTION__);\ if (format) fprintf(stderr, format, ##__VA_ARGS__);\ fputc('\n', stderr);\ fflush(stderr);\ }\ } while (0) #define PALETTE_SIZE 16 /* 16 color palettes in GdkRGBA format (red, green, blue, alpha) */ const GdkRGBA gruvbox_palette[PALETTE_SIZE] = { {0.156863, 0.156863, 0.156863, 1.000000}, {0.800000, 0.141176, 0.113725, 1.000000}, {0.596078, 0.592157, 0.101961, 1.000000}, {0.843137, 0.600000, 0.129412, 1.000000}, {0.270588, 0.521569, 0.533333, 1.000000}, {0.694118, 0.384314, 0.525490, 1.000000}, {0.407843, 0.615686, 0.415686, 1.000000}, {0.658824, 0.600000, 0.517647, 1.000000}, {0.572549, 0.513725, 0.454902, 1.000000}, {0.984314, 0.286275, 0.203922, 1.000000}, {0.721569, 0.733333, 0.149020, 1.000000}, {0.980392, 0.741176, 0.184314, 1.000000}, {0.513725, 0.647059, 0.596078, 1.000000}, {0.827451, 0.525490, 0.607843, 1.000000}, {0.556863, 0.752941, 0.486275, 1.000000}, {0.921569, 0.858824, 0.698039, 1.000000} }; const GdkRGBA tango_palette[PALETTE_SIZE] = { {0, 0, 0, 1}, {0.8, 0, 0, 1}, {0.305882, 0.603922, 0.023529, 1}, {0.768627, 0.627451, 0, 1}, {0.203922, 0.396078, 0.643137, 1}, {0.458824, 0.313725, 0.482353, 1}, {0.0235294,0.596078, 0.603922, 1}, {0.827451, 0.843137, 0.811765, 1}, {0.333333, 0.341176, 0.32549, 1}, {0.937255, 0.160784, 0.160784, 1}, {0.541176, 0.886275, 0.203922, 1}, {0.988235, 0.913725, 0.309804, 1}, {0.447059, 0.623529, 0.811765, 1}, {0.678431, 0.498039, 0.658824, 1}, {0.203922, 0.886275, 0.886275, 1}, {0.933333, 0.933333, 0.92549, 1} }; const GdkRGBA linux_palette[PALETTE_SIZE] = { {0, 0, 0, 1}, {0.666667, 0, 0, 1}, {0, 0.666667, 0, 1}, {0.666667, 0.333333, 0, 1}, {0, 0, 0.666667, 1}, {0.666667, 0, 0.666667, 1}, {0, 0.666667, 0.666667, 1}, {0.666667, 0.666667, 0.666667, 1}, {0.333333, 0.333333, 0.333333, 1}, {1, 0.333333, 0.333333, 1}, {0.333333, 1, 0.333333, 1}, {1, 1, 0.333333, 1}, {0.333333, 0.333333, 1, 1}, {1, 0.333333, 1, 1}, {0.333333, 1, 1, 1}, {1, 1, 1, 1} }; const GdkRGBA solarized_palette[PALETTE_SIZE] = { {0.027451, 0.211765, 0.258824, 1}, // 0 base02 {0.862745, 0.196078, 0.184314, 1}, // 1 red {0.521569, 0.600000, 0.000000, 1}, // 2 green {0.709804, 0.537255, 0.000000, 1}, // 3 yellow {0.149020, 0.545098, 0.823529, 1}, // 4 blue {0.827451, 0.211765, 0.509804, 1}, // 5 magenta {0.164706, 0.631373, 0.596078, 1}, // 6 cyan {0.933333, 0.909804, 0.835294, 1}, // 7 base2 {0.000000, 0.168627, 0.211765, 1}, // 8 base03 (bg) {0.796078, 0.294118, 0.086275, 1}, // 9 orange {0.345098, 0.431373, 0.458824, 1}, // 10 base01 {0.396078, 0.482353, 0.513725, 1}, // 11 base00 {0.513725, 0.580392, 0.588235, 1}, // 12 base0 (fg) {0.423529, 0.443137, 0.768627, 1}, // 13 violet {0.576471, 0.631373, 0.631373, 1}, // 14 base1 {0.992157, 0.964706, 0.890196, 1} // 15 base3 }; const GdkRGBA nord_palette[PALETTE_SIZE] = { {0.0, 0.0, 0.0234375, 1.0}, {0.74609375, 0.37890625, 0.4140625, 1.0}, {0.63671875, 0.7421875, 0.546875, 1.0}, {0.91796875, 0.79296875, 0.54296875, 1.0}, {0.50390625, 0.62890625, 0.75390625, 1.0}, {0.703125, 0.5546875, 0.67578125, 1.0}, {0.53125, 0.75, 0.8125, 1.0}, {0.89453125, 0.91015625, 0.9375, 1.0}, {0.296875, 0.3359375, 0.4140625, 1.0}, {0.74609375, 0.37890625, 0.4140625, 1.0}, {0.63671875, 0.7421875, 0.546875, 1.0}, {0.91796875, 0.79296875, 0.54296875, 1.0}, {0.50390625, 0.62890625, 0.75390625, 1.0}, {0.703125, 0.5546875, 0.67578125, 1.0}, {0.55859375, 0.734375, 0.73046875, 1.0}, {0.921875, 0.93359375, 0.953125, 1.0} }; const GdkRGBA xterm_palette[PALETTE_SIZE] = { {0, 0, 0, 1}, {0.803922, 0, 0, 1}, {0, 0.803922, 0, 1}, {0.803922, 0.803922, 0, 1}, {0.117647, 0.564706, 1, 1}, {0.803922, 0, 0.803922, 1}, {0, 0.803922, 0.803922, 1}, {0.898039, 0.898039, 0.898039, 1}, {0.298039, 0.298039, 0.298039, 1}, {1, 0, 0, 1}, {0, 1, 0, 1}, {1, 1, 0, 1}, {0.27451, 0.509804, 0.705882, 1}, {1, 0, 1, 1}, {0, 1, 1, 1}, {1, 1, 1, 1} }; const GdkRGBA rxvt_palette[PALETTE_SIZE] = { {0, 0, 0, 1}, {0.803921, 0, 0, 1}, {0, 0.803921, 0, 1}, {0.803921, 0.803921, 0, 1}, {0, 0, 0.803921, 1}, {0.803921, 0, 0.803921, 1}, {0, 0.803921, 0.803921, 1}, {0.980392, 0.921568, 0.843137, 1}, {0.250980, 0.250980, 0.250980, 1}, {1, 0, 0, 1}, {0, 1, 0, 1}, {1, 1, 0, 1}, {0, 0, 1, 1}, {1, 0, 1, 1}, {0, 1, 1, 1}, {1, 1, 1, 1} }; const GdkRGBA hybrid_palette[PALETTE_SIZE] = { {0.1568627450980392 , 0.16470588235294117 , 0.1803921568627451 , 1} , {0.6470588235294118 , 0.25882352941176473 , 0.25882352941176473 , 1} , {0.5490196078431373 , 0.5803921568627451 , 0.25098039215686274 , 1} , {0.8705882352941177 , 0.5764705882352941 , 0.37254901960784315 , 1} , {0.37254901960784315 , 0.5058823529411764 , 0.615686274509804 , 1} , {0.5215686274509804 , 0.403921568627451 , 0.5607843137254902 , 1} , {0.3686274509803922 , 0.5529411764705883 , 0.5294117647058824 , 1} , {0.4392156862745098 , 0.47058823529411764 , 0.5019607843137255 , 1} , {0.21568627450980393 , 0.23137254901960785 , 0.2549019607843137 , 1} , {0.8 , 0.4 , 0.4 , 1} , {0.7098039215686275 , 0.7411764705882353 , 0.40784313725490196 , 1} , {0.9411764705882353 , 0.7764705882352941 , 0.4549019607843137 , 1} , {0.5058823529411764 , 0.6352941176470588 , 0.7450980392156863 , 1} , {0.6980392156862745 , 0.5803921568627451 , 0.7333333333333333 , 1} , {0.5411764705882353 , 0.7450980392156863 , 0.7176470588235294 , 1} , {0.7725490196078432 , 0.7843137254901961 , 0.7764705882352941 , 1} }; const char *palettes_names[]= {"Solarized", "Tango", "Gruvbox", "Nord", "Xterm", "Linux", "Rxvt", "Hybrid", NULL}; const GdkRGBA *palettes[] = {solarized_palette, tango_palette, gruvbox_palette, nord_palette, xterm_palette, linux_palette, rxvt_palette, hybrid_palette, NULL}; #define DEFAULT_PALETTE 1 /* Tango palette */ /* Color schemes (fg&bg) for sakura. Each colorset can use a different scheme */ struct scheme { gchar *name; GdkRGBA bg; GdkRGBA fg; }; #define NUM_SCHEMES 5 #define DEFAULT_SCHEME 1 struct scheme predefined_schemes[NUM_SCHEMES] = { {"Custom", {0, 0, 0, 1}, {1, 1, 1, 1}}, /* Custom values are ignored, we use the ones chosen by the user */ {"White on black", {0, 0, 0, 1}, {1, 1, 1, 1}}, {"Green on black", {0, 0, 0, 1}, {0.4, 1, 0, 1}}, {"Solarized dark", {0.000000, 0.168627, 0.211765, 1}, {0.513725, 0.580392, 0.588235, 1}}, {"Solarized light", {0.992157, 0.964706, 0.890196, 1}, {0.396078, 0.482353, 0.513725, 1}} }; /* CSS definitions. Global CSS is empty, just drop here you CSS to personalize widgets */ #define SAKURA_CSS "" #define FADE_WINDOW_CSS "\ window#fade_window {\ background-color: black;\ } " #define FADE_WINDOW_OPACITY 0.5 #define NUM_COLORSETS 6 #define PCRE2_CODE_UNIT_WIDTH 8 #include /* Tab bar visibility */ typedef enum { SHOW_TAB_BAR_ALWAYS, SHOW_TAB_BAR_MULTIPLE, SHOW_TAB_BAR_NEVER } ShowTabBar; /* Global sakura data */ static struct { GtkWidget *main_window; GtkWidget *notebook; GtkWidget *menu; GtkWidget *fade_window; /* Window used for fading effect */ PangoFontDescription *font; gdouble line_height; /* Font line height */ GdkRGBA forecolors[NUM_COLORSETS]; GdkRGBA backcolors[NUM_COLORSETS]; GdkRGBA curscolors[NUM_COLORSETS]; guint schemes[NUM_COLORSETS]; /* Selected color scheme for each colorset */ const GdkRGBA *palette; guint palette_idx; gint last_colorset; char *current_match; guint width; guint height; glong columns; glong rows; gint scroll_lines; VteCursorShape cursor_type; ShowTabBar show_tab_bar; /* Show the tab bar: always, multiple, never */ bool show_scrollbar; bool show_closebutton; bool new_tab_after_current; bool tabs_on_bottom; bool less_questions; bool copy_on_select; bool urgent_bell; bool audible_bell; bool blinking_cursor; bool fullscreen; bool config_modified; /* Configuration has been modified */ bool externally_modified; /* Configuration file has been modified by another process */ bool resized; bool disable_numbered_tabswitch; /* For disabling direct tabswitching key */ bool use_fading; /* Fade the window when the focus change */ bool scrollable_tabs; bool bold_is_bright; /* Show bold characters as bright */ bool dont_save; /* Don't save config file */ bool first_run; /* To only execute commands first time sakura is launched */ GtkWidget *item_copy_link; /* We include here only the items which need to be hidden */ GtkWidget *item_open_link; GtkWidget *item_open_mail; GtkWidget *open_link_separator; GKeyFile *cfg; char *configfile; char *icon; char *shell_path; char *main_title; /* Main window static title from user input */ char *term; gchar *tab_default_title; gint add_tab_accelerator; gint del_tab_accelerator; gint switch_tab_accelerator; gint move_tab_accelerator; gint copy_accelerator; gint scrollbar_accelerator; gint open_url_accelerator; gint font_size_accelerator; gint set_tab_name_accelerator; gint search_accelerator; gint set_colorset_accelerator; gint new_window_accelerator; gint add_tab_key; gint del_tab_key; gint prev_tab_key; gint next_tab_key; gint copy_key; gint paste_key; gint scrollbar_key; gint set_tab_name_key; gint search_key; gint fullscreen_key; gint increase_font_size_key; gint decrease_font_size_key; gint set_colorset_keys[NUM_COLORSETS]; gint paste_button; gint menu_button; gint new_window_key; int orig_argc; /* Used for new windows */ char** orig_argv; /* Used for new windows */ VteRegex *http_vteregexp, *mail_vteregexp; char *word_chars; /* Exceptions for word selection */ char *argv[3]; } sakura; /* Data associated to each sakura tab */ struct sakura_tab { GtkWidget *hbox; GtkWidget *label; GtkWidget *vte; /* Reference to VTE terminal */ GtkWidget *scrollbar; GtkBorder padding; /* inner-property data */ bool label_set_byuser; int colorset; GPid pid; /* pid of the forked process */ gulong exit_handler_id; }; #define ICON_FILE "terminal-tango.svg" #define SCROLL_LINES 4096 #define DEFAULT_SCROLL_LINES 4096 #define HTTP_REGEXP "(ftp|http)s?://[^ \t\n\b]+[^.,!? \t\n\b()<>{}«»„“”‚‘’\\[\\]\'\"]" #define MAIL_REGEXP "[^ \t\n\b()<>{}«»„“”‚‘’\\[\\]\'\"][^ \t\n\b]*@([^ \t\n\b()<>{}«»„“”‚‘’\\[\\]\'\"]+\\.)+([a-zA-Z]{2,})" #define DEFAULT_CONFIGFILE "sakura.conf" #define DEFAULT_COLUMNS 80 #define DEFAULT_ROWS 24 #define DEFAULT_MIN_WIDTH_CHARS 20 #define DEFAULT_MIN_HEIGHT_CHARS 1 #define DEFAULT_FONT "Ubuntu Mono,monospace 13" #define DEFAULT_LINE_HEIGHT 1.0 #define FONT_MINIMAL_SIZE (PANGO_SCALE*6) #define DEFAULT_WORD_CHARS "-,./?%&#_~:" #define TAB_MAX_SIZE 40 #define TAB_MIN_SIZE 6 #define FORWARD 1 #define BACKWARDS 2 #define DEFAULT_ADD_TAB_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_DEL_TAB_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_SWITCH_TAB_ACCELERATOR (GDK_MOD1_MASK) #define DEFAULT_MOVE_TAB_ACCELERATOR (GDK_MOD1_MASK|GDK_SHIFT_MASK) #define DEFAULT_COPY_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_SCROLLBAR_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_OPEN_URL_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_FONT_SIZE_ACCELERATOR (GDK_CONTROL_MASK) #define DEFAULT_SET_TAB_NAME_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_SEARCH_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_SELECT_COLORSET_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_NEW_WINDOW_ACCELERATOR (GDK_CONTROL_MASK|GDK_SHIFT_MASK) #define DEFAULT_ADD_TAB_KEY GDK_KEY_T #define DEFAULT_DEL_TAB_KEY GDK_KEY_W #define DEFAULT_PREV_TAB_KEY GDK_KEY_Left #define DEFAULT_NEXT_TAB_KEY GDK_KEY_Right #define DEFAULT_COPY_KEY GDK_KEY_C #define DEFAULT_PASTE_KEY GDK_KEY_V #define DEFAULT_SCROLLBAR_KEY GDK_KEY_S #define DEFAULT_SET_TAB_NAME_KEY GDK_KEY_N #define DEFAULT_SEARCH_KEY GDK_KEY_F #define DEFAULT_FULLSCREEN_KEY GDK_KEY_F11 #define DEFAULT_INCREASE_FONT_SIZE_KEY GDK_KEY_plus #define DEFAULT_DECREASE_FONT_SIZE_KEY GDK_KEY_minus #define DEFAULT_NEW_WINDOW_KEY GDK_KEY_O #define DEFAULT_SCROLLABLE_TABS TRUE #define DEFAULT_PASTE_BUTTON 2 #define DEFAULT_MENU_BUTTON 3 /* make this an array instead of #defines to get a compile time * error instead of a runtime if NUM_COLORSETS changes */ static int cs_keys[NUM_COLORSETS] = {GDK_KEY_F1, GDK_KEY_F2, GDK_KEY_F3, GDK_KEY_F4, GDK_KEY_F5, GDK_KEY_F6}; #define ERROR_BUFFER_LENGTH 256 const char cfg_group[] = "sakura"; /* Get a set sakura tab data from/to our GObject (notebook) */ static GQuark term_data_id = 0; #define sakura_get_sktab( sakura, page_idx ) \ (struct sakura_tab*)g_object_get_qdata( \ G_OBJECT( gtk_notebook_get_nth_page( (GtkNotebook*)sakura.notebook, page_idx ) ), term_data_id); #define sakura_set_sktab( sakura, page_idx, sk_tab ) \ g_object_set_qdata_full( \ G_OBJECT( gtk_notebook_get_nth_page( (GtkNotebook*)sakura.notebook, page_idx) ), \ term_data_id, sk_tab, (GDestroyNotify)g_free); /* Configuration macros */ #define sakura_set_config_integer(key, value) do {\ g_key_file_set_integer(sakura.cfg, cfg_group, key, value);\ sakura.config_modified=TRUE;\ } while(0); #define sakura_set_config_string(key, value) do {\ g_key_file_set_value(sakura.cfg, cfg_group, key, value);\ sakura.config_modified=TRUE;\ } while(0); #define sakura_set_config_boolean(key, value) do {\ g_key_file_set_boolean(sakura.cfg, cfg_group, key, value);\ sakura.config_modified=TRUE;\ } while(0); #define sakura_set_config_double(key, value) do {\ g_key_file_set_double(sakura.cfg, cfg_group, key, value);\ sakura.config_modified=TRUE;\ } while(0); /* Spawn callback */ void sakura_spawm_callback (VteTerminal *, GPid, GError, gpointer); /* VTE callbacks */ static gboolean sakura_term_buttonpressed_cb (GtkWidget *, GdkEventButton *, gpointer); static gboolean sakura_term_buttonreleased_cb (GtkWidget *, GdkEventButton *, gpointer); static void sakura_beep_cb (GtkWidget *, void *); static void sakura_increase_font_cb (GtkWidget *, void *); static void sakura_decrease_font_cb (GtkWidget *, void *); static void sakura_child_exited_cb (GtkWidget *, void *); static void sakura_eof_cb (GtkWidget *, void *); static void sakura_title_changed_cb (GtkWidget *, void *); static gboolean sakura_delete_event_cb (GtkWidget *, void *); static void sakura_destroy_window_cb (GtkWidget *, void *); /* Main window callbacks */ static gboolean sakura_key_press_cb (GtkWidget *, GdkEventKey *, gpointer); static gboolean sakura_resized_window_cb (GtkWidget *, GdkEventConfigure *, void *); static gboolean sakura_focus_in_cb (GtkWidget *, GdkEvent *, void *); static gboolean sakura_focus_out_cb (GtkWidget *, GdkEvent *, void *); static void sakura_conf_changed_cb (GtkWidget *, void *); static void sakura_show_event_cb (GtkWidget *, gpointer); /* Notebook, notebook labels and notebook buttons callbacks */ static void sakura_switch_page_cb (GtkWidget *, GtkWidget *, guint, void *); static void sakura_page_removed_cb (GtkWidget *, void *); static gboolean sakura_notebook_scroll_cb (GtkWidget *, GdkEventScroll *); static gboolean sakura_label_clicked_cb (GtkWidget *, GdkEventButton *, void *); static gboolean sakura_notebook_focus_cb (GtkWindow *, GdkEvent *, void *); static void sakura_closebutton_clicked_cb (GtkWidget *, void *); /* Menuitem callbacks */ static void sakura_font_dialog_cb (GtkWidget *, void *); static void sakura_set_name_dialog_cb (GtkWidget *, void *); static void sakura_color_dialog_cb (GtkWidget *, void *); //static void sakura_set_title_dialog (GtkWidget *, void *); static void sakura_new_tab_cb (GtkWidget *, void *); static void sakura_close_tab_cb (GtkWidget *, void *); static void sakura_fullscreen_cb (GtkWidget *, void *); static void sakura_open_url_cb (GtkWidget *, void *); static void sakura_open_mail_cb (GtkWidget *, void *); static void sakura_copy_url_cb (GtkWidget *, void *); static void sakura_copy_cb (GtkWidget *, void *); static void sakura_paste_cb (GtkWidget *, void *); static void sakura_show_tab_bar_cb (GtkWidget *, void *); static void sakura_tabs_on_bottom_cb (GtkWidget *, void *); static void sakura_less_questions_cb (GtkWidget *, void *); static void sakura_copy_on_select_cb (GtkWidget *, void *); static void sakura_new_tab_after_current_cb (GtkWidget *, void *); static void sakura_show_scrollbar_cb (GtkWidget *, void *); static void sakura_disable_numbered_tabswitch_cb (GtkWidget *, void *); //static void sakura_use_fading_cb (GtkWidget *, void *); static void sakura_setname_entry_changed_cb (GtkWidget *, void *); static void sakura_set_cursor_cb (GtkWidget *, void *); static void sakura_blinking_cursor_cb (GtkWidget *, void *); static void sakura_audible_bell_cb (GtkWidget *, void *); static void sakura_urgent_bell_cb (GtkWidget *, void *); /* Misc */ static void sakura_error (const char *, ...); static void sakura_build_command (int *, char ***); static char * sakura_get_term_cwd (struct sakura_tab *); static char * sakura_get_term_cwd_osc7 (struct sakura_tab *); static guint sakura_tokeycode (guint key); static void sakura_set_keybind (const gchar *, guint); static guint sakura_get_keybind (const gchar *); static void sakura_sanitize_working_directory (void); /* Functions */ static void sakura_init (); static void sakura_init_popup (); static void sakura_add_tab (); static void sakura_del_tab (gint); static void sakura_close_tab (gint); /* Save config, del tab and destroy sakura */ static void sakura_destroy (); static void sakura_move_tab (gint); static gint sakura_find_tab (VteTerminal *); static void sakura_set_font (); static void sakura_set_tab_label_text (const gchar *, gint); static void sakura_set_size (void); static void sakura_config_done (); static void sakura_set_colorset (int); static void sakura_set_colors (void); static void sakura_search_dialog (void); static void sakura_search (const char *, bool); static void sakura_copy (void); static void sakura_paste (void); static void sakura_paste_primary (void); static void sakura_show_scrollbar (void); static void sakura_new_window (void); /* Globals for command line parameters */ static const char *option_font; static const char *option_workdir; static const char *option_execute; static const char *option_title; static gchar **option_xterm_args; static gboolean option_xterm_execute=FALSE; static gboolean option_version=FALSE; static gint option_ntabs=1; static gint option_login = FALSE; static const char *option_icon; static int option_rows, option_columns; static gboolean option_hold=FALSE; static char *option_config_file; static gboolean option_fullscreen; static gboolean option_maximize; static gint option_colorset; static GOptionEntry entries[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version, N_("Print version number"), NULL }, { "title", 't', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &option_title, N_("Set window title"), NULL}, { "font", 'f', 0, G_OPTION_ARG_STRING, &option_font, N_("Select initial terminal font"), NULL }, { "ntabs", 'n', 0, G_OPTION_ARG_INT, &option_ntabs, N_("Select initial number of tabs"), NULL }, { "working-directory", 'd', 0, G_OPTION_ARG_STRING, &option_workdir, N_("Set working directory"), NULL }, { "execute", 'x', 0, G_OPTION_ARG_STRING, &option_execute, N_("Execute command"), NULL }, { "xterm-execute", 'e', 0, G_OPTION_ARG_NONE, &option_xterm_execute, N_("Execute command (last option in the command line)"), NULL }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &option_xterm_args, NULL, NULL }, { "login", 'l', 0, G_OPTION_ARG_NONE, &option_login, N_("Login shell"), NULL }, { "icon", 'i', 0, G_OPTION_ARG_STRING, &option_icon, N_("Set window icon"), NULL }, { "columns", 'c', 0, G_OPTION_ARG_INT, &option_columns, N_("Set columns number"), NULL }, { "rows", 'r', 0, G_OPTION_ARG_INT, &option_rows, N_("Set rows number"), NULL }, { "hold", 'h', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &option_hold, N_("Hold window after execute command"), NULL }, { "maximize", 'm', 0, G_OPTION_ARG_NONE, &option_maximize, N_("Maximize window"), NULL }, { "fullscreen", 's', 0, G_OPTION_ARG_NONE, &option_fullscreen, N_("Fullscreen mode"), NULL }, { "config-file", 0, 0, G_OPTION_ARG_FILENAME, &option_config_file, N_("Use alternate configuration file"), NULL }, { "colorset", 0, 0, G_OPTION_ARG_INT, &option_colorset, N_("Select initial colorset"), NULL }, { NULL } }; /*************************/ /* Main window callbacks */ /*************************/ static gboolean sakura_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data) { gint page, npages; guint topage = 0; if (event->type != GDK_KEY_PRESS) return FALSE; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); /* Use keycodes instead of keyvals. With keyvals, key bindings work only in US/ISO8859-1 and similar locales */ guint keycode = event->hardware_keycode; /* Get the GDK accel mask to compare with our accelerators */ GdkModifierType accel_mask = gtk_accelerator_get_default_mod_mask(); /* Add/delete tab keybinding pressed */ if ((event->state & accel_mask) == sakura.add_tab_accelerator && keycode == sakura_tokeycode(sakura.add_tab_key)) { sakura_add_tab(); return TRUE; } else if ((event->state & accel_mask) == sakura.del_tab_accelerator && keycode == sakura_tokeycode(sakura.del_tab_key)) { /* Delete current tab */ sakura_close_tab(page); return TRUE; } /* New window keybinding pressed */ if ( (event->state & sakura.new_window_accelerator) == sakura.new_window_accelerator && keycode == sakura_tokeycode(sakura.new_window_key)) { sakura_new_window(); return TRUE; } /* Switch tab keybinding pressed (numbers or next/prev) */ //if ((event->state & accel_mask) == sakura.switch_tab_accelerator) { /* If we use accel_mask, GDK_MOD4_MASK (windows key) it's not detected... */ if ((event->state & sakura.switch_tab_accelerator) == sakura.switch_tab_accelerator) { /* Just propagate the event if there is only one tab */ if (npages >= 2) { if ((keycode >= sakura_tokeycode(GDK_KEY_1)) && (keycode <= sakura_tokeycode( GDK_KEY_9))) { /* User has explicitly disabled this branch, make sure to propagate the event */ if (sakura.disable_numbered_tabswitch) return FALSE; if (sakura_tokeycode(GDK_KEY_1) == keycode) topage = 0; else if (sakura_tokeycode(GDK_KEY_2) == keycode) topage = 1; else if (sakura_tokeycode(GDK_KEY_3) == keycode) topage = 2; else if (sakura_tokeycode(GDK_KEY_4) == keycode) topage = 3; else if (sakura_tokeycode(GDK_KEY_5) == keycode) topage = 4; else if (sakura_tokeycode(GDK_KEY_6) == keycode) topage = 5; else if (sakura_tokeycode(GDK_KEY_7) == keycode) topage = 6; else if (sakura_tokeycode(GDK_KEY_8) == keycode) topage = 7; else if (sakura_tokeycode(GDK_KEY_9) == keycode) topage = 8; if (topage <= npages) gtk_notebook_set_current_page(GTK_NOTEBOOK(sakura.notebook), topage); return TRUE; } else if (keycode == sakura_tokeycode(sakura.prev_tab_key)) { if (gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook))==0) { gtk_notebook_set_current_page(GTK_NOTEBOOK(sakura.notebook), npages-1); } else { gtk_notebook_prev_page(GTK_NOTEBOOK(sakura.notebook)); } return TRUE; } else if (keycode == sakura_tokeycode(sakura.next_tab_key)) { if (gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)) == (npages-1)) { gtk_notebook_set_current_page(GTK_NOTEBOOK(sakura.notebook), 0); } else { gtk_notebook_next_page(GTK_NOTEBOOK(sakura.notebook)); } return TRUE; } } } /* Move tab keybinding pressed */ if ((event->state & accel_mask) == sakura.move_tab_accelerator) { if (keycode == sakura_tokeycode(sakura.prev_tab_key)) { sakura_move_tab(BACKWARDS); return TRUE; } else if (keycode == sakura_tokeycode(sakura.next_tab_key)) { sakura_move_tab(FORWARD); return TRUE; } } /* Copy/paste keybinding pressed */ if ((event->state & accel_mask) == sakura.copy_accelerator) { if (keycode == sakura_tokeycode(sakura.copy_key)) { sakura_copy(); return TRUE; } else if (keycode == sakura_tokeycode(sakura.paste_key)) { sakura_paste(); return TRUE; } } /* Show scrollbar keybinding pressed */ if ((event->state & accel_mask) == sakura.scrollbar_accelerator) { if (keycode == sakura_tokeycode(sakura.scrollbar_key)) { sakura_show_scrollbar(); return TRUE; } } /* Set tab name keybinding pressed */ if ((event->state & accel_mask) == sakura.set_tab_name_accelerator) { if (keycode == sakura_tokeycode(sakura.set_tab_name_key)) { sakura_set_name_dialog_cb(NULL, NULL); return TRUE; } } /* Search keybinding pressed */ if ((event->state & accel_mask) == sakura.search_accelerator) { if (keycode == sakura_tokeycode(sakura.search_key)) { sakura_search_dialog(); return TRUE; } } /* Increase/decrease font size keybinding pressed */ if ((event->state & accel_mask) == sakura.font_size_accelerator) { if (keycode == sakura_tokeycode(sakura.increase_font_size_key)) { sakura_increase_font_cb(NULL, NULL); return TRUE; } else if (keycode == sakura_tokeycode(sakura.decrease_font_size_key)) { sakura_decrease_font_cb(NULL, NULL); return TRUE; } } /* F11 (fullscreen) pressed */ if (keycode == sakura_tokeycode(sakura.fullscreen_key)) { sakura_fullscreen_cb(NULL, NULL); return TRUE; } /* Change in colorset */ if ((event->state & accel_mask) == sakura.set_colorset_accelerator) { int i; for (i=0; iwidth != sakura.width || event->height != sakura.height) { //SAY("Configure event received. Current w %d h %d ConfigureEvent w %d h %d", //sakura.width, sakura.height, event->width, event->height); gtk_widget_hide(sakura.fade_window); sakura.resized = TRUE; } return FALSE; } /* Use focus-in-event to unmap the fade window */ static gboolean sakura_focus_in_cb (GtkWidget *widget, GdkEvent *event, void *data) { if (event->type != GDK_FOCUS_CHANGE) return FALSE; //if (!sakura.use_fading) return FALSE; /* Got the focus, hide the fade */ //gtk_widget_hide(sakura.fade_window); /* Reset urgency hint */ gtk_window_set_urgency_hint(GTK_WINDOW(sakura.main_window), FALSE); return FALSE; } /* Use focus-out-event to map the fade window */ static gboolean sakura_focus_out_cb (GtkWidget *widget, GdkEvent *event, void *data) { gint ax, ay, mx, my, x, y; if (event->type != GDK_FOCUS_CHANGE) return FALSE; if (!sakura.use_fading) return FALSE; /* No fade when the menu is displayed */ if (gtk_widget_is_visible(sakura.menu)) return FALSE; /* Give the right size and position to the fade_window to cover all the main window */ gtk_widget_translate_coordinates(sakura.notebook, sakura.main_window, 0, 0, &ax, &ay); gtk_window_get_position(GTK_WINDOW(sakura.main_window), &mx, &my); gint titlebar_height = ay-my; gtk_window_move(GTK_WINDOW(sakura.fade_window), mx, my+titlebar_height); //SAY("FADE ax %d ay %d x %d y %d titlebar_h %d", ax, ay, mx, my, titlebar_height); /* Same size as main window */ gtk_window_get_size(GTK_WINDOW(sakura.main_window), &x, &y); gtk_window_resize(GTK_WINDOW(sakura.fade_window), x, y); //gtk_widget_show_all(sakura.fade_window); return FALSE; } static void sakura_show_event_cb (GtkWidget *widget, gpointer data) { /* Set size when the window is first shown */ sakura_set_size(); } /* Callback called when sakura configuration file is modified by an external process */ static void sakura_conf_changed_cb (GtkWidget *widget, void *data) { sakura.externally_modified = true; } /**********************/ /* Notebook callbacks */ /**********************/ /* Handler for notebook scroll-event - switches tabs by scroll direction */ static gboolean sakura_notebook_scroll_cb (GtkWidget *widget, GdkEventScroll *event) { /* This callback cause undesirable scroll (when the mouse is over the vte window) when using * input methods like hime. Disable it by now */ /* gint page, npages; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); switch (event->direction) { case GDK_SCROLL_DOWN: gtk_notebook_set_current_page(GTK_NOTEBOOK(sakura.notebook), --page >= 0 ? page : npages - 1); break; case GDK_SCROLL_UP: gtk_notebook_set_current_page(GTK_NOTEBOOK(sakura.notebook), ++page < npages ? page : 0); break; case GDK_SCROLL_LEFT: case GDK_SCROLL_RIGHT: case GDK_SCROLL_SMOOTH: break; } */ return FALSE; } /* Callback called when the user switches tabs or closes a tab (but not when a tab is added) */ static void sakura_switch_page_cb (GtkWidget *widget, GtkWidget *widget_page, guint page_num, void *data) { struct sakura_tab *sk_tab; /* Don't use gtk_notebook_get_current_page in the callbacks, it returns the previous page */ sk_tab = sakura_get_sktab(sakura, page_num); /* Update the window title when a new tab is selected, but don't when an user title has been set */ //if (!sakura.tab_default_title && !sakura.main_title) if (!sakura.main_title) { if (g_strcmp0(gtk_label_get_text(GTK_LABEL(sk_tab->label)),"")!=0) { gtk_window_set_title(GTK_WINDOW(sakura.main_window), gtk_label_get_text(GTK_LABEL(sk_tab->label))); } } } static void sakura_page_removed_cb (GtkWidget *widget, void *data) { if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook))==1) { /* If the first tab is disabled, window size changes and we need to recalculate its size */ sakura_set_size(); } } /* Callback for focus-in-event to the notebook widget */ static gboolean sakura_notebook_focus_cb (GtkWindow *window, GdkEvent *event, void *data) { struct sakura_tab *sk_tab; gint page; if (event->type != GDK_FOCUS_CHANGE) return FALSE; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); /* When clicking several times in the label, terminal loses its focus. * So, when the notebook got the focus, make sure the terminal HAS te focus */ gtk_widget_grab_focus(sk_tab->vte); return FALSE; } /* Callback for clicking in the tabs close buttons */ static void sakura_closebutton_clicked_cb (GtkWidget *widget, void *data) { GtkWidget *hbox = (GtkWidget *)data; gint page; page = gtk_notebook_page_num(GTK_NOTEBOOK(sakura.notebook), hbox); sakura_close_tab(page); } /* Callback for clicking in the tabs labels */ static gboolean sakura_label_clicked_cb (GtkWidget *widget, GdkEventButton *button_event, void *data) { GtkWidget *hbox = (GtkWidget *)data; struct sakura_tab *sk_tab; gint page; page = gtk_notebook_page_num(GTK_NOTEBOOK(sakura.notebook), hbox); sk_tab = sakura_get_sktab(sakura, page); /* Not interested in non button press events */ if (button_event->type != GDK_BUTTON_PRESS) return FALSE; /* Left button click. We HAVE to propagate the event, or things like tab moving won't work */ if (button_event->button == 1) { gtk_widget_grab_focus(sk_tab->vte); return FALSE; } /* Ignore right click and propagate the event */ if (button_event->button == 3) return FALSE; /* The middle button was clicked, so close the tab */ sakura_close_tab(page); return TRUE; } /*****************/ /* VTE callbacks */ /*****************/ /* Callback for button release on the vte terminal. Used for copy-on-selection to clipboard */ static gboolean sakura_term_buttonreleased_cb (GtkWidget *widget, GdkEventButton *button_event, gpointer user_data) { if (button_event->type != GDK_BUTTON_RELEASE) return FALSE; if (sakura.copy_on_select) if (button_event->button == 1) sakura_copy(); return FALSE; } static gboolean sakura_term_buttonpressed_cb (GtkWidget *widget, GdkEventButton *button_event, gpointer user_data) { struct sakura_tab *sk_tab; gint page, tag; if (button_event->type != GDK_BUTTON_PRESS) return FALSE; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); /* Find out if cursor it's over a matched expression...*/ sakura.current_match = vte_terminal_match_check_event(VTE_TERMINAL(sk_tab->vte), (GdkEvent *) button_event, &tag); /* Left button with accelerator: open the URL if any */ if (button_event->button == 1 && ((button_event->state & sakura.open_url_accelerator) == sakura.open_url_accelerator) && sakura.current_match) { sakura_open_url_cb(NULL, NULL); return TRUE; } /* Paste when paste button is pressed */ if (sakura.copy_on_select) { if (button_event->button == sakura.paste_button) { sakura_paste_primary(); /* This is the expected X11 behaviour, to copy the PRIMARY clipboard with the middle click. TODO: Maybe add an option to use the secondary one? */ /* Do not propagate. vte has his own copy-on-select and we'll end with duplicates pastes */ return TRUE; } } /* Show the popup menu when menu button is pressed */ if (button_event->button == sakura.menu_button) { GtkMenu *menu; menu = GTK_MENU (user_data); if (sakura.current_match) { /* Show the extra options in the menu */ char *matches; /* Is it a mail address? */ if (vte_terminal_event_check_regex_simple(VTE_TERMINAL(sk_tab->vte), (GdkEvent *) button_event, &sakura.mail_vteregexp, 1, 0, &matches)) { gtk_widget_show(sakura.item_open_mail); gtk_widget_hide(sakura.item_open_link); } else { gtk_widget_show(sakura.item_open_link); gtk_widget_hide(sakura.item_open_mail); } gtk_widget_show(sakura.item_copy_link); gtk_widget_show(sakura.open_link_separator); g_free(matches); } else { /* Hide all the options */ gtk_widget_hide(sakura.item_open_mail); gtk_widget_hide(sakura.item_open_link); gtk_widget_hide(sakura.item_copy_link); gtk_widget_hide(sakura.open_link_separator); } gtk_menu_popup_at_pointer(menu, (GdkEvent *) button_event); return TRUE; } return FALSE; } static void sakura_beep_cb (GtkWidget *widget, void *data) { /* Remove the urgency hint. This is necessary to signal the window manager */ /* that a new urgent event happened when the urgent hint is set after this. */ /* TODO: this is already set in focus_in, so DO we really need it here? */ gtk_window_set_urgency_hint(GTK_WINDOW(sakura.main_window), FALSE); /* If the window is active(focused), ignore and don't set the urgency hint */ if (!gtk_window_is_active(GTK_WINDOW(sakura.main_window))) { if (sakura.urgent_bell) { gtk_window_set_urgency_hint(GTK_WINDOW(sakura.main_window), TRUE); } } } static void sakura_increase_font_cb (GtkWidget *widget, void *data) { gint new_size; /* Increment font size one unit */ new_size = pango_font_description_get_size(sakura.font)+PANGO_SCALE; pango_font_description_set_size(sakura.font, new_size); sakura_set_font(); sakura_set_size(); sakura_set_config_string("font", pango_font_description_to_string(sakura.font)); } static void sakura_decrease_font_cb (GtkWidget *widget, void *data) { gint new_size; /* Decrement font size one unit */ new_size = pango_font_description_get_size(sakura.font)-PANGO_SCALE; /* Set a minimal size */ if (new_size >= FONT_MINIMAL_SIZE) { pango_font_description_set_size(sakura.font, new_size); sakura_set_font(); sakura_set_size(); sakura_set_config_string("font", pango_font_description_to_string(sakura.font)); } } static void sakura_child_exited_cb (GtkWidget *widget, void *data) { gint page, npages; struct sakura_tab *sk_tab; page = gtk_notebook_page_num(GTK_NOTEBOOK(sakura.notebook), gtk_widget_get_parent(widget)); npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); /* Only write configuration to disk if it's the last tab */ if (npages==1) { sakura_config_done(); } if (option_hold==TRUE) { SAY("hold option has been activated"); return; } /* Child should be automatically reaped because we don't use G_SPAWN_DO_NOT_REAP_CHILD flag */ g_spawn_close_pid(sk_tab->pid); sakura_del_tab(page); npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); if (npages == 0) sakura_destroy(); } static void sakura_eof_cb (GtkWidget *widget, void *data) { SAY("Got EOF signal"); } /* This handler is called when vte window title changes (i.e.: cwd changes), * and it is used to change window and notebook pages titles */ static void sakura_title_changed_cb (GtkWidget *widget, void *data) { struct sakura_tab *sk_tab; const char *tabtitle; gint modified_page; VteTerminal *vte_term=(VteTerminal *)widget; modified_page = sakura_find_tab(vte_term); sk_tab = sakura_get_sktab(sakura, modified_page); tabtitle = vte_terminal_get_window_title(VTE_TERMINAL(sk_tab->vte)); /* User set values overrides any other one */ if (!sk_tab->label_set_byuser) { sakura_set_tab_label_text(tabtitle, modified_page); if (!sakura.main_title) gtk_window_set_title(GTK_WINDOW(sakura.main_window), tabtitle); } } static gboolean sakura_delete_event_cb (GtkWidget *widget, void *data) { struct sakura_tab *sk_tab; GtkWidget *dialog; gint response; gint npages; gint i; pid_t pgid; if (!sakura.less_questions) { npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); /* Check for each tab if there are running processes. Use tcgetpgrp to compare to the shell PGID */ for (i=0; i < npages; i++) { sk_tab = sakura_get_sktab(sakura, i); pgid = tcgetpgrp(vte_pty_get_fd(vte_terminal_get_pty(VTE_TERMINAL(sk_tab->vte)))); /* If running processes are found, we ask one time and exit */ if ( (pgid != -1) && (pgid != sk_tab->pid)) { dialog=gtk_message_dialog_new(GTK_WINDOW(sakura.main_window), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("There are running processes.\n\nDo you really want to close Sakura?")); response=gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); if (response==GTK_RESPONSE_YES) { sakura_config_done(); return FALSE; } else { return TRUE; } } } } sakura_config_done(); return FALSE; } static void sakura_destroy_window_cb (GtkWidget *widget, void *data) { sakura_destroy(); } /**********************/ /* Menuitem callbacks */ /**********************/ static void sakura_font_dialog_cb (GtkWidget *widget, void *data) { GtkWidget *font_dialog; gint response; font_dialog = gtk_font_chooser_dialog_new(_("Select font"), GTK_WINDOW(sakura.main_window)); gtk_font_chooser_set_font_desc(GTK_FONT_CHOOSER(font_dialog), sakura.font); response = gtk_dialog_run(GTK_DIALOG(font_dialog)); if (response == GTK_RESPONSE_OK) { pango_font_description_free(sakura.font); sakura.font = gtk_font_chooser_get_font_desc(GTK_FONT_CHOOSER(font_dialog)); sakura_set_font(); sakura_set_size(); sakura_set_config_string("font", pango_font_description_to_string(sakura.font)); } gtk_widget_destroy(font_dialog); } static void sakura_set_name_dialog_cb (GtkWidget *widget, void *data) { GtkWidget *input_dialog, *input_header; GtkWidget *entry, *label; GtkWidget *name_hbox; /* We need this for correct spacing */ gint response; gint page; struct sakura_tab *sk_tab; const gchar *text; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); input_dialog=gtk_dialog_new_with_buttons(_("Set tab name"), GTK_WINDOW(sakura.main_window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Apply"), GTK_RESPONSE_ACCEPT, NULL); /* Configure the new gtk header bar*/ input_header = gtk_dialog_get_header_bar(GTK_DIALOG(input_dialog)); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(input_header), FALSE); gtk_dialog_set_default_response(GTK_DIALOG(input_dialog), GTK_RESPONSE_ACCEPT); /* Create dialog contents */ name_hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); entry=gtk_entry_new(); label=gtk_label_new(_("New text")); /* Set tab label as entry default text (when first tab is not displayed, get_tab_label_text returns a null value, so check accordingly */ /* FIXME: Check why is returning NULL */ text = gtk_notebook_get_tab_label_text(GTK_NOTEBOOK(sakura.notebook), sk_tab->hbox); if (text) { SAY("TEXT %s", text); gtk_entry_set_text(GTK_ENTRY(entry), text); } gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); gtk_box_pack_start(GTK_BOX(name_hbox), label, TRUE, TRUE, 12); gtk_box_pack_start(GTK_BOX(name_hbox), entry, TRUE, TRUE, 12); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(input_dialog))), name_hbox, FALSE, FALSE, 12); /* Disable accept button until some text is entered */ g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(sakura_setname_entry_changed_cb), input_dialog); gtk_dialog_set_response_sensitive(GTK_DIALOG(input_dialog), GTK_RESPONSE_ACCEPT, FALSE); gtk_widget_show_all(name_hbox); response = gtk_dialog_run(GTK_DIALOG(input_dialog)); if (response == GTK_RESPONSE_ACCEPT) { sakura_set_tab_label_text(gtk_entry_get_text(GTK_ENTRY(entry)), page); gtk_window_set_title(GTK_WINDOW(sakura.main_window), gtk_entry_get_text(GTK_ENTRY(entry))); sk_tab->label_set_byuser=true; sakura.main_title=NULL; /* Ignore the user-set window title if the user names the tab */ } gtk_widget_destroy(input_dialog); } /* Callback for the color dialog signals. Used to UPDATE the contents of that dialog (passed as 'data') */ static void sakura_color_dialog_changed_cb ( GtkWidget *widget, void *data) { GtkDialog *dialog = (GtkDialog*) data; GtkColorButton *fore_button = g_object_get_data (G_OBJECT(dialog), "fore_button"); GtkColorButton *back_button = g_object_get_data (G_OBJECT(dialog), "back_button"); GtkColorButton *curs_button = g_object_get_data (G_OBJECT(dialog), "curs_button"); GdkRGBA *forecolors = g_object_get_data (G_OBJECT(dialog), "fore"); GdkRGBA *backcolors = g_object_get_data (G_OBJECT(dialog), "back"); GdkRGBA *curscolors = g_object_get_data (G_OBJECT(dialog), "curs"); GtkComboBox *cs_combo = g_object_get_data (G_OBJECT(dialog), "cs_combo"); GtkComboBox *scheme_combo = g_object_get_data (G_OBJECT(dialog), "scheme_combo"); GtkSpinButton *opacity_spin = g_object_get_data (G_OBJECT(dialog), "opacity_spin"); GtkCheckButton *bib_checkbutton = g_object_get_data (G_OBJECT(dialog), "bib_checkbutton"); gint current_cs = gtk_combo_box_get_active(cs_combo); /* If we come here as a result of a change in the active colorset, load the new colorset to the buttons. * Else, the color buttons or opacity spin have gotten a new value, store that. */ if ((GtkWidget *)cs_combo == widget ) { /* Spin opacity is a percentage, convert it*/ gint new_opacity = (int) (backcolors[current_cs].alpha*100); gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(fore_button), &forecolors[current_cs]); gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(back_button), &backcolors[current_cs]); gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(curs_button), &curscolors[current_cs]); gtk_spin_button_set_value(opacity_spin, new_opacity); gtk_combo_box_set_active(GTK_COMBO_BOX(scheme_combo), sakura.schemes[current_cs]); } else if ((GtkWidget *)scheme_combo == widget) { /* Scheme has changed, update the buttons. No cursor and no alpha */ int selected_scheme = gtk_combo_box_get_active(GTK_COMBO_BOX(scheme_combo)); if (selected_scheme != 0) { float old_alpha = backcolors[current_cs].alpha; /* Keep the previous alpha */ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(fore_button), &predefined_schemes[selected_scheme].fg); gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(back_button), &predefined_schemes[selected_scheme].bg); forecolors[current_cs] = predefined_schemes[selected_scheme].fg; backcolors[current_cs] = predefined_schemes[selected_scheme].bg; backcolors[current_cs].alpha = old_alpha; sakura.schemes[current_cs] = selected_scheme; } /* else Custom, do nothing */ } else if ((GtkWidget *)bib_checkbutton == widget) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bib_checkbutton))) { sakura.bold_is_bright = true; } else { sakura.bold_is_bright = false; } } else { gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(fore_button), &forecolors[current_cs]); gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(back_button), &backcolors[current_cs]); gtk_color_chooser_get_rgba(GTK_COLOR_CHOOSER(curs_button), &curscolors[current_cs]); gtk_spin_button_update(opacity_spin); backcolors[current_cs].alpha = gtk_spin_button_get_value(opacity_spin)/100; /* User changed colors. Set custom scheme */ sakura.schemes[current_cs] = 0; gtk_combo_box_set_active(GTK_COMBO_BOX(scheme_combo), sakura.schemes[current_cs]); } } /* Dialog to select foreground, background and cursors colors, transparency and palette */ static void sakura_color_dialog_cb (GtkWidget *widget, void *data) { GtkWidget *color_dialog; GtkWidget *color_header; GtkWidget *cs_label, *scheme_label, *fore_label, *back_label, *curs_label, *opacity_label, *palette_label; GtkWidget *cs_combo, *scheme_combo, *fore_button, *back_button, *curs_button, *palette_combo, *opacity_spin; GtkWidget *cs_hbox, *scheme_hbox, *fore_hbox, *back_hbox, *curs_hbox, *opacity_hbox, *palette_hbox, *bib_hbox; GtkWidget *bib_checkbutton; GdkRGBA temp_fore[NUM_COLORSETS]; GdkRGBA temp_back[NUM_COLORSETS]; GdkRGBA temp_curs[NUM_COLORSETS]; GtkAdjustment *spin_adj; struct sakura_tab *sk_tab; gint response; gint page, i; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); color_dialog = gtk_dialog_new_with_buttons(_("Select colors"), GTK_WINDOW(sakura.main_window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Select"), GTK_RESPONSE_ACCEPT, NULL); /* Configure the new gtk header bar */ color_header = gtk_dialog_get_header_bar(GTK_DIALOG(color_dialog)); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(color_header), FALSE); gtk_dialog_set_default_response(GTK_DIALOG(color_dialog), GTK_RESPONSE_ACCEPT); /* Add the combobox to select the current colorset */ cs_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); cs_label = gtk_label_new(_("Colorset")); cs_combo = gtk_combo_box_text_new(); gchar combo_text[3]; for (i=0; i < NUM_COLORSETS; i++) { g_snprintf(combo_text, 2, "%d", i+1); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(cs_combo), NULL, combo_text); } gtk_combo_box_set_active(GTK_COMBO_BOX(cs_combo), sk_tab->colorset); /* Add the scheme combobox */ scheme_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); scheme_label = gtk_label_new(_("Color scheme")); scheme_combo = gtk_combo_box_text_new(); for (i=0; i < NUM_SCHEMES; i++) { gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(scheme_combo), NULL, predefined_schemes[i].name); } gtk_combo_box_set_active(GTK_COMBO_BOX(scheme_combo), sakura.schemes[sk_tab->colorset]); /* Foreground and background and cursor color buttons */ fore_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); back_hbox = gtk_box_new(FALSE, 12); curs_hbox = gtk_box_new(FALSE, 12); fore_label = gtk_label_new(_("Foreground color")); back_label = gtk_label_new(_("Background color")); curs_label = gtk_label_new(_("Cursor color")); fore_button = gtk_color_button_new_with_rgba(&sakura.forecolors[sk_tab->colorset]); back_button = gtk_color_button_new_with_rgba(&sakura.backcolors[sk_tab->colorset]); curs_button = gtk_color_button_new_with_rgba(&sakura.curscolors[sk_tab->colorset]); /* Opacity control */ opacity_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); spin_adj = gtk_adjustment_new ((sakura.backcolors[sk_tab->colorset].alpha)*100, 0.0, 100.0, 1.0, 5.0, 0); opacity_spin = gtk_spin_button_new(GTK_ADJUSTMENT(spin_adj), 1.0, 0); opacity_label = gtk_label_new(_("Opacity level (%)")); /* Palette combobox */ palette_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); palette_label = gtk_label_new(_("Palette")); palette_combo = gtk_combo_box_text_new(); for (i=0; i < (sizeof(palettes_names)) / (sizeof(palettes_names[0])); i++) { gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(palette_combo), NULL, palettes_names[i]); } gtk_combo_box_set_active(GTK_COMBO_BOX(palette_combo), sakura.palette_idx); /* Bold is bright checkbutton */ bib_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); bib_checkbutton = gtk_check_button_new_with_label(_("Use bright colors for bold text")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bib_checkbutton), sakura.bold_is_bright); gtk_box_pack_start(GTK_BOX(cs_hbox), cs_label, FALSE, FALSE, 12); gtk_box_pack_end(GTK_BOX(cs_hbox), cs_combo, FALSE, FALSE, 12); gtk_box_pack_start(GTK_BOX(scheme_hbox), scheme_label, FALSE, FALSE, 12); gtk_box_pack_end(GTK_BOX(scheme_hbox), scheme_combo, FALSE, FALSE, 12); gtk_box_pack_start(GTK_BOX(fore_hbox), fore_label, FALSE, FALSE, 12); gtk_box_pack_end(GTK_BOX(fore_hbox), fore_button, FALSE, FALSE, 12); gtk_box_pack_start(GTK_BOX(back_hbox), back_label, FALSE, FALSE, 12); gtk_box_pack_end(GTK_BOX(back_hbox), back_button, FALSE, FALSE, 12); gtk_box_pack_start(GTK_BOX(curs_hbox), curs_label, FALSE, FALSE, 12); gtk_box_pack_end(GTK_BOX(curs_hbox), curs_button, FALSE, FALSE, 12); gtk_box_pack_start(GTK_BOX(opacity_hbox), opacity_label, FALSE, FALSE, 12); gtk_box_pack_end(GTK_BOX(opacity_hbox), opacity_spin, FALSE, FALSE, 12); gtk_box_pack_start(GTK_BOX(palette_hbox), palette_label, FALSE, FALSE, 12); gtk_box_pack_end(GTK_BOX(palette_hbox), palette_combo, FALSE, FALSE, 12); gtk_box_pack_start(GTK_BOX(bib_hbox), bib_checkbutton, FALSE, FALSE, 12); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))), cs_hbox, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))), scheme_hbox, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))), fore_hbox, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))), back_hbox, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))), curs_hbox, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))), opacity_hbox, FALSE, FALSE, 6); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))), palette_hbox, FALSE, FALSE, 6); gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))), bib_hbox, FALSE, FALSE, 6); gtk_widget_show_all(gtk_dialog_get_content_area(GTK_DIALOG(color_dialog))); /* When the user switches the colorset, callback needs access to these selector widgets */ g_object_set_data(G_OBJECT(color_dialog), "cs_combo", cs_combo); g_object_set_data(G_OBJECT(color_dialog), "scheme_combo", scheme_combo); g_object_set_data(G_OBJECT(color_dialog), "fore_button", fore_button); g_object_set_data(G_OBJECT(color_dialog), "back_button", back_button); g_object_set_data(G_OBJECT(color_dialog), "curs_button", curs_button); g_object_set_data(G_OBJECT(color_dialog), "opacity_spin", opacity_spin); g_object_set_data(G_OBJECT(color_dialog), "fore", temp_fore); g_object_set_data(G_OBJECT(color_dialog), "back", temp_back); g_object_set_data(G_OBJECT(color_dialog), "curs", temp_curs); g_object_set_data(G_OBJECT(color_dialog), "bib_checkbutton", bib_checkbutton); g_signal_connect(G_OBJECT(cs_combo), "changed", G_CALLBACK(sakura_color_dialog_changed_cb), color_dialog); g_signal_connect(G_OBJECT(scheme_combo), "changed", G_CALLBACK(sakura_color_dialog_changed_cb), color_dialog); g_signal_connect(G_OBJECT(fore_button), "color-set", G_CALLBACK(sakura_color_dialog_changed_cb), color_dialog); g_signal_connect(G_OBJECT(back_button), "color-set", G_CALLBACK(sakura_color_dialog_changed_cb), color_dialog); g_signal_connect(G_OBJECT(curs_button), "color-set", G_CALLBACK(sakura_color_dialog_changed_cb), color_dialog); g_signal_connect(G_OBJECT(opacity_spin), "changed", G_CALLBACK(sakura_color_dialog_changed_cb), color_dialog); g_signal_connect(G_OBJECT(bib_checkbutton), "toggled", G_CALLBACK(sakura_color_dialog_changed_cb), color_dialog); for (i=0; icolorset = gtk_combo_box_get_active(GTK_COMBO_BOX(cs_combo)); sakura_set_config_integer("last_colorset", sk_tab->colorset+1); /* Set the selected palette */ guint palette_idx = gtk_combo_box_get_active(GTK_COMBO_BOX(palette_combo)); sakura.palette = palettes[palette_idx]; sakura.palette_idx = palette_idx; sakura_set_config_integer("palette", sakura.palette_idx); /* Set bold is bright option */ sakura_set_config_boolean("bold_is_bright", sakura.bold_is_bright); /* Apply the new colorsets to all tabs */ sakura_set_colors(); } gtk_widget_destroy(color_dialog); } #if 0 static void sakura_set_title_dialog (GtkWidget *widget, void *data) { GtkWidget *title_dialog, *title_header; GtkWidget *entry, *label; GtkWidget *title_hbox; gint response; title_dialog=gtk_dialog_new_with_buttons(_("Set window title"), GTK_WINDOW(sakura.main_window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Apply"), GTK_RESPONSE_ACCEPT, NULL); /* Configure the new gtk header bar*/ title_header=gtk_dialog_get_header_bar(GTK_DIALOG(title_dialog)); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(title_header), FALSE); gtk_dialog_set_default_response(GTK_DIALOG(title_dialog), GTK_RESPONSE_ACCEPT); entry=gtk_entry_new(); label=gtk_label_new(_("New window title")); title_hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); /* Set window label as entry default text */ gtk_entry_set_text(GTK_ENTRY(entry), gtk_window_get_title(GTK_WINDOW(sakura.main_window))); gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); gtk_box_pack_start(GTK_BOX(title_hbox), label, TRUE, TRUE, 12); gtk_box_pack_start(GTK_BOX(title_hbox), entry, TRUE, TRUE, 12); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(title_dialog))), title_hbox, FALSE, FALSE, 12); /* Disable accept button until some text is entered */ g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(sakura_setname_entry_changed), title_dialog); gtk_dialog_set_response_sensitive(GTK_DIALOG(title_dialog), GTK_RESPONSE_ACCEPT, FALSE); gtk_widget_show_all(title_hbox); response=gtk_dialog_run(GTK_DIALOG(title_dialog)); if (response==GTK_RESPONSE_ACCEPT) { /* Bug #257391 shadow reaches here too... */ gtk_window_set_title(GTK_WINDOW(sakura.main_window), gtk_entry_get_text(GTK_ENTRY(entry))); } gtk_widget_destroy(title_dialog); } #endif static void sakura_copy_url_cb (GtkWidget *widget, void *data) { GtkClipboard* clip; clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); gtk_clipboard_set_text(clip, sakura.current_match, -1 ); //clip = gtk_clipboard_get(GDK_SELECTION_PRIMARY); //gtk_clipboard_set_text(clip, sakura.current_match, -1 ); } static void sakura_open_url_cb (GtkWidget *widget, void *data) { GError *error=NULL; gchar *browser=NULL; SAY("Opening %s", sakura.current_match); browser = g_strdup(g_getenv("BROWSER")); if (!browser) { if ( !(browser = g_find_program_in_path("xdg-open")) ) { sakura_error("Browser not found"); } } if (browser) { gchar * argv[] = {browser, sakura.current_match, NULL}; if (!g_spawn_async(".", argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) { sakura_error("Couldn't exec \"%s %s\": %s", browser, sakura.current_match, error->message); g_error_free(error); } g_free(browser); } } static void sakura_open_mail_cb (GtkWidget *widget, void *data) { GError *error = NULL; gchar *program = NULL; if ( (program = g_find_program_in_path("xdg-email")) ) { gchar * argv[] = { program, sakura.current_match, NULL }; if (!g_spawn_async(".", argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error)) { sakura_error("Couldn't exec \"%s %s\": %s", program, sakura.current_match, error->message); } g_free(program); } } static void sakura_show_tab_bar_cb (GtkWidget *widget, void *data) { char *setting_string = (char *)data; char *config_string; gboolean show_tabs; if (strcmp(setting_string, "always")==0) { sakura.show_tab_bar = SHOW_TAB_BAR_ALWAYS; config_string = "always"; show_tabs = TRUE; } else if (strcmp(setting_string, "multiple")==0) { sakura.show_tab_bar = SHOW_TAB_BAR_MULTIPLE; config_string = "multiple"; show_tabs = (gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)) != 1); } else if (strcmp(setting_string, "never")==0) { sakura.show_tab_bar = SHOW_TAB_BAR_NEVER; config_string = "never"; show_tabs = FALSE; } sakura_set_config_string("show_tab_bar", config_string); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(sakura.notebook), show_tabs); sakura_set_size(); } static void sakura_tabs_on_bottom_cb (GtkWidget *widget, void *data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { gtk_notebook_set_tab_pos(GTK_NOTEBOOK(sakura.notebook), GTK_POS_BOTTOM); sakura_set_config_boolean("tabs_on_bottom", TRUE); } else { gtk_notebook_set_tab_pos(GTK_NOTEBOOK(sakura.notebook), GTK_POS_TOP); sakura_set_config_boolean("tabs_on_bottom", FALSE); } } static void sakura_less_questions_cb (GtkWidget *widget, void *data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { sakura.less_questions = TRUE; sakura_set_config_boolean("less_questions", TRUE); } else { sakura.less_questions = FALSE; sakura_set_config_boolean("less_questions", FALSE); } } static void sakura_copy_on_select_cb (GtkWidget *widget, void *data) { sakura.copy_on_select = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); if (sakura.copy_on_select) { sakura_set_config_boolean("copy_on_select", TRUE); } else { sakura_set_config_boolean("copy_on_select", FALSE); } } static void sakura_new_tab_after_current_cb (GtkWidget *widget, void *data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { sakura.new_tab_after_current=TRUE; sakura_set_config_boolean("new_tab_after_current", TRUE); } else { sakura.new_tab_after_current=FALSE; sakura_set_config_boolean("new_tab_after_current", FALSE); } } static void sakura_show_scrollbar_cb (GtkWidget *widget, void *data) { sakura_show_scrollbar(); } static void sakura_urgent_bell_cb (GtkWidget *widget, void *data) { sakura.urgent_bell = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); if (sakura.urgent_bell) { sakura_set_config_string("urgent_bell", "Yes"); } else { sakura_set_config_string("urgent_bell", "No"); } } static void sakura_audible_bell_cb (GtkWidget *widget, void *data) { gint page; struct sakura_tab *sk_tab; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { vte_terminal_set_audible_bell (VTE_TERMINAL(sk_tab->vte), TRUE); sakura_set_config_string("audible_bell", "Yes"); } else { vte_terminal_set_audible_bell (VTE_TERMINAL(sk_tab->vte), FALSE); sakura_set_config_string("audible_bell", "No"); } } static void sakura_blinking_cursor_cb (GtkWidget *widget, void *data) { gint page; struct sakura_tab *sk_tab; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { vte_terminal_set_cursor_blink_mode (VTE_TERMINAL(sk_tab->vte), VTE_CURSOR_BLINK_ON); sakura_set_config_string("blinking_cursor", "Yes"); } else { vte_terminal_set_cursor_blink_mode (VTE_TERMINAL(sk_tab->vte), VTE_CURSOR_BLINK_OFF); sakura_set_config_string("blinking_cursor", "No"); } } static void sakura_set_cursor_cb (GtkWidget *widget, void *data) { struct sakura_tab *sk_tab; int n_pages, i; char *cursor_string = (char *)data; n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { if (strcmp(cursor_string, "block")==0) { sakura.cursor_type=VTE_CURSOR_SHAPE_BLOCK; } else if (strcmp(cursor_string, "underline")==0) { sakura.cursor_type=VTE_CURSOR_SHAPE_UNDERLINE; } else if (strcmp(cursor_string, "ibeam")==0) { sakura.cursor_type=VTE_CURSOR_SHAPE_IBEAM; } for (i = (n_pages - 1); i >= 0; i--) { sk_tab = sakura_get_sktab(sakura, i); vte_terminal_set_cursor_shape(VTE_TERMINAL(sk_tab->vte), sakura.cursor_type); } sakura_set_config_integer("cursor_type", sakura.cursor_type); } } static void sakura_setname_entry_changed_cb (GtkWidget *widget, void *data) { GtkDialog *title_dialog=(GtkDialog *)data; if (strcmp(gtk_entry_get_text(GTK_ENTRY(widget)), "")==0) { gtk_dialog_set_response_sensitive(GTK_DIALOG(title_dialog), GTK_RESPONSE_ACCEPT, FALSE); } else { gtk_dialog_set_response_sensitive(GTK_DIALOG(title_dialog), GTK_RESPONSE_ACCEPT, TRUE); } } /* Parameters are never used */ static void sakura_copy_cb (GtkWidget *widget, void *data) { sakura_copy(); } /* Parameters are never used */ static void sakura_paste_cb (GtkWidget *widget, void *data) { sakura_paste(); } static void sakura_new_tab_cb (GtkWidget *widget, void *data) { sakura_add_tab(); } static void sakura_close_tab_cb (GtkWidget *widget, void *data) { gint page; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sakura_close_tab(page); } static void sakura_fullscreen_cb (GtkWidget *widget, void *data) { if (!sakura.fullscreen) { sakura.fullscreen = TRUE; gtk_window_fullscreen(GTK_WINDOW(sakura.main_window)); } else { sakura.fullscreen = FALSE; gtk_window_unfullscreen(GTK_WINDOW(sakura.main_window)); } } static void sakura_disable_numbered_tabswitch_cb (GtkWidget *widget, void *data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { sakura.disable_numbered_tabswitch = true; sakura_set_config_boolean("disable_numbered_tabswitch", TRUE); } else { sakura.disable_numbered_tabswitch = false; sakura_set_config_boolean("disable_numbered_tabswitch", FALSE); } } #if 0 static void sakura_use_fading_cb (GtkWidget *widget, void *data) { if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { sakura.use_fading = true; sakura_set_config_boolean("use_fading", TRUE); } else { sakura.use_fading = false; sakura_set_config_boolean("use_fading", FALSE); } } #endif /**************************/ /******* Functions ********/ /**************************/ static void sakura_init() { GError *gerror=NULL; char* configdir = NULL; int i; term_data_id = g_quark_from_static_string("sakura_term"); /*** Config file initialization ***/ sakura.cfg = g_key_file_new(); sakura.config_modified=false; configdir = g_build_filename( g_get_user_config_dir(), "sakura", NULL ); if ( ! g_file_test( g_get_user_config_dir(), G_FILE_TEST_EXISTS) ) g_mkdir( g_get_user_config_dir(), 0755 ); if ( ! g_file_test( configdir, G_FILE_TEST_EXISTS) ) g_mkdir( configdir, 0755 ); if (option_config_file) { sakura.configfile = g_build_filename(configdir, option_config_file, NULL); } else { /* Use more standard-conforming path for config files, if available. */ sakura.configfile = g_build_filename(configdir, DEFAULT_CONFIGFILE, NULL); } g_free(configdir); /* Open config file */ if (!g_key_file_load_from_file(sakura.cfg, sakura.configfile, 0, &gerror)) { /* If there's no file, ignore the error. A new one is created */ if (gerror->code==G_KEY_FILE_ERROR_UNKNOWN_ENCODING || gerror->code==G_KEY_FILE_ERROR_INVALID_VALUE) { g_error_free(gerror); fprintf(stderr, "Not valid config file format\n"); exit(EXIT_FAILURE); } } /* Add GFile monitor to control file external changes */ GFile *cfgfile = g_file_new_for_path(sakura.configfile); GFileMonitor *mon_cfgfile = g_file_monitor_file (cfgfile, 0, NULL, NULL); g_signal_connect(G_OBJECT(mon_cfgfile), "changed", G_CALLBACK(sakura_conf_changed_cb), NULL); gchar *cfgtmp = NULL; /* We can safely ignore errors from g_key_file_get_value(), since if the * call to g_key_file_has_key() was successful, the key IS there. From the * glib docs I don't know if we can ignore errors from g_key_file_has_key, * too. I think we can: the only possible error is that the config file * doesn't exist, but we have just read it! */ for (i=0; icode == G_KEY_FILE_ERROR_INVALID_VALUE) { sakura.palette_idx = DEFAULT_PALETTE; sakura_set_config_integer("palette", DEFAULT_PALETTE); g_error_free(gerror); } sakura.palette = palettes[sakura.palette_idx]; /* Keybindings are only in the config file */ if (!g_key_file_has_key(sakura.cfg, cfg_group, "add_tab_accelerator", NULL)) { sakura_set_config_integer("add_tab_accelerator", DEFAULT_ADD_TAB_ACCELERATOR); } sakura.add_tab_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "add_tab_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "del_tab_accelerator", NULL)) { sakura_set_config_integer("del_tab_accelerator", DEFAULT_DEL_TAB_ACCELERATOR); } sakura.del_tab_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "del_tab_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "switch_tab_accelerator", NULL)) { sakura_set_config_integer("switch_tab_accelerator", DEFAULT_SWITCH_TAB_ACCELERATOR); } sakura.switch_tab_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "switch_tab_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "move_tab_accelerator", NULL)) { sakura_set_config_integer("move_tab_accelerator", DEFAULT_MOVE_TAB_ACCELERATOR); } sakura.move_tab_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "move_tab_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "copy_accelerator", NULL)) { sakura_set_config_integer("copy_accelerator", DEFAULT_COPY_ACCELERATOR); } sakura.copy_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "copy_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "scrollbar_accelerator", NULL)) { sakura_set_config_integer("scrollbar_accelerator", DEFAULT_SCROLLBAR_ACCELERATOR); } sakura.scrollbar_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "scrollbar_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "open_url_accelerator", NULL)) { sakura_set_config_integer("open_url_accelerator", DEFAULT_OPEN_URL_ACCELERATOR); } sakura.open_url_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "open_url_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "font_size_accelerator", NULL)) { sakura_set_config_integer("font_size_accelerator", DEFAULT_FONT_SIZE_ACCELERATOR); } sakura.font_size_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "font_size_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "set_tab_name_accelerator", NULL)) { sakura_set_config_integer("set_tab_name_accelerator", DEFAULT_SET_TAB_NAME_ACCELERATOR); } sakura.set_tab_name_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "set_tab_name_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "search_accelerator", NULL)) { sakura_set_config_integer("search_accelerator", DEFAULT_SEARCH_ACCELERATOR); } sakura.search_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "search_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "new_window_accelerator", NULL)) { sakura_set_config_integer("new_window_accelerator", DEFAULT_NEW_WINDOW_ACCELERATOR); } sakura.new_window_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "new_window_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "add_tab_key", NULL)) { sakura_set_keybind("add_tab_key", DEFAULT_ADD_TAB_KEY); } sakura.add_tab_key = sakura_get_keybind("add_tab_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "del_tab_key", NULL)) { sakura_set_keybind("del_tab_key", DEFAULT_DEL_TAB_KEY); } sakura.del_tab_key = sakura_get_keybind("del_tab_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "prev_tab_key", NULL)) { sakura_set_keybind("prev_tab_key", DEFAULT_PREV_TAB_KEY); } sakura.prev_tab_key = sakura_get_keybind("prev_tab_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "next_tab_key", NULL)) { sakura_set_keybind("next_tab_key", DEFAULT_NEXT_TAB_KEY); } sakura.next_tab_key = sakura_get_keybind("next_tab_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "copy_key", NULL)) { sakura_set_keybind( "copy_key", DEFAULT_COPY_KEY); } sakura.copy_key = sakura_get_keybind("copy_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "paste_key", NULL)) { sakura_set_keybind("paste_key", DEFAULT_PASTE_KEY); } sakura.paste_key = sakura_get_keybind("paste_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "scrollbar_key", NULL)) { sakura_set_keybind("scrollbar_key", DEFAULT_SCROLLBAR_KEY); } sakura.scrollbar_key = sakura_get_keybind("scrollbar_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "set_tab_name_key", NULL)) { sakura_set_keybind("set_tab_name_key", DEFAULT_SET_TAB_NAME_KEY); } sakura.set_tab_name_key = sakura_get_keybind("set_tab_name_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "search_key", NULL)) { sakura_set_keybind("search_key", DEFAULT_SEARCH_KEY); } sakura.search_key = sakura_get_keybind("search_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "increase_font_size_key", NULL)) { sakura_set_keybind("increase_font_size_key", DEFAULT_INCREASE_FONT_SIZE_KEY); } sakura.increase_font_size_key = sakura_get_keybind("increase_font_size_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "decrease_font_size_key", NULL)) { sakura_set_keybind("decrease_font_size_key", DEFAULT_DECREASE_FONT_SIZE_KEY); } sakura.decrease_font_size_key = sakura_get_keybind("decrease_font_size_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "fullscreen_key", NULL)) { sakura_set_keybind("fullscreen_key", DEFAULT_FULLSCREEN_KEY); } sakura.fullscreen_key = sakura_get_keybind("fullscreen_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "new_window_key", NULL)) { sakura_set_keybind("new_window_key", DEFAULT_NEW_WINDOW_KEY); } sakura.new_window_key = sakura_get_keybind("new_window_key"); if (!g_key_file_has_key(sakura.cfg, cfg_group, "set_colorset_accelerator", NULL)) { sakura_set_config_integer("set_colorset_accelerator", DEFAULT_SELECT_COLORSET_ACCELERATOR); } sakura.set_colorset_accelerator = g_key_file_get_integer(sakura.cfg, cfg_group, "set_colorset_accelerator", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "icon_file", NULL)) { sakura_set_config_string("icon_file", ICON_FILE); } sakura.icon = g_key_file_get_string(sakura.cfg, cfg_group, "icon_file", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "paste_button", NULL)) { sakura_set_config_integer("paste_button", DEFAULT_PASTE_BUTTON); } sakura.paste_button = g_key_file_get_integer(sakura.cfg, cfg_group, "paste_button", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "menu_button", NULL)) { sakura_set_config_integer("menu_button", DEFAULT_MENU_BUTTON); } sakura.menu_button = g_key_file_get_integer(sakura.cfg, cfg_group, "menu_button", NULL); /* NULL if not found. Don't add a new one */ /* Only in config file */ sakura.tab_default_title = g_key_file_get_string(sakura.cfg, cfg_group, "tab_default_title", NULL); sakura.dont_save = g_key_file_get_boolean(sakura.cfg, cfg_group, "dont_save", NULL); /* Default terminal size */ if (!g_key_file_has_key(sakura.cfg, cfg_group, "window_columns", NULL)) { sakura_set_config_integer("window_columns", DEFAULT_COLUMNS); } sakura.columns = g_key_file_get_integer(sakura.cfg, cfg_group, "window_columns", NULL); if (!g_key_file_has_key(sakura.cfg, cfg_group, "window_rows", NULL)) { sakura_set_config_integer("window_rows", DEFAULT_ROWS); } sakura.rows = g_key_file_get_integer(sakura.cfg, cfg_group, "window_rows", NULL); /* Optional only, no need to set it if not found */ sakura.shell_path = g_key_file_get_string(sakura.cfg, cfg_group, "shell_path", NULL); /* Default terminal. Only in config file */ sakura.term = g_key_file_get_value(sakura.cfg, cfg_group, "term", NULL); /*** Sakura window initialization ***/ /* Use always GTK header bar*/ g_object_set(gtk_settings_get_default(), "gtk-dialogs-use-header", TRUE, NULL); /* Create our windows */ sakura.main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(sakura.main_window), "sakura"); gtk_widget_set_name(sakura.main_window, "sakura"); sakura.fade_window = gtk_window_new(GTK_WINDOW_POPUP); gtk_widget_set_name(sakura.fade_window, "fade_window"); gtk_window_set_position(GTK_WINDOW(sakura.fade_window), GTK_WIN_POS_NONE); gtk_widget_set_opacity(sakura.fade_window, FADE_WINDOW_OPACITY); gtk_window_set_transient_for(GTK_WINDOW(sakura.fade_window), GTK_WINDOW(sakura.main_window)); /* Add CSS styles for main and fade window*/ GtkCssProvider *provider = gtk_css_provider_new(); GdkScreen *screen = gtk_widget_get_screen(GTK_WIDGET(sakura.main_window)); gtk_css_provider_load_from_data(provider, SAKURA_CSS, -1, NULL); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_object_unref(provider); provider = gtk_css_provider_new(); screen = gtk_widget_get_screen(GTK_WIDGET(sakura.fade_window)); gtk_css_provider_load_from_data(provider, FADE_WINDOW_CSS, -1, NULL); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); g_object_unref(provider); /* Create notebook and set style */ sakura.notebook = gtk_notebook_new(); gtk_notebook_set_scrollable((GtkNotebook*)sakura.notebook, sakura.scrollable_tabs); /* Adding mask, for handle scroll events */ gtk_widget_add_events(sakura.notebook, GDK_SCROLL_MASK); /* Figure out if we have rgba capabilities. Without this transparency won't work as expected */ screen = gtk_widget_get_screen (GTK_WIDGET (sakura.main_window)); GdkVisual *visual = gdk_screen_get_rgba_visual (screen); if (visual != NULL && gdk_screen_is_composited (screen)) { gtk_widget_set_visual (GTK_WIDGET (sakura.main_window), visual); } /*** Command line options initialization ***/ /* Set argv for forked childs. Real argv vector starts at argv[1] because we're using G_SPAWN_FILE_AND_ARGV_ZERO to be able to launch login shells */ /* If the shell_path has been set in the config file it takes priority over the envvar */ if (sakura.shell_path != NULL) { sakura.argv[0] = g_strdup(sakura.shell_path); sakura.argv[1] = g_strdup(sakura.shell_path); } else { sakura.argv[0] = g_strdup(g_getenv("SHELL")); if (option_login) { sakura.argv[1] = g_strdup_printf("-%s", g_getenv("SHELL")); } else { sakura.argv[1] = g_strdup(g_getenv("SHELL")); } } sakura.argv[2]=NULL; /* Add datadir path to icon name and set icon */ gchar *icon_path; gerror=NULL; if (option_icon) { icon_path = g_strdup_printf("%s", option_icon); } else { icon_path = g_strdup_printf(DATADIR "/pixmaps/%s", sakura.icon); } gtk_window_set_icon_from_file(GTK_WINDOW(sakura.main_window), icon_path, &gerror); g_free(icon_path); icon_path=NULL; if (gerror) g_error_free(gerror); /* More options */ if (option_title) { sakura.main_title = g_strdup_printf("%s", option_title); gtk_window_set_title(GTK_WINDOW(sakura.main_window), sakura.main_title); } else { sakura.main_title = NULL; } if (option_columns) { sakura.columns = option_columns; } if (option_rows) { sakura.rows = option_rows; } if (option_font) { sakura.font=pango_font_description_from_string(option_font); } if (option_colorset && option_colorset>0 && option_colorset <= NUM_COLORSETS) { sakura.last_colorset = option_colorset; } sakura.fullscreen = FALSE; if (option_fullscreen) { sakura_fullscreen_cb(NULL, NULL); /* FIXME: Move to sakura_set_size?? */ } sakura.resized = FALSE; sakura.externally_modified = false; sakura.first_run=true; gerror = NULL; sakura.http_vteregexp = vte_regex_new_for_match(HTTP_REGEXP, strlen(HTTP_REGEXP), PCRE2_MULTILINE, &gerror); if (!sakura.http_vteregexp) { SAY("http_regexp: %s", gerror->message); g_error_free(gerror); } gerror=NULL; sakura.mail_vteregexp = vte_regex_new_for_match(MAIL_REGEXP, strlen(MAIL_REGEXP), PCRE2_MULTILINE, &gerror); if (!sakura.mail_vteregexp) { SAY("mail_regexp: %s", gerror->message); g_error_free(gerror); } gtk_container_add(GTK_CONTAINER(sakura.main_window), sakura.notebook); sakura_init_popup(); g_signal_connect(G_OBJECT(sakura.main_window), "delete_event", G_CALLBACK(sakura_delete_event_cb), NULL); g_signal_connect(G_OBJECT(sakura.main_window), "destroy", G_CALLBACK(sakura_destroy_window_cb), NULL); g_signal_connect(G_OBJECT(sakura.main_window), "key-press-event", G_CALLBACK(sakura_key_press_cb), NULL); g_signal_connect(G_OBJECT(sakura.main_window), "configure-event", G_CALLBACK(sakura_resized_window_cb), NULL); g_signal_connect(G_OBJECT(sakura.main_window), "focus-out-event", G_CALLBACK(sakura_focus_out_cb), NULL); g_signal_connect(G_OBJECT(sakura.main_window), "focus-in-event", G_CALLBACK(sakura_focus_in_cb), NULL); g_signal_connect(G_OBJECT(sakura.main_window), "show", G_CALLBACK(sakura_show_event_cb), NULL); } static void sakura_init_popup() { GtkWidget *item_new_tab, *item_set_name, *item_close_tab, *item_copy, *item_paste, *item_fullscreen, *item_select_font, *item_select_colors, *item_show_tab_bar, *item_show_tab_bar_always, *item_show_tab_bar_multiple, *item_show_tab_bar_never, *item_toggle_scrollbar, *item_options, *item_urgent_bell, *item_audible_bell, *item_blinking_cursor, *item_cursor, *item_cursor_block, *item_cursor_underline, *item_cursor_ibeam, *item_tabs_on_bottom, *item_less_questions, *item_copy_on_select, *item_disable_numbered_tabswitch, *item_new_tab_after_current; // *item_use_fading; GtkWidget *options_menu, *show_tab_bar_menu, *cursor_menu; sakura.item_open_mail = gtk_menu_item_new_with_label(_("Open mail")); sakura.item_open_link = gtk_menu_item_new_with_label(_("Open link")); sakura.item_copy_link = gtk_menu_item_new_with_label(_("Copy link")); item_new_tab = gtk_menu_item_new_with_label(_("New tab")); item_set_name = gtk_menu_item_new_with_label(_("Set tab name...")); item_close_tab = gtk_menu_item_new_with_label(_("Close tab")); item_fullscreen = gtk_menu_item_new_with_label(_("Full screen")); item_copy = gtk_menu_item_new_with_label(_("Copy")); item_paste = gtk_menu_item_new_with_label(_("Paste")); item_options = gtk_menu_item_new_with_label(_("Options")); item_select_font = gtk_menu_item_new_with_label(_("Select font...")); item_select_colors = gtk_menu_item_new_with_label(_("Select colors...")); item_show_tab_bar = gtk_menu_item_new_with_label(_("Show tab bar")); item_show_tab_bar_always = gtk_radio_menu_item_new_with_label(NULL, _("Always")); item_show_tab_bar_multiple = gtk_radio_menu_item_new_with_label_from_widget( GTK_RADIO_MENU_ITEM(item_show_tab_bar_always), _("When there's more than one tab")); item_show_tab_bar_never = gtk_radio_menu_item_new_with_label_from_widget( GTK_RADIO_MENU_ITEM(item_show_tab_bar_always), _("Never")); item_tabs_on_bottom = gtk_check_menu_item_new_with_label(_("Tabs at bottom")); item_new_tab_after_current = gtk_check_menu_item_new_with_label(_("New tab after current tab")); item_toggle_scrollbar = gtk_check_menu_item_new_with_label(_("Show scrollbar")); item_less_questions = gtk_check_menu_item_new_with_label(_("Fewer questions at exit time")); item_copy_on_select = gtk_check_menu_item_new_with_label(_("Automatically copy selected text")); item_urgent_bell = gtk_check_menu_item_new_with_label(_("Set urgent bell")); item_audible_bell = gtk_check_menu_item_new_with_label(_("Set audible bell")); item_blinking_cursor = gtk_check_menu_item_new_with_label(_("Set blinking cursor")); item_disable_numbered_tabswitch = gtk_check_menu_item_new_with_label(_("Disable numbered tabswitch")); //item_use_fading = gtk_check_menu_item_new_with_label(_("Enable focus fade")); item_cursor = gtk_menu_item_new_with_label(_("Set cursor type")); item_cursor_block = gtk_radio_menu_item_new_with_label(NULL, _("Block")); item_cursor_underline = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(item_cursor_block), _("Underline")); item_cursor_ibeam = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(item_cursor_block), _("IBeam")); /* Show defaults in menu items */ switch (sakura.show_tab_bar) { case SHOW_TAB_BAR_ALWAYS: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_show_tab_bar_always), TRUE); break; case SHOW_TAB_BAR_MULTIPLE: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_show_tab_bar_multiple), TRUE); break; case SHOW_TAB_BAR_NEVER: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_show_tab_bar_never), TRUE); } if (sakura.new_tab_after_current) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_new_tab_after_current), TRUE); } else { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_new_tab_after_current), FALSE); } if (sakura.tabs_on_bottom) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_tabs_on_bottom), TRUE); } else { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_tabs_on_bottom), FALSE); } if (sakura.less_questions) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_less_questions), TRUE); } else { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_less_questions), FALSE); } if (sakura.copy_on_select) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_copy_on_select), TRUE); } if (sakura.show_scrollbar) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_toggle_scrollbar), TRUE); } else { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_toggle_scrollbar), FALSE); } if (sakura.disable_numbered_tabswitch) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_disable_numbered_tabswitch), TRUE); } else { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_disable_numbered_tabswitch), FALSE); } //if (sakura.use_fading) { // gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_use_fading), TRUE); //} else { // gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_use_fading), FALSE); //} if (sakura.urgent_bell) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_urgent_bell), TRUE); } if (sakura.audible_bell) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_audible_bell), TRUE); } if (sakura.blinking_cursor) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_blinking_cursor), TRUE); } switch (sakura.cursor_type) { case VTE_CURSOR_SHAPE_BLOCK: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_cursor_block), TRUE); break; case VTE_CURSOR_SHAPE_UNDERLINE: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_cursor_underline), TRUE); break; case VTE_CURSOR_SHAPE_IBEAM: gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item_cursor_ibeam), TRUE); } sakura.open_link_separator = gtk_separator_menu_item_new(); sakura.menu = gtk_menu_new(); /* Add items to popup menu */ gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), sakura.item_open_mail); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), sakura.item_open_link); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), sakura.item_copy_link); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), sakura.open_link_separator); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), item_new_tab); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), item_set_name); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), item_close_tab); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), gtk_separator_menu_item_new()); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), item_fullscreen); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), gtk_separator_menu_item_new()); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), item_copy); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), item_paste); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), gtk_separator_menu_item_new()); gtk_menu_shell_append(GTK_MENU_SHELL(sakura.menu), item_options); options_menu = gtk_menu_new(); show_tab_bar_menu = gtk_menu_new(); cursor_menu = gtk_menu_new(); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_select_colors); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_select_font); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), gtk_separator_menu_item_new()); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_show_tab_bar); gtk_menu_shell_append(GTK_MENU_SHELL(show_tab_bar_menu), item_show_tab_bar_always); gtk_menu_shell_append(GTK_MENU_SHELL(show_tab_bar_menu), item_show_tab_bar_multiple); gtk_menu_shell_append(GTK_MENU_SHELL(show_tab_bar_menu), item_show_tab_bar_never); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_tabs_on_bottom); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_new_tab_after_current); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), gtk_separator_menu_item_new()); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_toggle_scrollbar); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_less_questions); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_copy_on_select); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_urgent_bell); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_audible_bell); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_disable_numbered_tabswitch); //gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_use_fading); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_blinking_cursor); gtk_menu_shell_append(GTK_MENU_SHELL(options_menu), item_cursor); gtk_menu_shell_append(GTK_MENU_SHELL(cursor_menu), item_cursor_block); gtk_menu_shell_append(GTK_MENU_SHELL(cursor_menu), item_cursor_underline); gtk_menu_shell_append(GTK_MENU_SHELL(cursor_menu), item_cursor_ibeam); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_options), options_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_show_tab_bar), show_tab_bar_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(item_cursor), cursor_menu); /* ... and finally assign callbacks to menuitems */ g_signal_connect(G_OBJECT(item_new_tab), "activate", G_CALLBACK(sakura_new_tab_cb), NULL); g_signal_connect(G_OBJECT(item_set_name), "activate", G_CALLBACK(sakura_set_name_dialog_cb), NULL); g_signal_connect(G_OBJECT(item_close_tab), "activate", G_CALLBACK(sakura_close_tab_cb), NULL); g_signal_connect(G_OBJECT(item_select_font), "activate", G_CALLBACK(sakura_font_dialog_cb), NULL); g_signal_connect(G_OBJECT(item_copy), "activate", G_CALLBACK(sakura_copy_cb), NULL); g_signal_connect(G_OBJECT(item_paste), "activate", G_CALLBACK(sakura_paste_cb), NULL); g_signal_connect(G_OBJECT(item_select_colors), "activate", G_CALLBACK(sakura_color_dialog_cb), NULL); g_signal_connect(G_OBJECT(item_show_tab_bar_always), "activate", G_CALLBACK(sakura_show_tab_bar_cb), "always"); g_signal_connect(G_OBJECT(item_show_tab_bar_multiple), "activate", G_CALLBACK(sakura_show_tab_bar_cb), "multiple"); g_signal_connect(G_OBJECT(item_show_tab_bar_never), "activate", G_CALLBACK(sakura_show_tab_bar_cb), "never"); g_signal_connect(G_OBJECT(item_tabs_on_bottom), "activate", G_CALLBACK(sakura_tabs_on_bottom_cb), NULL); g_signal_connect(G_OBJECT(item_less_questions), "activate", G_CALLBACK(sakura_less_questions_cb), NULL); g_signal_connect(G_OBJECT(item_copy_on_select), "activate", G_CALLBACK(sakura_copy_on_select_cb), NULL); g_signal_connect(G_OBJECT(item_new_tab_after_current), "activate", G_CALLBACK(sakura_new_tab_after_current_cb), NULL); g_signal_connect(G_OBJECT(item_toggle_scrollbar), "activate", G_CALLBACK(sakura_show_scrollbar_cb), NULL); g_signal_connect(G_OBJECT(item_urgent_bell), "activate", G_CALLBACK(sakura_urgent_bell_cb), NULL); g_signal_connect(G_OBJECT(item_audible_bell), "activate", G_CALLBACK(sakura_audible_bell_cb), NULL); g_signal_connect(G_OBJECT(item_blinking_cursor), "activate", G_CALLBACK(sakura_blinking_cursor_cb), NULL); g_signal_connect(G_OBJECT(item_disable_numbered_tabswitch), "activate", G_CALLBACK(sakura_disable_numbered_tabswitch_cb), NULL); //g_signal_connect(G_OBJECT(item_use_fading), "activate", G_CALLBACK(sakura_use_fading_cb), NULL); g_signal_connect(G_OBJECT(item_cursor_block), "activate", G_CALLBACK(sakura_set_cursor_cb), "block"); g_signal_connect(G_OBJECT(item_cursor_underline), "activate", G_CALLBACK(sakura_set_cursor_cb), "underline"); g_signal_connect(G_OBJECT(item_cursor_ibeam), "activate", G_CALLBACK(sakura_set_cursor_cb), "ibeam"); g_signal_connect(G_OBJECT(sakura.item_open_mail), "activate", G_CALLBACK(sakura_open_mail_cb), NULL); g_signal_connect(G_OBJECT(sakura.item_open_link), "activate", G_CALLBACK(sakura_open_url_cb), NULL); g_signal_connect(G_OBJECT(sakura.item_copy_link), "activate", G_CALLBACK(sakura_copy_url_cb), NULL); g_signal_connect(G_OBJECT(item_fullscreen), "activate", G_CALLBACK(sakura_fullscreen_cb), NULL); gtk_widget_show_all(sakura.menu); } static void sakura_destroy() { /* Delete all existing tabs */ while (gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)) >= 1) { sakura_del_tab(-1); } g_key_file_free(sakura.cfg); pango_font_description_free(sakura.font); free(sakura.configfile); gtk_main_quit(); } static void sakura_search_dialog () { GtkWidget *title_dialog, *title_header; GtkWidget *entry, *label; GtkWidget *title_hbox; gint response; title_dialog=gtk_dialog_new_with_buttons(_("Search"), GTK_WINDOW(sakura.main_window), GTK_DIALOG_MODAL|GTK_DIALOG_USE_HEADER_BAR, _("_Cancel"), GTK_RESPONSE_CANCEL, _("_Apply"), GTK_RESPONSE_ACCEPT, NULL); /* Configure the new gtk header bar*/ title_header = gtk_dialog_get_header_bar(GTK_DIALOG(title_dialog)); gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(title_header), FALSE); gtk_dialog_set_default_response(GTK_DIALOG(title_dialog), GTK_RESPONSE_ACCEPT); entry = gtk_entry_new(); label = gtk_label_new(_("Search")); title_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); gtk_box_pack_start(GTK_BOX(title_hbox), label, TRUE, TRUE, 12); gtk_box_pack_start(GTK_BOX(title_hbox), entry, TRUE, TRUE, 12); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(title_dialog))), title_hbox, FALSE, FALSE, 12); /* Disable accept button until some text is entered */ g_signal_connect(G_OBJECT(entry), "changed", G_CALLBACK(sakura_setname_entry_changed_cb), title_dialog); gtk_dialog_set_response_sensitive(GTK_DIALOG(title_dialog), GTK_RESPONSE_ACCEPT, FALSE); gtk_widget_show_all(title_hbox); response = gtk_dialog_run(GTK_DIALOG(title_dialog)); if (response == GTK_RESPONSE_ACCEPT) { sakura_search(gtk_entry_get_text(GTK_ENTRY(entry)), 0); } gtk_widget_destroy(title_dialog); } void sakura_search (const char *pattern, bool reverse) { GError *error=NULL; VteRegex *regex; gint page; struct sakura_tab *sk_tab; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); vte_terminal_search_set_wrap_around(VTE_TERMINAL(sk_tab->vte), TRUE); regex=vte_regex_new_for_search(pattern, (gssize) strlen(pattern), PCRE2_MULTILINE|PCRE2_CASELESS, &error); if (!regex) { /* Ubuntu-fucking-morons (17.10/18.04/18.10) package a broken VTE without PCRE2, and search fails */ /* For more info about their moronity please look at https://github.com/gnunn1/tilix/issues/916 */ sakura_error(error->message); g_error_free(error); } else { vte_terminal_search_set_regex(VTE_TERMINAL(sk_tab->vte), regex, 0); if (!vte_terminal_search_find_next(VTE_TERMINAL(sk_tab->vte))) { vte_terminal_unselect_all(VTE_TERMINAL(sk_tab->vte)); vte_terminal_search_find_next(VTE_TERMINAL(sk_tab->vte)); } if (regex) vte_regex_unref(regex); } } static void sakura_copy () { gint page; struct sakura_tab *sk_tab; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); if (vte_terminal_get_has_selection(VTE_TERMINAL(sk_tab->vte))) { vte_terminal_copy_clipboard_format(VTE_TERMINAL(sk_tab->vte), VTE_FORMAT_TEXT); } } static void sakura_paste () { gint page; struct sakura_tab *sk_tab; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); vte_terminal_paste_clipboard(VTE_TERMINAL(sk_tab->vte)); } static void sakura_paste_primary () { gint page; struct sakura_tab *sk_tab; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); vte_terminal_paste_primary(VTE_TERMINAL(sk_tab->vte)); } static void sakura_show_scrollbar (void) { gint page, n_pages; struct sakura_tab *sk_tab; int i; n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); if (!g_key_file_get_boolean(sakura.cfg, cfg_group, "scrollbar", NULL)) { sakura.show_scrollbar = true; sakura_set_config_boolean("scrollbar", TRUE); } else { sakura.show_scrollbar = false; sakura_set_config_boolean("scrollbar", FALSE); } /* Toggle/Untoggle the scrollbar for all tabs */ for (i = (n_pages - 1); i >= 0; i--) { sk_tab = sakura_get_sktab(sakura, i); if (!sakura.show_scrollbar) gtk_widget_hide(sk_tab->scrollbar); else gtk_widget_show(sk_tab->scrollbar); } sakura_set_size(); } static void sakura_set_size (void) { struct sakura_tab *sk_tab; gint pad_x, pad_y; gint char_width, char_height; guint npages; gint min_width, natural_width; gint page; sk_tab = sakura_get_sktab(sakura, 0); npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); /* Mayhaps an user resize happened. Check if row and columns have changed */ if (sakura.resized) { sakura.columns = vte_terminal_get_column_count(VTE_TERMINAL(sk_tab->vte)); sakura.rows = vte_terminal_get_row_count(VTE_TERMINAL(sk_tab->vte)); SAY("New columns %ld and rows %ld", sakura.columns, sakura.rows); sakura.resized = FALSE; } gtk_style_context_get_padding(gtk_widget_get_style_context(sk_tab->vte), gtk_widget_get_state_flags(sk_tab->vte), &sk_tab->padding); pad_x = sk_tab->padding.left + sk_tab->padding.right; pad_y = sk_tab->padding.top + sk_tab->padding.bottom; //SAY("padding x %d y %d", pad_x, pad_y); char_width = vte_terminal_get_char_width(VTE_TERMINAL(sk_tab->vte)); char_height = vte_terminal_get_char_height(VTE_TERMINAL(sk_tab->vte)); char_height = (int) (sakura.line_height * char_height); sakura.width = pad_x + (char_width * sakura.columns); sakura.height = pad_y + (char_height * sakura.rows); if (sakura.show_tab_bar == SHOW_TAB_BAR_ALWAYS || (sakura.show_tab_bar == SHOW_TAB_BAR_MULTIPLE && npages > 1)) { /* TODO: Yeah i know, this is utter shit. Remove this ugly hack and set geometry hints*/ if (!sakura.show_scrollbar) //sakura.height += min_height - 10; sakura.height += 10; else //sakura.height += min_height - 47; sakura.height += 47; sakura.width += 8; sakura.width += /* (hb*2)+*/ (pad_x*2); } page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); gtk_widget_get_preferred_width(sk_tab->scrollbar, &min_width, &natural_width); //SAY("SCROLLBAR min width %d natural width %d", min_width, natural_width); if (sakura.show_scrollbar) { sakura.width += min_width; } /* Maximize window at init time when command line option is used */ if (option_maximize && sakura.first_run) { gtk_window_maximize(GTK_WINDOW(sakura.main_window)); gtk_widget_show_all(GTK_WIDGET(sakura.main_window)); return; /* No need to resize */ } gtk_window_resize(GTK_WINDOW(sakura.main_window), sakura.width, sakura.height); SAY("Resized to %d %d", sakura.width, sakura.height); } static void sakura_set_font() { gint n_pages; struct sakura_tab *sk_tab; int i; n_pages=gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); /* Set the font for all tabs */ for (i = (n_pages - 1); i >= 0; i--) { sk_tab = sakura_get_sktab(sakura, i); vte_terminal_set_font(VTE_TERMINAL(sk_tab->vte), sakura.font); vte_terminal_set_cell_height_scale(VTE_TERMINAL(sk_tab->vte), sakura.line_height); } } /* Set colorset when colosert keybinding is used */ static void sakura_set_colorset (int cs) { gint page; struct sakura_tab *sk_tab; if (cs < 0 || cs >= NUM_COLORSETS) return; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); sk_tab->colorset = cs; sakura_set_config_integer("last_colorset", sk_tab->colorset+1); sakura_set_colors(); } /* Set the terminal colors for all notebook tabs */ static void sakura_set_colors () { int i; int n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); struct sakura_tab *sk_tab; for (i = (n_pages - 1); i >= 0; i--) { sk_tab = sakura_get_sktab(sakura, i); /* Set fore, back, cursor color and palette for the terminal's colorset */ vte_terminal_set_colors(VTE_TERMINAL(sk_tab->vte), &sakura.forecolors[sk_tab->colorset], &sakura.backcolors[sk_tab->colorset], sakura.palette, PALETTE_SIZE); vte_terminal_set_color_cursor(VTE_TERMINAL(sk_tab->vte), &sakura.curscolors[sk_tab->colorset]); /* Use background color to make text visible when the cursor is over it */ vte_terminal_set_color_cursor_foreground(VTE_TERMINAL(sk_tab->vte), &sakura.backcolors[sk_tab->colorset]); vte_terminal_set_bold_is_bright(VTE_TERMINAL(sk_tab->vte), sakura.bold_is_bright); } /* Main window opacity must be set. Otherwise vte widget will remain opaque */ gtk_widget_set_opacity(sakura.main_window, sakura.backcolors[sk_tab->colorset].alpha); } static void sakura_move_tab(gint direction) { gint page, n_pages; GtkWidget *child; page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); child = gtk_notebook_get_nth_page(GTK_NOTEBOOK(sakura.notebook), page); if (direction == FORWARD) { if (page != n_pages-1) gtk_notebook_reorder_child(GTK_NOTEBOOK(sakura.notebook), child, page+1); } else { if (page != 0) gtk_notebook_reorder_child(GTK_NOTEBOOK(sakura.notebook), child, page-1); } } /* Find the notebook page for the vte terminal passed as a parameter */ static gint sakura_find_tab(VteTerminal *vte_term) { gint matched_page, page, n_pages; struct sakura_tab *sk_tab; n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); matched_page = -1; page = 0; do { sk_tab = sakura_get_sktab(sakura, page); if ((VteTerminal *)sk_tab->vte == vte_term) { matched_page=page; } page++; } while (page < n_pages); return (matched_page); } static void sakura_set_tab_label_text(const gchar *title, gint page) { struct sakura_tab *sk_tab; gchar *chopped_title; gchar *default_label_text; sk_tab = sakura_get_sktab(sakura, page); if ((title != NULL) && (g_strcmp0(title, "") != 0)) { /* Chop to max size */ chopped_title = g_strndup(title, TAB_MAX_SIZE); /* Honor the minimum tab label size */ while (strlen(chopped_title)< TAB_MIN_SIZE) { char *old_ptr = chopped_title; chopped_title = g_strconcat(chopped_title, " ", NULL); free(old_ptr); } gtk_label_set_text(GTK_LABEL(sk_tab->label), chopped_title); free(chopped_title); } else { /* Use the default values */ default_label_text = g_strdup_printf(_("Terminal %d"), page); gtk_label_set_text(GTK_LABEL(sk_tab->label), default_label_text); free(default_label_text); } } /* Callback for vte_terminal_spawn_async */ void sakura_spawn_callback (VteTerminal *vte, GPid pid, GError *error, gpointer user_data) { struct sakura_tab *sk_tab = (struct sakura_tab *) user_data; if (pid == -1) { /* Fork has failed */ SAY("Error: %s", error->message); } else { sk_tab->pid=pid; } } static void sakura_add_tab() { struct sakura_tab *sk_tab; GtkWidget *tab_title_hbox; GtkWidget *close_button; /* We could put them inside struct sakura_tab, but it is not necessary */ GtkWidget *event_box; gint index, page, npages; gchar *cwd = NULL; gchar *default_label_text = NULL; sk_tab = g_new0(struct sakura_tab, 1); /* Create the tab label */ sk_tab->label = gtk_label_new(NULL); gtk_label_set_ellipsize(GTK_LABEL(sk_tab->label), PANGO_ELLIPSIZE_END); /* Create hbox for our label & button */ tab_title_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); gtk_widget_set_hexpand(tab_title_hbox, TRUE); /* Label widgets has no window associated, so we need an event box to catch click events */ event_box = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(event_box), sk_tab->label); gtk_widget_set_events(event_box, GDK_BUTTON_PRESS_MASK); /* Expand&fill the event_box to get click events all along the tab */ gtk_box_pack_start(GTK_BOX(tab_title_hbox), event_box, TRUE, TRUE, 0); /* If the tab close button is enabled, create and add it to the tab */ if (sakura.show_closebutton) { close_button = gtk_button_new(); /* Adding scroll-event to button, to propagate it to notebook (fix for scroll event when pointer is above the button) */ gtk_widget_add_events(close_button, GDK_SCROLL_MASK); gtk_widget_set_name(close_button, "closebutton"); gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE); GtkWidget *image = gtk_image_new_from_icon_name("window-close", GTK_ICON_SIZE_MENU); gtk_container_add (GTK_CONTAINER (close_button), image); gtk_box_pack_start(GTK_BOX(tab_title_hbox), close_button, FALSE, FALSE, 0); } if (sakura.tabs_on_bottom) { gtk_notebook_set_tab_pos(GTK_NOTEBOOK(sakura.notebook), GTK_POS_BOTTOM); } gtk_widget_show_all(tab_title_hbox); /* Create new vte terminal, scrollbar, and pack it */ sk_tab->vte = vte_terminal_new(); sk_tab->scrollbar = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(sk_tab->vte))); sk_tab->hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(sk_tab->hbox), sk_tab->vte, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(sk_tab->hbox), sk_tab->scrollbar, FALSE, FALSE, 0); sk_tab->colorset = sakura.last_colorset-1; /* -1 if there is no pages yet */ page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); /* Use previous terminal (if there is one) cwd and colorset */ if (page >= 0) { struct sakura_tab *prev_term; prev_term = sakura_get_sktab(sakura, page); /* If OSC7 method doesn't work, use the old one as fallback */ if ((cwd = sakura_get_term_cwd_osc7(prev_term)) == NULL) { SAY("osc7 is null"); sakura_get_term_cwd(prev_term); } sk_tab->colorset = prev_term->colorset; } if (!cwd) cwd = g_get_current_dir(); if (!sakura.new_tab_after_current) { if ((index=gtk_notebook_append_page(GTK_NOTEBOOK(sakura.notebook), sk_tab->hbox, tab_title_hbox))==-1) { sakura_error("Cannot create a new tab"); exit(1); } } else { if ((index=gtk_notebook_insert_page(GTK_NOTEBOOK(sakura.notebook), sk_tab->hbox, tab_title_hbox, page+1))==-1) { sakura_error("Cannot create a new tab"); exit(1); } } gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(sakura.notebook), sk_tab->hbox, TRUE); sakura_set_sktab(sakura, index, sk_tab ); /* vte signals */ g_signal_connect(G_OBJECT(sk_tab->vte), "bell", G_CALLBACK(sakura_beep_cb), NULL); g_signal_connect(G_OBJECT(sk_tab->vte), "increase-font-size", G_CALLBACK(sakura_increase_font_cb), NULL); g_signal_connect(G_OBJECT(sk_tab->vte), "decrease-font-size", G_CALLBACK(sakura_decrease_font_cb), NULL); sk_tab->exit_handler_id = g_signal_connect(G_OBJECT(sk_tab->vte), "child-exited", G_CALLBACK(sakura_child_exited_cb), NULL); g_signal_connect(G_OBJECT(sk_tab->vte), "eof", G_CALLBACK(sakura_eof_cb), NULL); g_signal_connect(G_OBJECT(sk_tab->vte), "window-title-changed", G_CALLBACK(sakura_title_changed_cb), NULL); g_signal_connect_after(G_OBJECT(sk_tab->vte), "button-press-event", G_CALLBACK(sakura_term_buttonpressed_cb), sakura.menu); g_signal_connect_swapped(G_OBJECT(sk_tab->vte), "button-release-event", G_CALLBACK(sakura_term_buttonreleased_cb), sakura.menu); /* Label & button signals */ /* We need the hbox to know which label/button was clicked */ g_signal_connect(G_OBJECT(event_box), "button_press_event", G_CALLBACK(sakura_label_clicked_cb), sk_tab->hbox); if (sakura.show_closebutton) { g_signal_connect(G_OBJECT(close_button), "clicked", G_CALLBACK(sakura_closebutton_clicked_cb), sk_tab->hbox); } /* Allow the user to use a different TERM value */ char *command_env[2]; command_env[1]=NULL; if (sakura.term != NULL) { command_env[0] = g_strdup_printf ("TERM=%s", sakura.term); } else { command_env[0] = g_strdup_printf ("TERM=xterm-256color"); } /******* First tab **********/ npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); if (npages == 1) { if (sakura.show_tab_bar == SHOW_TAB_BAR_ALWAYS) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(sakura.notebook), TRUE); } else { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(sakura.notebook), FALSE); } gtk_notebook_set_show_border(GTK_NOTEBOOK(sakura.notebook), FALSE); /* Set geometry hints when the first tab is created */ GdkGeometry sk_hints; sk_hints.base_width = vte_terminal_get_char_width(VTE_TERMINAL(sk_tab->vte)); sk_hints.base_height = vte_terminal_get_char_height(VTE_TERMINAL(sk_tab->vte)); sk_hints.min_width = vte_terminal_get_char_width(VTE_TERMINAL(sk_tab->vte)) * DEFAULT_MIN_WIDTH_CHARS; sk_hints.min_height = vte_terminal_get_char_height(VTE_TERMINAL(sk_tab->vte)) * DEFAULT_MIN_HEIGHT_CHARS; sk_hints.width_inc = vte_terminal_get_char_width(VTE_TERMINAL(sk_tab->vte)); sk_hints.height_inc = vte_terminal_get_char_height(VTE_TERMINAL(sk_tab->vte)); gtk_window_set_geometry_hints(GTK_WINDOW(sakura.main_window), GTK_WIDGET (sk_tab->vte), &sk_hints, GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); sakura_set_font(); sakura_set_colors(); /* Set size before showing the widgets but after setting the font */ sakura_set_size(); /* Notebook signals. Per notebook signals only need to be defined once, so we put them here */ g_signal_connect(sakura.notebook, "scroll-event", G_CALLBACK(sakura_notebook_scroll_cb), NULL); g_signal_connect(G_OBJECT(sakura.notebook), "switch-page", G_CALLBACK(sakura_switch_page_cb), NULL); g_signal_connect(G_OBJECT(sakura.notebook), "page-removed", G_CALLBACK(sakura_page_removed_cb), NULL); g_signal_connect(G_OBJECT(sakura.notebook), "focus-in-event", G_CALLBACK(sakura_notebook_focus_cb), NULL); gtk_widget_show_all(sakura.notebook); if (!sakura.show_scrollbar) { gtk_widget_hide(sk_tab->scrollbar); } gtk_widget_show(sakura.main_window); sakura_set_colors(); #ifdef GDK_WINDOWING_X11 /* Set WINDOWID env variable */ GdkDisplay *display = gdk_display_get_default(); if (GDK_IS_X11_DISPLAY (display)) { GdkWindow *gwin = gtk_widget_get_window (sakura.main_window); if (gwin != NULL) { guint winid = gdk_x11_window_get_xid (gwin); gchar *winidstr = g_strdup_printf ("%d", winid); g_setenv ("WINDOWID", winidstr, FALSE); g_free (winidstr); } } #endif int command_argc = 0; char **command_argv = NULL; /* Execute command for the fist tab if we have one */ if (option_execute||option_xterm_execute) { char *path; sakura_build_command(&command_argc, &command_argv); /* If the command is valid, run it */ if (command_argc > 0) { path = g_find_program_in_path(command_argv[0]); if (!path) { sakura_error("%s command not found", command_argv[0]); command_argc = 0; } vte_terminal_spawn_async(VTE_TERMINAL(sk_tab->vte), VTE_PTY_NO_HELPER, NULL, command_argv, command_env, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, -1, NULL, sakura_spawn_callback, sk_tab); free(path); g_strfreev(command_argv); } } /* Fork shell if there is no execute option or if the command is not valid */ if ( (!option_execute && !option_xterm_execute) || (command_argc==0)) { if (option_hold == TRUE) { sakura_error("Hold option given without any command"); option_hold = FALSE; } vte_terminal_spawn_async(VTE_TERMINAL(sk_tab->vte), VTE_PTY_NO_HELPER, cwd, sakura.argv, command_env, G_SPAWN_SEARCH_PATH|G_SPAWN_FILE_AND_ARGV_ZERO, NULL, NULL, NULL, -1, NULL, sakura_spawn_callback, sk_tab); } /********** Not the first tab ************/ } else { sakura_set_font(); sakura_set_colors(); gtk_widget_show_all(sk_tab->hbox); if (!sakura.show_scrollbar) { gtk_widget_hide(sk_tab->scrollbar); } if (npages == 2 && sakura.show_tab_bar != SHOW_TAB_BAR_NEVER) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(sakura.notebook), TRUE); sakura_set_size(); } /* Call set_current page after showing the widget: gtk ignores this * function in the window is not visible *sigh*. Gtk documentation * says this is for "historical" reasons. Me arse */ gtk_notebook_set_current_page(GTK_NOTEBOOK(sakura.notebook), index); int command_argc = 0; char **command_argv = NULL; /* Execute command (only in the first run) for additional tabs if we have one */ if ((option_execute||option_xterm_execute) && sakura.first_run) { char *path; sakura_build_command(&command_argc, &command_argv); /* If the command is valid, run it */ if (command_argc > 0) { path = g_find_program_in_path(command_argv[0]); if (!path) { sakura_error("%s command not found", command_argv[0]); command_argc = 0; } vte_terminal_spawn_async(VTE_TERMINAL(sk_tab->vte), VTE_PTY_NO_HELPER, NULL, command_argv, command_env, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, -1, NULL, sakura_spawn_callback, sk_tab); free(path); g_strfreev(command_argv); } } /* Fork shell if there is no execute option or if the command is not valid */ if ( (!option_execute && !option_xterm_execute) || (command_argc==0)) { if (option_hold == TRUE) { sakura_error("Hold option given without any command"); option_hold = FALSE; } vte_terminal_spawn_async(VTE_TERMINAL(sk_tab->vte), VTE_PTY_NO_HELPER, cwd, sakura.argv, command_env, G_SPAWN_SEARCH_PATH|G_SPAWN_FILE_AND_ARGV_ZERO, NULL, NULL, NULL, -1, NULL, sakura_spawn_callback, sk_tab); } } free(cwd); /* Applying tab title pattern from config (https://answers.launchpad.net/sakura/+question/267951) */ if (sakura.tab_default_title != NULL) { default_label_text = sakura.tab_default_title; sk_tab->label_set_byuser = true; } else { sk_tab->label_set_byuser=false; } /* Set the default title text (NULL is valid) */ page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sakura_set_tab_label_text(default_label_text, page); /* Init vte terminal */ vte_terminal_set_scrollback_lines(VTE_TERMINAL(sk_tab->vte), sakura.scroll_lines); vte_terminal_match_add_regex(VTE_TERMINAL(sk_tab->vte), sakura.http_vteregexp, PCRE2_CASELESS); vte_terminal_match_add_regex(VTE_TERMINAL(sk_tab->vte), sakura.mail_vteregexp, PCRE2_CASELESS); vte_terminal_set_mouse_autohide(VTE_TERMINAL(sk_tab->vte), TRUE); vte_terminal_set_backspace_binding(VTE_TERMINAL(sk_tab->vte), VTE_ERASE_ASCII_DELETE); vte_terminal_set_word_char_exceptions(VTE_TERMINAL(sk_tab->vte), sakura.word_chars); vte_terminal_set_audible_bell (VTE_TERMINAL(sk_tab->vte), sakura.audible_bell ? TRUE : FALSE); vte_terminal_set_cursor_blink_mode (VTE_TERMINAL(sk_tab->vte), sakura.blinking_cursor ? VTE_CURSOR_BLINK_ON : VTE_CURSOR_BLINK_OFF); vte_terminal_set_cursor_shape (VTE_TERMINAL(sk_tab->vte), sakura.cursor_type); } /* Do all the work necessary before & after deleting the tab passed as a parameter */ static void sakura_close_tab (gint page) { gint npages, response; pid_t pgid; struct sakura_tab *sk_tab; GtkWidget *dialog; npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); /* Only write configuration to disk if it's the last tab */ if (npages == 1) { sakura_config_done(); } /* Check if there are running processes for this tab. Use tcgetpgrp to compare to the shell PGID */ pgid = tcgetpgrp(vte_pty_get_fd(vte_terminal_get_pty(VTE_TERMINAL(sk_tab->vte)))); if ( (pgid != -1) && (pgid != sk_tab->pid) && (!sakura.less_questions) ) { dialog=gtk_message_dialog_new(GTK_WINDOW(sakura.main_window), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("There is a running process in this terminal.\n\nDo you really want to close it?")); response=gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); if (response==GTK_RESPONSE_YES) sakura_del_tab(page); } else /* No processes */ sakura_del_tab(page); /* And destroy sakura if it's the last tab */ if (npages == 1) sakura_destroy(); } /* Delete the notebook tab passed as a parameter */ static void sakura_del_tab(gint page) { struct sakura_tab *sk_tab; gint npages; sk_tab = sakura_get_sktab(sakura, page); npages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)); /* Do the first tab checks BEFORE deleting the tab, to ensure correct * sizes are calculated when the tab is deleted */ if (npages == 2) { if (sakura.show_tab_bar == SHOW_TAB_BAR_ALWAYS) { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(sakura.notebook), TRUE); } else { gtk_notebook_set_show_tabs(GTK_NOTEBOOK(sakura.notebook), FALSE); } } gtk_widget_hide(sk_tab->hbox); g_signal_handler_disconnect (sk_tab->vte, sk_tab->exit_handler_id); gtk_notebook_remove_page(GTK_NOTEBOOK(sakura.notebook), page); /* Find the next page, if it exists, and grab focus */ if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(sakura.notebook)) > 0) { page = gtk_notebook_get_current_page(GTK_NOTEBOOK(sakura.notebook)); sk_tab = sakura_get_sktab(sakura, page); gtk_widget_grab_focus(sk_tab->vte); } } /* New window -- launch a new instance */ static void sakura_new_window() { GPid pid; GError* error = NULL; char** spawn_argv = malloc(sizeof(char*) * ((sakura.orig_argc ? sakura.orig_argc : 1) + 1)); if(!spawn_argv) { fprintf(stderr, "Error allocating memory for starting new instance!\n"); return; } #ifdef __linux__ /* We try to get the full path of the currently running instance of sakura and use * that for spawning a new process. This is to take care of the case when running * an instance of sakura no in PATH. Unfortunately, procfs is not universally * supported, we restrict it to Linux (and we assume that if we build on Linux, * we will run on Linux as well) */ char cmdline[PATH_MAX + 1]; ssize_t tmp = readlink("/proc/self/exe", cmdline, PATH_MAX); cmdline[tmp] = 0; spawn_argv[0] = cmdline; #else /* Otherwise, we rely on sakura being in PATH */ spawn_argv[0] = "sakura"; #endif /* remove command arguments so that the new window will be in interactive mode */ char** dst; char** src; if(sakura.orig_argc) for(dst = spawn_argv + 1, src = sakura.orig_argv + 1; *src; ++dst, ++src) { if(!strcmp(*src, "-e") || !strcmp(*src, "--xterm-execute")) { break; } if(!strcmp(*src, "-x") || !strcmp(*src, "--xterm")) { ++src; if(!(*src)) { break; } } else { *dst = *src; } } *dst = NULL; /* Get a startup notification ID / xdg-activation token and add it to the environment */ char **envp = NULL; /* TODO: keep this instead of recreating every time */ GAppInfo *info = G_APP_INFO(g_desktop_app_info_new("sakura.desktop")); if (!info) info = g_app_info_create_from_commandline("sakura", "sakura", G_APP_INFO_CREATE_SUPPORTS_STARTUP_NOTIFICATION, NULL); if (info) { GdkAppLaunchContext *ctx = gdk_display_get_app_launch_context(gdk_display_get_default()); char *startup_id = g_app_launch_context_get_startup_notify_id(G_APP_LAUNCH_CONTEXT(ctx), info, NULL); if (startup_id) { envp = g_get_environ(); envp = g_environ_setenv(envp, "DESKTOP_STARTUP_ID", startup_id, TRUE); envp = g_environ_setenv(envp, "XDG_ACTIVATION_TOKEN", startup_id, TRUE); } g_object_unref(ctx); } if (!g_spawn_async(NULL, spawn_argv, envp, G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL, NULL, &pid, &error)) { fprintf(stderr, "Error starting new instance:\n%s\n", error->message); g_error_free(error); } g_spawn_close_pid(pid); free(spawn_argv); if (envp) g_strfreev(envp); if (info) g_object_unref(info); } /* Save configuration */ static void sakura_config_done() { GError *gerror = NULL; gsize len = 0; /* Don't save config file. Option only available thru the config file for users who know the risks */ if (sakura.dont_save) return; gchar *cfgdata = g_key_file_to_data(sakura.cfg, &len, &gerror); if (!cfgdata) { fprintf(stderr, "%s\n", gerror->message); g_error_free(gerror); exit(EXIT_FAILURE); } bool overwrite = false; /* If there's been changes by another sakura process, ask whether to overwrite it or not */ /* And if less_questions options is selected don't overwrite */ if (sakura.externally_modified && !sakura.config_modified && !sakura.less_questions) { GtkWidget *dialog; gint response; dialog = gtk_message_dialog_new(GTK_WINDOW(sakura.main_window), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Configuration has been modified by another process. Overwrite?")); response = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); if (response == GTK_RESPONSE_YES) overwrite = true; } /* Write to file IF there's been changes of IF we want to overwrite another process changes */ if (sakura.config_modified || overwrite) { GIOChannel *cfgfile = g_io_channel_new_file(sakura.configfile, "w", &gerror); if (!cfgfile) { fprintf(stderr, "%s\n", gerror->message); g_error_free(gerror); exit(EXIT_FAILURE); } /* FIXME: if the number of chars written is not "len", something happened. * Check for errors appropriately...*/ GIOStatus status = g_io_channel_write_chars(cfgfile, cfgdata, len, NULL, &gerror); if (status != G_IO_STATUS_NORMAL) { // FIXME: we should deal with temporary failures (G_IO_STATUS_AGAIN) fprintf(stderr, "%s\n", gerror->message); g_error_free(gerror); exit(EXIT_FAILURE); } g_io_channel_shutdown(cfgfile, TRUE, &gerror); g_io_channel_unref(cfgfile); } } /*******************/ /* Misc. functions */ /*******************/ static void sakura_error(const char *format, ...) { GtkWidget *dialog; va_list args; char* buff; va_start(args, format); buff = g_malloc(sizeof(char)*ERROR_BUFFER_LENGTH); vsnprintf(buff, sizeof(char)*ERROR_BUFFER_LENGTH, format, args); va_end(args); dialog = gtk_message_dialog_new(GTK_WINDOW(sakura.main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", buff); gtk_window_set_title(GTK_WINDOW(dialog), _("Error message")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_free(buff); } static void sakura_build_command(int *command_argc, char ***command_argv) { GError *gerror = NULL; if (option_execute) { /* -x option: only one argument */ if (!g_shell_parse_argv(option_execute, command_argc, command_argv, &gerror)) { switch (gerror->code) { case G_SHELL_ERROR_EMPTY_STRING: sakura_error("Empty exec string"); exit(1); break; case G_SHELL_ERROR_BAD_QUOTING: sakura_error("Cannot parse command line arguments: mangled quoting"); exit(1); break; case G_SHELL_ERROR_FAILED: sakura_error("Error in exec option command line arguments"); exit(1); } g_error_free(gerror); } } else { /* -e option: last in the command line, takes all extra arguments */ if (option_xterm_args) { guint size=0, i=0; gchar **quoted_args=NULL; do { size++; } while (option_xterm_args[size]); /* Get option_xterm_args size */ /* Quote all arguments to be able to use parameters with spaces like filenames */ quoted_args = g_malloc(sizeof(char *) * (size+1)); while (option_xterm_args[i]) { quoted_args[i] = g_shell_quote(option_xterm_args[i]); i++; } quoted_args[i]=NULL; /* Join all arguments and parse them to create argc&argv */ gchar *command_joined= command_joined = g_strjoinv(" ", quoted_args); if (!g_shell_parse_argv(command_joined, command_argc, command_argv, &gerror)) { switch (gerror->code) { case G_SHELL_ERROR_EMPTY_STRING: sakura_error("Empty exec string"); exit(1); break; case G_SHELL_ERROR_BAD_QUOTING: sakura_error("Cannot parse command line arguments: mangled quoting"); exit(1); case G_SHELL_ERROR_FAILED: sakura_error("Error in exec option command line arguments"); exit(1); } } if (gerror != NULL) g_error_free(gerror); g_free(command_joined); g_strfreev(quoted_args); } } } static void sakura_set_keybind(const gchar *key, guint value) { char *valname; valname = gdk_keyval_name(value); g_key_file_set_string(sakura.cfg, cfg_group, key, valname); sakura.config_modified = TRUE; } static guint sakura_get_keybind(const gchar *key) { gchar *value; guint retval = GDK_KEY_VoidSymbol; value = g_key_file_get_string(sakura.cfg, cfg_group, key, NULL); if (value != NULL) { retval = gdk_keyval_from_name(value); g_free(value); } /* For backwards compatibility with integer values */ /* If gdk_keyval_from_name fail, it seems to be integer value*/ if ((retval == GDK_KEY_VoidSymbol) || (retval == 0)) { retval = g_key_file_get_integer(sakura.cfg, cfg_group, key, NULL); } /* Always use uppercase value as keyval */ return gdk_keyval_to_upper(retval); } /* Legacy function to use as fallback if our shell doesn't emit OSC7. * Retrieves the CWD of the specified sk_tab page.Original borrowed * from gnome-terminal. Adapted by Hong Jen Yee and David Gómez */ static char * sakura_get_term_cwd(struct sakura_tab* sk_tab) { char *cwd = NULL; if (sk_tab->pid >= 0) { char *file, *buf; struct stat sb; int len; file = g_strdup_printf ("/proc/%d/cwd", sk_tab->pid); if (g_stat(file, &sb) == -1) { g_free(file); return cwd; } buf = g_malloc(sb.st_size + 1); if (buf == NULL) { g_free(file); return cwd; } len = readlink(file, buf, sb.st_size + 1); if (len > 0 && buf[0] == '/') { buf[len] = '\0'; cwd = g_strdup(buf); } g_free(buf); g_free(file); } return cwd; } static char * sakura_get_term_cwd_osc7(struct sakura_tab* sk_tab) { gchar *cwd = NULL; gchar *osc7_hostname = NULL; const char *osc7_uri = NULL; const char *hostname = NULL; osc7_uri = vte_terminal_get_current_directory_uri(VTE_TERMINAL(sk_tab->vte)); if (osc7_uri) { cwd = g_filename_from_uri(osc7_uri, &osc7_hostname, NULL); /* Check if the hostname matchs. If not, return NULL */ hostname = g_get_host_name(); if ((strcmp(osc7_hostname, hostname) != 0) || (strcmp(osc7_hostname, "localhost") == 0)) cwd = NULL; } return cwd; } static guint sakura_tokeycode (guint key) { GdkKeymap *keymap; GdkKeymapKey *keys; gint n_keys; guint res = 0; keymap = gdk_keymap_get_for_display(gdk_display_get_default()); /* Empty shortcut */ if (key == 0) return 0; if (gdk_keymap_get_entries_for_keyval(keymap, key, &keys, &n_keys)) { if (n_keys > 0) { res = keys[0].keycode; } g_free(keys); } return res; } /* This function is used to fix bug #1393939 */ static void sakura_sanitize_working_directory() { const gchar *home_directory = g_getenv("HOME"); if (home_directory == NULL) { home_directory = g_get_home_dir(); } if (home_directory != NULL) { if (chdir(home_directory)) { fprintf(stderr, _("Cannot change working directory\n")); exit(1); } } } /********/ /* main */ /********/ int main(int argc, char **argv) { gchar *localedir; int i; int n; char **nargv; int nargc; gboolean have_e; /* Localization */ setlocale(LC_ALL, ""); localedir = g_strdup_printf("%s/locale", DATADIR); textdomain(GETTEXT_PACKAGE); bindtextdomain(GETTEXT_PACKAGE, localedir); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); g_free(localedir); /* Rewrites argv to include a -- after the -e argument this is required to make * sure GOption doesn't grab any arguments meant for the command being called */ /* Initialize nargv */ nargv = (char**)calloc((argc+1), sizeof(char*)); n = 0; nargc = argc; have_e = FALSE; /* Save original arguments to start a new instance if needed */ sakura.orig_argc = argc; sakura.orig_argv = argv; for (i=0; imessage); g_error_free(error); exit(1); } g_option_context_free(context); if (option_workdir && chdir(option_workdir)) { fprintf(stderr, _("Cannot change working directory\n")); exit(1); } if (option_version) { fprintf(stderr, _("sakura version is %s\n"), VERSION); exit(1); } if (option_ntabs <= 0) { option_ntabs = 1; } /* Init stuff */ gtk_init(&nargc, &nargv); g_strfreev(nargv); sakura_init(); /* Add initial tabs (1 by default) */ for (i=0; i