Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:iDesmI:kf6
applet-window-buttons6
_service:obs_scm:applet-window-buttons6-1710115...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:applet-window-buttons6-1710115487.a7b95da.obscpio of Package applet-window-buttons6
07070100000000000081A400000000000000000000000165EE4A9F000005BC000000000000000000000000000000000000003800000000applet-window-buttons6-1710115487.a7b95da/.clang-format--- BasedOnStyle: Microsoft AccessModifierOffset: -2 AlignAfterOpenBracket: Align AllowAllArgumentsOnNextLine: false AllowAllConstructorInitializersOnNextLine: false AllowAllParametersOfDeclarationOnNextLine: false AlignConsecutiveMacros: true AllowShortBlocksOnASingleLine: Never AllowShortCaseLabelsOnASingleLine: true AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: Never AllowShortLambdasOnASingleLine: All AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false AlwaysBreakTemplateDeclarations: Yes BinPackArguments: true BinPackParameters: true BreakBeforeBraces: Allman BreakBeforeTernaryOperators: false BreakInheritanceList: BeforeComma BreakStringLiterals: false ColumnLimit: 170 CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false Cpp11BracedListStyle: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true IncludeBlocks: Regroup IndentCaseLabels: true IndentPPDirectives: None IndentWidth: 4 MaxEmptyLinesToKeep: 1 NamespaceIndentation: All ReflowComments: true SortIncludes: true SortUsingDeclarations: true SpaceAfterCStyleCast: true SpaceAfterTemplateKeyword: false SpaceBeforeParens: ControlStatements SpaceBeforeRangeBasedForLoopColon: true SpacesInParentheses: false Standard: c++17 StatementMacros: [Q_UNUSED LOG DEBUG] # ForEachMacros: [list_foreach] TabWidth: 4 UseTab: Never 07070100000001000081A400000000000000000000000165EE4A9F0000016A000000000000000000000000000000000000003500000000applet-window-buttons6-1710115487.a7b95da/.gitignore*~ .* !.arcconfig !.gitignore # Ignore hidden files .directory # Ignore patches *.patch~ # build directory build/ # backup files *.autosave *.desktop~ *.gitignore~ *.js~ *.kate-swp *.qml~ *.sh~ *.xml~ .*.cpp~ .*.h~ .*.js~ .*.pot~ .*.po~ .*.qml~ .*.txt~ .*.xml~ .*~ *.*.user *.*.orig # locale files *.mo # KDevelop Project files *.kdev4 .kdev4/ build-kdev/ 07070100000002000081A400000000000000000000000165EE4A9F000012CB000000000000000000000000000000000000003700000000applet-window-buttons6-1710115487.a7b95da/CHANGELOG.md### CHANGELOG #### Version 0.11.0 * support Plasma 5.24 way of discovering themes from theme engines * hide when preserveemptyspace is selected #### Version 0.10.1 * fix glitches with slide-in/out animations * improve cpu and hard disk usage * remove all workarounds related to faulty buttons painting * respect and trust bug fixes in decorations provided with Plasma 5.23.2 #### Version 0.10.0 * support Plasma 5.23 * depend only on Plasma and KDecorations2 >= 5.23 * drop option for plasma panels to disable decoration on maximized windows #### Version 0.9.0 * support Plasma 5.18 and 5.21 * support aurorae monochrome icons with Latte auto-color functionality * support aurorae restore button * fix, do not hide buttons for AlwaysVisible * fix, do not hide button in Latte edit mode * fix, improve default based on Plasma values * fix, preserve empty space for hidden states when needed * remove no needed workarounds #### Version 0.8.1 * fix compatibility with Plasma 5.18 (Rodrigo Pedra Brum) * never hide buttons for AlwaysVisible visibility state #### Version 0.8.0 * fix which plasma theme colors are used for buttons when Colors:Plasma Theme is chosen * do not show buttons that the current window has disabled them, for example a window is NOT Closable; Close button becomes hidden in such case * hide buttons when the last active maximized window is minimized and there are no other shown windows * improve configuration window texts * create a new decoration only when it is really needed * reduce filesystem trackers for scheme colors files * use shared decoration between all buttons * set an object name for the shared decoration in order to be easily identified by KDecoration2 decorations #### Version 0.7.0 * introduce a new Button Size percentage option and drop thickness margin in order to set the buttons size * introduce Hidden State in order for the user to choose how buttons should behave when they should not be shown. Currently two states are supported: Slide out and Preserve Empty Space * introduce a new Color Scheme based on current Plasma Theme used and make it also default * live preview for changes in the settings window * do not crash when the selected decoration does not exist in the systemm, for example it was uninstalled * update buttons for scheme changes #### Version 0.6.0 * new visibility mode: At least one window is shown * option to draw buttons in inactive state (for both c++ and aurorae decorations) * fix the current buttons decoration discovery, the user can now change between different decorations and the buttons style is updated runtime * hide when the last maximized window is closed and the visibility mode is ActiveMaximized * fix multi-screens behavior for Latte panels * fix typo that broke builds at some systems #### Version 0.5.0 * provide a relevant background for window buttons in configuration window to fix contrast issues * support new Latte v0.9 Communicator API * support new Latte v0.9 Windows Tracking interface when in Latte dock/panel #### Version 0.4 * add new KeepAbove button support (community contribution) * merge different versions into a single one. One version for all Plasma versions >= 5.12 * close ComboBoxes after clicking #### Version 0.3 * support new Latte coloring and Communicator mechanism * fix spacing issues with Aurorae themes #### Version 0.2 * Choose Colors to apply a color palette to your window buttons * Three different Visibility modes, Always Visible/Active Window/Active and Maximized * Multi-Screen aware, handle active windows only from current screen or from any screen * Option to activate/deactivate borderless maximized windows and a third System Decide when the checkbox is partially checked in order to play nice with Latte v0.8 * respect Fitt's Law and include padding and margins when hovering buttons * fix, update buttons visual settings when the user changes the current decoration settings * fix, respect all focus out/hover out events * provide a Plasma 5.12 compatible version #### Version 0.1 * Current mode, in order to automatically update button appearance according to plasma current window decoration * Choose the decoration theme you would like to use for the buttons * Support Minimize/Maximize/Close/OnAllDesktops buttons * Support icon-based Aurorae themes such as **.svg** and **.svgz** * Identify system's available decorations automatically * Option to show buttons only when there is an active-maximized window in the current screen * Slide out/in animation for showing/hiding buttons * Reorder buttons according to user preference * Various appearance settings in order to adjust margins. This way you can also change the button size * Automatically discover Aurorae theme settings in order to make buttons look identical to window buttons 07070100000003000081A400000000000000000000000165EE4A9F00000534000000000000000000000000000000000000003900000000applet-window-buttons6-1710115487.a7b95da/CMakeLists.txtcmake_minimum_required(VERSION 3.20 FATAL_ERROR) project(applet_windowbuttons) set(CMAKE_CXX_STANDARD 14) set(VERSION 0.12.0) set(AUTHOR "Michail Vourlakos") set(EMAIL "mvourlakos@gmail.com") set(QT_MIN_VERSION "6.6.0") set(KF6_MIN_VERSION "5.246.0") set(KDECORATION2_MIN_VERSION "5.90") find_package(ECM ${KF6_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED NO_MODULE COMPONENTS Gui Qml Quick) find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS CoreAddons Declarative Package Svg) find_package(Plasma "5.90" REQUIRED) find_package(KDecoration2 ${KDECORATION2_MIN_VERSION} REQUIRED) include(ECMFindQmlModule) include(CheckIncludeFiles) include(KDECMakeSettings) include(KDEInstallDirs) set(KDECORATION2_VERSION_MAJOR ${KDecoration2_VERSION_MAJOR}) set(KDECORATION2_VERSION_MINOR ${KDecoration2_VERSION_MINOR}) message(STATUS "KDECORATION2 VERSION MAJOR : ${KDECORATION2_VERSION_MAJOR}") message(STATUS "KDECORATION2 VERSION MINOR : ${KDECORATION2_VERSION_MINOR}") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libappletdecoration/config-decoration.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/libappletdecoration/config-decoration.h) add_subdirectory(libappletdecoration) plasma_install_package(package org.kde.windowbuttons) 07070100000004000081A400000000000000000000000165EE4A9F000046AC000000000000000000000000000000000000003200000000applet-window-buttons6-1710115487.a7b95da/COPYING 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. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> 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. <signature of Ty Coon>, 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. 07070100000005000081A400000000000000000000000165EE4A9F000067A2000000000000000000000000000000000000003600000000applet-window-buttons6-1710115487.a7b95da/COPYING.LIB GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 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. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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 with this License. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. 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. <one line to give the library's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; 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. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. <signature of Ty Coon>, 1 April 1990 Ty Coon, President of Vice That's all there is to it! 07070100000006000081A400000000000000000000000165EE4A9F00000492000000000000000000000000000000000000003A00000000applet-window-buttons6-1710115487.a7b95da/INSTALLATION.mdInstallation ============ ## Building from Source The provided `install.sh` script will build everything and install it for you. Before running the installation script you have to install the dependencies needed for compiling. ### Build Dependencies - Ubuntu: ``` sudo apt install g++ extra-cmake-modules qtbase5-dev qtdeclarative5-dev libkf5declarative-dev libkf5plasma-dev libkdecorations2-dev gettext ``` - Fedora: ``` sudo dnf install extra-cmake-modules qt5-qtdeclarative-devel kf5-plasma-devel kf5-kdeclarative-devel kf5-kconfigwidgets-devel kf5-ki18n-devel kdecoration-devel ``` - Arch: ``` sudo pacman -Syu sudo pacman -S gcc extra-cmake-modules plasma-framework gettext kdecoration ``` ### Building and Installing Once you have installed the dependencies listed above you can execute the build and install script: ``` sh install.sh ``` ## Prebuilt Binaries - Ubuntu: You can install via a PPA on Ubuntu 18.04 (Bionic) or later including KDE Neon. ``` sudo add-apt-repository ppa:krisives/applet-window-buttons sudo apt install applet-window-buttons ``` - openSUSE: install the package from the official repo ``` sudo zypper in applet-window-buttons ``` 07070100000007000081A400000000000000000000000165EE4A9F000046AC000000000000000000000000000000000000003200000000applet-window-buttons6-1710115487.a7b95da/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. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> 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. <signature of Ty Coon>, 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. 07070100000008000081A400000000000000000000000165EE4A9F00000448000000000000000000000000000000000000003400000000applet-window-buttons6-1710115487.a7b95da/README.md# Window Buttons Applet This is a Plasma 5 applet that shows window buttons in your panels. This plasmoid is coming from [Latte land](https://phabricator.kde.org/source/latte-dock/repository/master/) but it can also support Plasma panels. <p align="center"> <img src="https://i.imgur.com/4FItfte.gif" width="580"><br/> <i>slide in/out animation</i> </p> <p align="center"> <img src="https://i.imgur.com/70qeMME.png" width="580"><br/> <i>Breeze decoration</i> </p> <p align="center"> <img src="https://i.imgur.com/uEen6P0.png" width="580"><br/> <i>BreezeEnhanced decoration</i> </p> <p align="center"> <img src="https://i.imgur.com/Zz20RXC.png" width="580"><br/> <i>Settings window</i> </p> # Requires - Qt >= 5.9 - KF5 >= 5.38 - Plasma >= 5.23.2 - KDecoration2 >= 5.23 **Qt elements**: Gui Qml Quick **KF5 elements**: CoreAddons Declarative Plasma PlasmaQuick extra-cmake-modules # Install You can execute `sh install.sh` in the root directory as long as you have installed the previous mentioned development packages. For more details please read [INSTALLATION.md](/INSTALLATION.md) 07070100000009000081ED00000000000000000000000165EE4A9F0000009F000000000000000000000000000000000000003500000000applet-window-buttons6-1710115487.a7b95da/install.shif ! [ -a build ] ; then mkdir build fi cd build cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -Wnodev .. make -j$(nproc) sudo make install 0707010000000A000041ED00000000000000000000000365EE4A9F00000000000000000000000000000000000000000000003E00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration0707010000000B000081A400000000000000000000000165EE4A9F00000621000000000000000000000000000000000000004D00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/CMakeLists.txtcmake_minimum_required(VERSION 3.10 FATAL_ERROR) set(QT_MIN_VERSION "6.6.0") set(KF6_MIN_VERSION "6.0.0") find_package(ECM 0.0.11 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings) set(appletdecoration_SRCS appletdecorationplugin.cpp auroraetheme.cpp buttonsmodel.cpp commontools.cpp decorationsmodel.cpp decorationpalette.cpp environment.cpp padding.cpp previewbutton.cpp previewbridge.cpp previewclient.cpp previewsettings.cpp previewshareddecoration.cpp schemecolors.cpp schemesmodel.cpp themeextended.cpp types.cpp ) add_library(appletdecorationplugin SHARED ${appletdecoration_SRCS}) find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED Quick DBus Widgets) find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS CoreAddons I18n Service ConfigWidgets KCMUtils) find_package(KDecoration2 REQUIRED) target_link_libraries(appletdecorationplugin Qt6::Core Qt6::DBus Qt6::Widgets Qt6::Quick KF6::CoreAddons KF6::ConfigWidgets KF6::I18n Plasma::Plasma KF6::Service KF6::Svg KF6::KCMUtils KDecoration2::KDecoration KDecoration2::KDecoration2Private ) # install plugin install(TARGETS appletdecorationplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/appletdecoration) install(DIRECTORY qml/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/appletdecoration) install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/appletdecoration) 0707010000000C000081A400000000000000000000000165EE4A9F000008C3000000000000000000000000000000000000005900000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/appletdecorationplugin.cpp/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ #include "appletdecorationplugin.h" #include "auroraetheme.h" #include "decorationsmodel.h" #include "environment.h" #include "padding.h" #include "previewbridge.h" #include "previewbutton.h" #include "previewclient.h" #include "previewsettings.h" #include "previewshareddecoration.h" #include "schemesmodel.h" #include "themeextended.h" #include "types.h" #include <KDecoration2/Decoration> #include <QQmlEngine> #include <QtQml> void AppletDecorationPlugin::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("org.kde.appletdecoration")); qmlRegisterUncreatableType<Types>(uri, 0, 1, "Types", "Applet decoration types"); qmlRegisterType<AuroraeTheme>(uri, 0, 1, "AuroraeTheme"); qmlRegisterType<BridgeItem>(uri, 0, 1, "Bridge"); qmlRegisterType<Settings>(uri, 0, 1, "Settings"); qmlRegisterType<PreviewButtonItem>(uri, 0, 1, "Button"); qmlRegisterType<DecorationsModel>(uri, 0, 1, "DecorationsModel"); qmlRegisterType<SchemesModel>(uri, 0, 1, "ColorsModel"); qmlRegisterType<SharedDecoration>(uri, 0, 1, "SharedDecoration"); qmlRegisterType<ExtendedTheme>(uri, 0, 1, "PlasmaThemeExtended"); qmlRegisterAnonymousType<Padding>("", 1); qmlRegisterAnonymousType<PreviewClient>("", 1); qmlRegisterAnonymousType<PreviewBridge>("", 1); qmlRegisterAnonymousType<KDecoration2::Decoration>("", 1); qmlRegisterSingletonType<Environment>(uri, 0, 1, "Environment", &Environment::instance); } 0707010000000D000081A400000000000000000000000165EE4A9F0000044A000000000000000000000000000000000000005700000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/appletdecorationplugin.h/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ #ifndef APPLETDECORATIONPLUGIN_H #define APPLETDECORATIONPLUGIN_H #include <QQmlExtensionPlugin> class AppletDecorationPlugin : public QQmlExtensionPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") public: void registerTypes(const char *uri) override; }; #endif 0707010000000E000081A400000000000000000000000165EE4A9F0000189B000000000000000000000000000000000000004F00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/auroraetheme.cpp/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ #include "auroraetheme.h" #include "commontools.h" #include <KConfigGroup> #include <KDirWatch> #include <KSharedConfig> #include <KSvg/Svg> #include <QDebug> #include <QDir> #include <QFileInfo> #include <QRgb> static const QString s_auroraeSvgTheme = QStringLiteral("__aurorae__svg__"); static const QString s_auroraerc = QStringLiteral("auroraerc"); static int i_buttonSizeStep = 4; AuroraeTheme::AuroraeTheme(QObject *parent) : QObject(parent) { const auto auroraerc = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + s_auroraerc; KDirWatch::self()->addFile(auroraerc); connect(KDirWatch::self(), &KDirWatch::dirty, this, &AuroraeTheme::auroraeRCChanged); connect(KDirWatch::self(), &KDirWatch::created, this, &AuroraeTheme::auroraeRCChanged); connect(this, &AuroraeTheme::themeChanged, this, &AuroraeTheme::loadSettings); } AuroraeTheme::~AuroraeTheme() { } int AuroraeTheme::buttonWidth() const { int f = (int) m_buttonSize; return m_buttonWidth + ((f - 1) * i_buttonSizeStep); } int AuroraeTheme::buttonHeight() const { int f = (int) m_buttonSize; return m_buttonHeight + ((f - 1) * i_buttonSizeStep); } int AuroraeTheme::buttonSpacing() const { return m_buttonSpacing; } int AuroraeTheme::duration() const { return m_duration; } float AuroraeTheme::buttonRatio() const { return ((float) m_buttonWidth / (float) m_buttonHeight); } QString AuroraeTheme::theme() const { return m_theme; } void AuroraeTheme::setTheme(QString theme) { if (m_theme == theme || theme.isEmpty()) { return; } m_theme = theme; updateAurorae(theme); emit themeChanged(); } QString AuroraeTheme::themeName() const { return m_themeName; } QString AuroraeTheme::themePath() const { return m_themePath; } QString AuroraeTheme::themeType() const { return m_themeType; } QColor AuroraeTheme::titleBackgroundColor() const { return m_titleBackgroundColor; } bool AuroraeTheme::hasMonochromeIcons() const { return m_hasMonochromeIcons; } bool AuroraeTheme::hasRestoreButton() const { return m_hasRestoreButton; } QString AuroraeTheme::monochromePrefix() const { return m_monochromePrefix; } void AuroraeTheme::auroraeRCChanged(const QString &filename) { if (!filename.endsWith(s_auroraerc)) return; loadSettings(); } void AuroraeTheme::updateAurorae(const QString &themeName) { const QString separator("__"); const QString name = themeName.section(separator, -1, -1); QString path = standardPath("aurorae/themes/" + name); if (QFileInfo(path + "/close.svg").exists()) m_themeType = "svg"; else if (QFileInfo(path + "/close.svgz").exists()) m_themeType = "svgz"; else if (QFileInfo(path + "/close.png").exists()) m_themeType = "png"; else m_themeType = "svg"; m_hasRestoreButton = QFileInfo(path + "/restore." + m_themeType).exists(); m_themeName = name; m_themePath = path; } void AuroraeTheme::loadSettings() { const QString rc(m_themePath + "/" + m_themeName + "rc"); if (!QFileInfo(rc).exists()) { return; } const auto auroraerc = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + s_auroraerc; if (QFileInfo(auroraerc).exists()) { KSharedConfigPtr auroraePtr = KSharedConfig::openConfig(auroraerc); const KConfigGroup themeGroup = KConfigGroup(auroraePtr, m_themeName); m_buttonSize = static_cast<Types::ButtonSize>(themeGroup.readEntry("ButtonSize", (int) Types::NormalButton)); } else { m_buttonSize = Types::NormalButton; } KSharedConfigPtr rcPtr = KSharedConfig::openConfig(rc); const KConfigGroup generalGroup = KConfigGroup(rcPtr, u"General"_qs); const KConfigGroup layoutGroup = KConfigGroup(rcPtr, u"Layout"_qs); m_duration = generalGroup.readEntry("Animation", 0); m_buttonWidth = layoutGroup.readEntry("ButtonWidth", 24); m_buttonHeight = layoutGroup.readEntry("ButtonHeight", 24); m_buttonSpacing = layoutGroup.readEntry("ButtonSpacing", 2); QString monoprefix = generalGroup.readEntry("MonochromeIconsPrefix", ""); if (!monoprefix.isEmpty()) { m_hasMonochromeIcons = true; m_monochromePrefix = (monoprefix == "*" ? "" : monoprefix); } else { m_hasMonochromeIcons = false; m_monochromePrefix = ""; } parseThemeImages(); emit settingsChanged(); } void AuroraeTheme::parseThemeImages() { QString origBackgroundFilePath = m_themePath + "/decoration." + m_themeType; if (!QFileInfo(origBackgroundFilePath).exists()) { qDebug() << "Aurorare decoration file was not found for theme: " << m_themeName; return; } KSvg::Svg *svg = new KSvg::Svg(this); svg->setImagePath(origBackgroundFilePath); svg->resize(50, 50); QImage img = svg->image(QSize(50, 50), "decoration-top"); int maxOpacity = -1; for (int y = 49; y >= 0; --y) { for (int x = 0; x < 50; ++x) { QRgb pix = img.pixel(x, y); int opacity = qAlpha(pix); //! the equality returns better results for more aurorae themes if (maxOpacity <= opacity) { maxOpacity = opacity; m_titleBackgroundColor = QColor(qRed(pix), qGreen(pix), qBlue(pix)); } } } svg->deleteLater(); } 0707010000000F000081A400000000000000000000000165EE4A9F00000C87000000000000000000000000000000000000004D00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/auroraetheme.h/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ #ifndef AURORAETHEME_H #define AURORAETHEME_H #include "types.h" #include <QColor> #include <QObject> class AuroraeTheme : public QObject { Q_OBJECT Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(QString themeName READ themeName NOTIFY themeChanged) Q_PROPERTY(QString themePath READ themePath NOTIFY themeChanged) Q_PROPERTY(QString themeType READ themeType NOTIFY themeChanged) Q_PROPERTY(int buttonHeight READ buttonHeight NOTIFY settingsChanged) Q_PROPERTY(int buttonWidth READ buttonWidth NOTIFY settingsChanged) Q_PROPERTY(int buttonSpacing READ buttonSpacing NOTIFY settingsChanged) Q_PROPERTY(int duration READ duration NOTIFY settingsChanged) Q_PROPERTY(float buttonRatio READ buttonRatio NOTIFY settingsChanged) Q_PROPERTY(QColor titleBackgroundColor READ titleBackgroundColor NOTIFY settingsChanged) Q_PROPERTY(bool hasRestoreButton READ hasRestoreButton NOTIFY settingsChanged) Q_PROPERTY(bool hasMonochromeIcons READ hasMonochromeIcons NOTIFY settingsChanged) Q_PROPERTY(QString monochromePrefix READ monochromePrefix NOTIFY settingsChanged) public: explicit AuroraeTheme(QObject *parent = nullptr); ~AuroraeTheme() override; ; QString theme() const; void setTheme(QString theme); QString themeName() const; QString themePath() const; QString themeType() const; int buttonHeight() const; int buttonWidth() const; int buttonSpacing() const; int duration() const; float buttonRatio() const; QColor titleBackgroundColor() const; bool hasRestoreButton() const; bool hasMonochromeIcons() const; QString monochromePrefix() const; signals: void settingsChanged(); void themeChanged(); private slots: void parseThemeImages(); void auroraeRCChanged(const QString &filename); private: void loadSettings(); void updateAurorae(const QString &themeName); private: bool m_hasMonochromeIcons{ false }; bool m_hasRestoreButton{ false }; int m_buttonHeight{ 24 }; int m_buttonWidth{ 24 }; int m_buttonSpacing{ 2 }; int m_duration{ 0 }; Types::ButtonSize m_buttonSize{ Types::NormalButton }; // Normal size QString m_theme; QString m_themeName; QString m_themePath; QString m_themeType; QString m_monochromePrefix; QColor m_titleBackgroundColor; }; #endif 07070100000010000081A400000000000000000000000165EE4A9F000016C5000000000000000000000000000000000000004F00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/buttonsmodel.cpp/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #include "buttonsmodel.h" #include <KLocalizedString> #include <QFontDatabase> ButtonsModel::ButtonsModel(const QVector<KDecoration2::DecorationButtonType> &buttons, QObject *parent) : QAbstractListModel(parent), m_buttons(buttons) { } ButtonsModel::ButtonsModel(QObject *parent) : ButtonsModel(QVector<KDecoration2::DecorationButtonType>({ KDecoration2::DecorationButtonType::Menu, KDecoration2::DecorationButtonType::ApplicationMenu, KDecoration2::DecorationButtonType::OnAllDesktops, KDecoration2::DecorationButtonType::Minimize, KDecoration2::DecorationButtonType::Maximize, KDecoration2::DecorationButtonType::Close, KDecoration2::DecorationButtonType::ContextHelp, KDecoration2::DecorationButtonType::Shade, KDecoration2::DecorationButtonType::KeepBelow, KDecoration2::DecorationButtonType::KeepAbove, }), parent) { } ButtonsModel::~ButtonsModel() = default; int ButtonsModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { return 0; } return m_buttons.count(); } static QString buttonToName(KDecoration2::DecorationButtonType type) { switch (type) { case KDecoration2::DecorationButtonType::Menu: return i18n("Menu"); case KDecoration2::DecorationButtonType::ApplicationMenu: return i18n("Application menu"); case KDecoration2::DecorationButtonType::OnAllDesktops: return i18n("On all desktops"); case KDecoration2::DecorationButtonType::Minimize: return i18n("Minimize"); case KDecoration2::DecorationButtonType::Maximize: return i18n("Maximize"); case KDecoration2::DecorationButtonType::Close: return i18n("Close"); case KDecoration2::DecorationButtonType::ContextHelp: return i18n("Context help"); case KDecoration2::DecorationButtonType::Shade: return i18n("Shade"); case KDecoration2::DecorationButtonType::KeepBelow: return i18n("Keep below"); case KDecoration2::DecorationButtonType::KeepAbove: return i18n("Keep above"); default: return QString(); } } QVariant ButtonsModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() < 0 || index.row() >= m_buttons.count() || index.column() != 0) return QVariant(); const auto &button = m_buttons.at(index.row()); switch (role) { case Qt::DisplayRole: return buttonToName(button); case Qt::UserRole: return QVariant::fromValue(int(button)); } return QVariant(); } QHash<int, QByteArray> ButtonsModel::roleNames() const { QHash<int, QByteArray> roles; roles.insert(Qt::DisplayRole, QByteArrayLiteral("display")); roles.insert(Qt::UserRole, QByteArrayLiteral("button")); return roles; } void ButtonsModel::remove(int row) { if (row < 0 || row >= m_buttons.count()) return; beginRemoveRows(QModelIndex(), row, row); m_buttons.removeAt(row); endRemoveRows(); } void ButtonsModel::down(int index) { if (m_buttons.count() < 2 || index == m_buttons.count() - 1) return; beginMoveRows(QModelIndex(), index, index, QModelIndex(), index + 2); m_buttons.insert(index + 1, m_buttons.takeAt(index)); endMoveRows(); } void ButtonsModel::up(int index) { if (m_buttons.count() < 2 || index == 0) return; beginMoveRows(QModelIndex(), index, index, QModelIndex(), index - 1); m_buttons.insert(index - 1, m_buttons.takeAt(index)); endMoveRows(); } void ButtonsModel::add(KDecoration2::DecorationButtonType type) { beginInsertRows(QModelIndex(), m_buttons.count(), m_buttons.count()); m_buttons.append(type); endInsertRows(); } void ButtonsModel::add(int index, int type) { beginInsertRows(QModelIndex(), index + 1, index + 1); m_buttons.insert(index + 1, KDecoration2::DecorationButtonType(type)); endInsertRows(); } void ButtonsModel::move(int sourceIndex, int targetIndex) { if (sourceIndex == qMax(0, targetIndex)) { return; } /* When moving an item down, the destination index needs to be incremented by one, as explained in the documentation: http://doc.qt.nokia.com/qabstractitemmodel.html#beginMoveRows */ if (targetIndex > sourceIndex) { // Row will be moved down beginMoveRows(QModelIndex(), sourceIndex, sourceIndex, QModelIndex(), targetIndex + 1); } else { beginMoveRows(QModelIndex(), sourceIndex, sourceIndex, QModelIndex(), qMax(0, targetIndex)); } m_buttons.move(sourceIndex, qMax(0, targetIndex)); endMoveRows(); } 07070100000011000081A400000000000000000000000165EE4A9F00000870000000000000000000000000000000000000004D00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/buttonsmodel.h/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #ifndef KDECOARTIONS_PREVIEW_BUTTONS_MODEL_H #define KDECOARTIONS_PREVIEW_BUTTONS_MODEL_H #include <KDecoration2/DecorationButton> #include <QAbstractListModel> class PreviewBridge; class ButtonsModel : public QAbstractListModel { Q_OBJECT public: explicit ButtonsModel(const QVector<KDecoration2::DecorationButtonType> &buttons, QObject *parent = 0); explicit ButtonsModel(QObject *parent = nullptr); virtual ~ButtonsModel(); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QHash<int, QByteArray> roleNames() const override; QVector<KDecoration2::DecorationButtonType> buttons() const { return m_buttons; } Q_INVOKABLE void remove(int index); Q_INVOKABLE void up(int index); Q_INVOKABLE void down(int index); Q_INVOKABLE void move(int sourceIndex, int targetIndex); void add(KDecoration2::DecorationButtonType type); Q_INVOKABLE void add(int index, int type); private: QVector<KDecoration2::DecorationButtonType> m_buttons; }; #endif 07070100000012000081A400000000000000000000000165EE4A9F00000905000000000000000000000000000000000000004E00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/commontools.cpp/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. * */ #include "commontools.h" #include <QFileInfo> #include <QStandardPaths> QString standardPath(QString subPath, bool localfirst) { QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); if (localfirst) { for (const auto &pt : paths) { QString ptF = pt + "/" + subPath; if (QFileInfo(ptF).exists()) { return ptF; } } } else { for (int i = paths.count() - 1; i >= 0; i--) { QString ptF = paths[i] + "/" + subPath; if (QFileInfo(ptF).exists()) { return ptF; } } } //! in any case that above fails if (QFileInfo("/usr/share/" + subPath).exists()) { return "/usr/share/" + subPath; } return ""; } QStringList standardPaths(bool localfirst) { QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); if (localfirst) { return paths; } else { QStringList reversed; for (int i = paths.count() - 1; i >= 0; i--) { reversed << paths[i]; } return reversed; } } QStringList standardPathsFor(QString subPath, bool localfirst) { QStringList paths = standardPaths(localfirst); QString separator = subPath.startsWith("/") ? "" : "/"; for (int i = 0; i < paths.count(); ++i) { paths[i] = paths[i] + separator + subPath; } return paths; } 07070100000013000081A400000000000000000000000165EE4A9F0000045A000000000000000000000000000000000000004C00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/commontools.h/* * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. * */ #include <QString> #include <QStringList> //! returns the standard path found that contains the subPath //! local paths have higher priority by default QString standardPath(QString subPath, bool localFirst = true); QStringList standardPaths(bool localfirst = true); QStringList standardPathsFor(QString subPath, bool localfirst = true); 07070100000014000081A400000000000000000000000165EE4A9F000000E2000000000000000000000000000000000000005800000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/config-decoration.h.cmake#ifndef CONFIG_DECORATION_H #define CONFIG_DECORATION_H #cmakedefine KDECORATION2_VERSION_MAJOR @KDECORATION2_VERSION_MAJOR@ #cmakedefine KDECORATION2_VERSION_MINOR @KDECORATION2_VERSION_MINOR@ #endif // CONFIG_DECORATION_H 07070100000015000081A400000000000000000000000165EE4A9F000012C4000000000000000000000000000000000000005400000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/decorationpalette.cpp/******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr> Copyright 2015 Mika Allan Rauhala <mika.allan.rauhala@gmail.com> 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, see <http://www.gnu.org/licenses/>. *********************************************************************/ #include "decorationpalette.h" #include <KColorScheme> #include <KConfigGroup> #include <KSharedConfig> #include <QDebug> #include <QFileInfo> #include <QPalette> #include <QStandardPaths> DecorationPalette::DecorationPalette(const QString &colorScheme) : m_colorScheme(QFileInfo(colorScheme).isAbsolute() ? colorScheme : QStandardPaths::locate(QStandardPaths::GenericConfigLocation, colorScheme)) { if (m_colorScheme.isEmpty() && colorScheme == QStringLiteral("kdeglobals")) { // kdeglobals doesn't exist so create it. This is needed to monitor it using QFileSystemWatcher. auto config = KSharedConfig::openConfig(colorScheme, KConfig::SimpleConfig); KConfigGroup wmConfig(config, QStringLiteral("WM")); wmConfig.writeEntry("FakeEntryToKeepThisGroup", true); config->sync(); m_colorScheme = QStandardPaths::locate(QStandardPaths::GenericConfigLocation, colorScheme); } m_watcher.addPath(m_colorScheme); connect(&m_watcher, &QFileSystemWatcher::fileChanged, [this]() { m_watcher.addPath(m_colorScheme), update(), emit changed(); }); update(); } bool DecorationPalette::isValid() const { return m_activeTitleBarColor.isValid(); } QColor DecorationPalette::color(KDecoration2::ColorGroup group, KDecoration2::ColorRole role) const { using KDecoration2::ColorGroup; using KDecoration2::ColorRole; switch (role) { case ColorRole::Frame: { switch (group) { case ColorGroup::Active: return m_activeFrameColor; case ColorGroup::Inactive: return m_inactiveFrameColor; default: break; } break; } case ColorRole::TitleBar: { switch (group) { case ColorGroup::Active: return m_activeTitleBarColor; case ColorGroup::Inactive: return m_inactiveTitleBarColor; default: break; } break; } case ColorRole::Foreground: { switch (group) { case ColorGroup::Active: return m_activeForegroundColor; case ColorGroup::Inactive: return m_inactiveForegroundColor; case ColorGroup::Warning: return m_warningForegroundColor; default: break; } } default: break; } return QColor(); } QPalette DecorationPalette::palette() const { return m_palette; } void DecorationPalette::update() { auto config = KSharedConfig::openConfig(m_colorScheme, KConfig::SimpleConfig); KConfigGroup wmConfig(config, QStringLiteral("WM")); if (!wmConfig.exists() && !m_colorScheme.endsWith(QStringLiteral("/kdeglobals"))) { qDebug() << "Invalid color scheme" << m_colorScheme << "lacks WM group"; return; } m_palette = KColorScheme::createApplicationPalette(config); m_activeFrameColor = wmConfig.readEntry("frame", m_palette.color(QPalette::Active, QPalette::Base)); // !! TODO: Base? m_inactiveFrameColor = wmConfig.readEntry("inactiveFrame", m_activeFrameColor); m_activeTitleBarColor = wmConfig.readEntry("activeBackground", m_palette.color(QPalette::Active, QPalette::Highlight)); m_inactiveTitleBarColor = wmConfig.readEntry("inactiveBackground", m_inactiveFrameColor); m_activeForegroundColor = wmConfig.readEntry("activeForeground", m_palette.color(QPalette::Active, QPalette::HighlightedText)); m_inactiveForegroundColor = wmConfig.readEntry("inactiveForeground", m_activeForegroundColor.darker()); KConfigGroup windowColorsConfig(config, QStringLiteral("Colors:Window")); m_warningForegroundColor = windowColorsConfig.readEntry("ForegroundNegative", QColor(237, 21, 2)); } 07070100000016000081A400000000000000000000000165EE4A9F00000732000000000000000000000000000000000000005200000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/decorationpalette.h/******************************************************************** KWin - the KDE window manager This file is part of the KDE project. Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> Copyright 2014 Hugo Pereira Da Costa <hugo.pereira@free.fr> Copyright 2015 Mika Allan Rauhala <mika.allan.rauhala@gmail.com> 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, see <http://www.gnu.org/licenses/>. *********************************************************************/ #ifndef KWIN_DECORATION_PALETTE_H #define KWIN_DECORATION_PALETTE_H #include <KDecoration2/DecorationSettings> #include <QFileSystemWatcher> #include <QPalette> class DecorationPalette : public QObject { Q_OBJECT public: DecorationPalette(const QString &colorScheme); bool isValid() const; QColor color(KDecoration2::ColorGroup group, KDecoration2::ColorRole role) const; QPalette palette() const; Q_SIGNALS: void changed(); private: void update(); QString m_colorScheme; QFileSystemWatcher m_watcher; QPalette m_palette; QColor m_activeTitleBarColor; QColor m_inactiveTitleBarColor; QColor m_activeFrameColor; QColor m_inactiveFrameColor; QColor m_activeForegroundColor; QColor m_inactiveForegroundColor; QColor m_warningForegroundColor; }; #endif 07070100000017000081A400000000000000000000000165EE4A9F00002372000000000000000000000000000000000000005300000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/decorationsmodel.cpp/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #include "decorationsmodel.h" #include "previewbridge.h" #include <KConfigGroup> #include <KDecoration2/Decoration> #include <KDecoration2/DecorationSettings> #include <KDecoration2/DecorationThemeProvider> #include <KDirWatch> #include <KPluginFactory> #include <KSharedConfig> #include <Plasma/PluginLoader> #include <QDebug> #include <QDir> #include <kdecoration2/decorationthemeprovider.h> #include <qloggingcategory.h> Q_LOGGING_CATEGORY(decorations_model, "DecorationsModel"); static const QString s_defaultPlugin = QStringLiteral("org.kde.breeze"); static const QString s_defaultTheme; static const QString s_auroraePlugin = QStringLiteral("org.kde.kwin.aurorae"); static const QString s_auroraeSvgTheme = QStringLiteral("__aurorae__svg__"); static const QString s_kwinrc = QStringLiteral("kwinrc"); static const QString s_pluginName = QStringLiteral("org.kde.kdecoration2"); DecorationsModel::DecorationsModel(QObject *parent) : QAbstractListModel(parent) { init(); loadCurrents(); const auto kwinRc = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + s_kwinrc; KDirWatch::self()->addFile(kwinRc); connect(KDirWatch::self(), &KDirWatch::dirty, this, &DecorationsModel::kwinChanged); connect(KDirWatch::self(), &KDirWatch::created, this, &DecorationsModel::kwinChanged); } DecorationsModel::~DecorationsModel() = default; int DecorationsModel::count() const { return m_plugins.size(); } QString DecorationsModel::currentPlugin() const { return m_currentPlugin; } void DecorationsModel::setCurrentPlugin(QString plugin) { if (m_currentPlugin == plugin) { return; } m_currentPlugin = plugin; emit currentPluginChanged(); } QString DecorationsModel::currentTheme() const { return m_currentTheme; } void DecorationsModel::setCurrentTheme(QString theme) { if (m_currentTheme == theme) { return; } m_currentTheme = theme; emit currentThemeChanged(); } int DecorationsModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { return 0; } return m_plugins.size(); } QVariant DecorationsModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.column() != 0 || index.row() < 0 || index.row() >= int(m_plugins.size())) { return QVariant(); } const Data &d = m_plugins.at(index.row()); switch (role) { case Qt::DisplayRole: return d.visibleName; case Qt::UserRole + 4: return d.pluginName; case Qt::UserRole + 5: return d.themeName; case Qt::UserRole + 6: return d.isAuroraeTheme; case Qt::UserRole + 7: return d.configuration; } return QVariant(); } QHash<int, QByteArray> DecorationsModel::roleNames() const { QHash<int, QByteArray> roles({ { Qt::DisplayRole, QByteArrayLiteral("display") }, { Qt::UserRole + 4, QByteArrayLiteral("plugin") }, { Qt::UserRole + 5, QByteArrayLiteral("theme") }, { Qt::UserRole + 6, QByteArrayLiteral("isAuroraeTheme") }, { Qt::UserRole + 7, QByteArrayLiteral("configureable") } }); return roles; } static bool isThemeEngine(const QVariantMap &decoSettingsMap) { return decoSettingsMap["themes"].toBool(); } static bool isConfigureable(const QVariantMap &decoSettingsMap) { return decoSettingsMap["kcmodule"].toBool(); } static QString themeListKeyword(const QVariantMap &decoSettingsMap) { return decoSettingsMap["themeListKeyword"].toString(); } static QString findKNewStuff(const QVariantMap &decoSettingsMap) { return decoSettingsMap["KNewStuff"].toString(); } void DecorationsModel::init() { beginResetModel(); m_plugins.clear(); const auto plugins = KPluginMetaData::findPlugins(s_pluginName); for (const auto &info : plugins) { const auto decoSettingsMap = info.rawData().value("org.kde.kdecoration2").toObject().toVariantMap(); const QString &kns = findKNewStuff(decoSettingsMap); if (!kns.isEmpty() && !m_knsProvides.contains(kns)) m_knsProvides.insert(kns, info.name().isEmpty() ? info.pluginId() : info.name()); if (isThemeEngine(decoSettingsMap)) { const QString keyword = themeListKeyword(decoSettingsMap); if (keyword.isNull()) { // We cannot list the themes qWarning() << "No theme list keyword for" << info.pluginId(); continue; } const auto themeProvider = KPluginFactory::instantiatePlugin<KDecoration2::DecorationThemeProvider>(info).plugin; for (const auto &t : themeProvider->themes()) { Data data; data.pluginName = t.pluginId(); data.themeName = t.themeName(); data.visibleName = t.visibleName(); if (data.pluginName == s_auroraePlugin && data.themeName.startsWith(s_auroraeSvgTheme)) data.isAuroraeTheme = true; qCInfo(decorations_model) << "Adding theme" << data.visibleName << "from" << data.pluginName; m_plugins.emplace_back(std::move(data)); } } else { const Data data{ .pluginName = info.pluginId(), .themeName = QString(), .visibleName = info.name().isEmpty() ? info.pluginId() : info.name(), .isAuroraeTheme = false, .configuration = isConfigureable(decoSettingsMap), }; qCInfo(decorations_model) << "Adding theme" << data.visibleName << "from" << data.pluginName; m_plugins.emplace_back(std::move(data)); } } endResetModel(); } void DecorationsModel::loadCurrents() { const KConfigGroup config = KSharedConfig::openConfig(s_kwinrc)->group(s_pluginName); const QString plugin = config.readEntry("library", s_defaultPlugin); const QString theme = config.readEntry("theme", s_defaultTheme); bool exists{ false }; bool isAur{ isAurorae(plugin, theme) }; if ((!isAur && pluginExists(plugin)) || (isAur && decorationExists(plugin, theme))) { exists = true; } setCurrentPlugin(exists ? plugin : s_defaultPlugin); setCurrentTheme(exists ? theme : s_defaultTheme); } void DecorationsModel::kwinChanged(const QString &filename) { if (!filename.endsWith(s_kwinrc)) { return; } loadCurrents(); } bool DecorationsModel::isAurorae(const QString &plugin, const QString &theme) { auto it = std::find_if(m_plugins.cbegin(), m_plugins.cend(), [plugin, theme](const Data &d) { return d.pluginName == plugin && d.themeName == theme; }); if (it == m_plugins.cend()) { return false; } return (*it).isAuroraeTheme; } bool DecorationsModel::decorationExists(const QString &plugin, const QString &theme) { auto it = std::find_if(m_plugins.cbegin(), m_plugins.cend(), [plugin, theme](const Data &d) { return d.pluginName == plugin && d.themeName == theme; }); if (it == m_plugins.cend()) { return false; } return true; } bool DecorationsModel::pluginExists(const QString &plugin) { auto it = std::find_if(m_plugins.cbegin(), m_plugins.cend(), [plugin](const Data &d) { return d.pluginName == plugin; }); if (it == m_plugins.cend()) { return false; } return true; } QModelIndex DecorationsModel::findDecoration(const QString &pluginName, const QString &themeName) const { auto it = std::find_if(m_plugins.cbegin(), m_plugins.cend(), [pluginName, themeName](const Data &d) { return d.pluginName == pluginName && d.themeName == themeName; }); if (it == m_plugins.cend()) { return QModelIndex(); } const auto distance = std::distance(m_plugins.cbegin(), it); return createIndex(distance, 0); } 07070100000018000081A400000000000000000000000165EE4A9F00000B4A000000000000000000000000000000000000005100000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/decorationsmodel.h/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #ifndef DECORATIONSMODEL_H #define DECORATIONSMODEL_H #include <QAbstractListModel> class DecorationsModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(QString currentPlugin READ currentPlugin NOTIFY currentPluginChanged) Q_PROPERTY(QString currentTheme READ currentTheme NOTIFY currentThemeChanged) public: explicit DecorationsModel(QObject *parent = nullptr); virtual ~DecorationsModel(); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QHash<int, QByteArray> roleNames() const override; QModelIndex findDecoration(const QString &pluginName, const QString &themeName = QString()) const; QMap<QString, QString> knsProviders() const { return m_knsProvides; } int count() const; QString currentPlugin() const; QString currentTheme() const; public Q_SLOTS: Q_INVOKABLE bool decorationExists(const QString &plugin, const QString &theme); Q_INVOKABLE bool isAurorae(const QString &plugin, const QString &theme); signals: void countChanged(); void currentThemeChanged(); void currentPluginChanged(); private slots: void init(); void loadCurrents(); void kwinChanged(const QString &filename); void setCurrentPlugin(QString plugin); void setCurrentTheme(QString theme); private: bool pluginExists(const QString &plugin); private: struct Data { QString pluginName; QString themeName; QString visibleName; bool isAuroraeTheme = false; bool configuration = false; }; QString m_currentPlugin; QString m_currentTheme; std::vector<Data> m_plugins; QMap<QString, QString> m_knsProvides; }; #endif 07070100000019000081A400000000000000000000000165EE4A9F00000AE6000000000000000000000000000000000000004E00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/environment.cpp/* * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of Window Buttons Applet * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ #include "environment.h" #include <QDebug> #include <QProcess> #include <plasma_version.h> Environment::Environment(QObject *parent) : QObject(parent) { } Environment::~Environment() { qDebug() << staticMetaObject.className() << "destructed"; } uint Environment::frameworksVersion() const { return PLASMA_VERSION; } uint Environment::plasmaDesktopVersion() { if (m_plasmaDesktopVersion == -1) { m_plasmaDesktopVersion = identifyPlasmaDesktopVersion(); } return m_plasmaDesktopVersion; } uint Environment::makeVersion(uint major, uint minor, uint release) const { return (((major) << 16) | ((minor) << 8) | (release)); } uint Environment::identifyPlasmaDesktopVersion() { //! Identify Plasma Desktop version QProcess process; process.start("plasmashell", QStringList() << "-v"); process.waitForFinished(); QString output(process.readAllStandardOutput()); QStringList stringSplit = output.split(" "); if (stringSplit.count() >= 2) { qDebug() << " /////////////////////////"; QString cleanVersionString = stringSplit[1].remove("\n"); QStringList plasmaDesktopVersionParts = cleanVersionString.split("."); if (plasmaDesktopVersionParts.count() == 3) { uint maj = plasmaDesktopVersionParts[0].toUInt(); uint min = plasmaDesktopVersionParts[1].toUInt(); uint rel = plasmaDesktopVersionParts[2].toUInt(); if (maj > 0) { uint desktopVersion = makeVersion(maj, min, rel); QString message("Plasma Desktop version: " + QString::number(maj) + "." + QString::number(min) + "." + QString::number(rel) + " (" + QString::number(desktopVersion) + ")"); qDebug() << message; qDebug() << " /////////////////////////"; return desktopVersion; } } qDebug() << " /////////////////////////"; } return 0; } 0707010000001A000081A400000000000000000000000165EE4A9F000007A6000000000000000000000000000000000000004C00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/environment.h/* * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of Window Buttons Applet * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ #ifndef ENVIRONMENT_H #define ENVIRONMENT_H #include <QJSEngine> #include <QObject> #include <QQmlEngine> class Environment final : public QObject { Q_OBJECT Q_PROPERTY(uint frameworksVersion READ frameworksVersion NOTIFY frameworksVersionChanged) Q_PROPERTY(uint plasmaDesktopVersion READ plasmaDesktopVersion NOTIFY plasmaDesktopVersionChanged) public: virtual ~Environment(); bool compositingActive() const; bool isPlatformWayland() const; uint frameworksVersion() const; uint plasmaDesktopVersion(); static QObject *instance(QQmlEngine *engine, QJSEngine *scriptEngine) { Q_UNUSED(engine) Q_UNUSED(scriptEngine) // NOTE: QML engine is the owner of this resource return new Environment; } public slots: Q_INVOKABLE uint makeVersion(uint major, uint minor, uint release) const; signals: void frameworksVersionChanged(); void plasmaDesktopVersionChanged(); private: explicit Environment(QObject *parent = nullptr); void loadPlasmaDesktopVersion(); uint identifyPlasmaDesktopVersion(); private: int m_plasmaDesktopVersion{ -1 }; }; #endif // ENVIRONMENT_H 0707010000001B000081A400000000000000000000000165EE4A9F00000721000000000000000000000000000000000000004A00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/padding.cpp/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #include "padding.h" Padding::Padding(QObject *parent) : QObject(parent) { } Padding::~Padding() { } int Padding::top() const { return m_top; } void Padding::setTop(int top) { if (m_top == top) { return; } m_top = top; emit topChanged(); } int Padding::left() const { return m_left; } void Padding::setLeft(int left) { if (m_left == left) { return; } m_left = left; emit leftChanged(); } int Padding::bottom() const { return m_bottom; } void Padding::setBottom(int bottom) { if (m_bottom == bottom) { return; } m_bottom = bottom; emit bottomChanged(); } int Padding::right() const { return m_right; } void Padding::setRight(int right) { if (m_right == right) { return; } m_right = right; emit rightChanged(); } 0707010000001C000081A400000000000000000000000165EE4A9F00000751000000000000000000000000000000000000004800000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/padding.h/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #ifndef PADDING_H #define PADDING_H #include <QObject> class Padding : public QObject { Q_OBJECT Q_PROPERTY(int top READ top WRITE setTop NOTIFY topChanged); Q_PROPERTY(int left READ left WRITE setLeft NOTIFY leftChanged); Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomChanged); Q_PROPERTY(int right READ right WRITE setRight NOTIFY rightChanged); public: explicit Padding(QObject *parent = nullptr); virtual ~Padding(); int top() const; void setTop(int top); int left() const; void setLeft(int left); int bottom() const; void setBottom(int bottom); int right() const; void setRight(int right); signals: void topChanged(); void leftChanged(); void bottomChanged(); void rightChanged(); private: int m_top{ 0 }; int m_left{ 0 }; int m_bottom{ 0 }; int m_right{ 0 }; }; #endif 0707010000001D000081A400000000000000000000000165EE4A9F000017DD000000000000000000000000000000000000005000000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewbridge.cpp/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #include "previewbridge.h" #include "previewbutton.h" #include "previewclient.h" #include "previewsettings.h" #include <KDirWatch> #include <KPluginFactory> #include <KPluginMetaData> #include <QStandardPaths> static const QString s_pluginName = QStringLiteral("org.kde.kdecoration2"); static const QString s_breezerc = QStringLiteral("breezerc"); PreviewBridge::PreviewBridge(QObject *parent) : KDecoration2::DecorationBridge(parent), m_lastCreatedClient(nullptr), m_lastCreatedSettings(nullptr), m_valid(false) { connect(this, &PreviewBridge::pluginChanged, this, &PreviewBridge::createFactory); const auto breezeRc = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1Char('/') + s_breezerc; KDirWatch::self()->addFile(breezeRc); connect(KDirWatch::self(), &KDirWatch::dirty, this, &PreviewBridge::settingsFileChanged); connect(KDirWatch::self(), &KDirWatch::created, this, &PreviewBridge::settingsFileChanged); } PreviewBridge::~PreviewBridge() = default; std::unique_ptr<KDecoration2::DecoratedClientPrivate> PreviewBridge::createClient(KDecoration2::DecoratedClient *client, KDecoration2::Decoration *decoration) { auto ptr = std::make_unique<PreviewClient>(client, decoration); m_lastCreatedClient = ptr.get(); return ptr; } std::unique_ptr<KDecoration2::DecorationSettingsPrivate> PreviewBridge::settings(KDecoration2::DecorationSettings *parent) { auto ptr = std::make_unique<PreviewSettings>(parent); m_lastCreatedSettings = ptr.get(); return ptr; } void PreviewBridge::registerButton(PreviewButtonItem *button) { m_previewButtons.append(button); } void PreviewBridge::unregisterButton(PreviewButtonItem *button) { m_previewButtons.removeAll(button); } void PreviewBridge::setPlugin(const QString &plugin) { if (m_plugin == plugin) return; m_plugin = plugin; qDebug() << "Plugin changed to: " << m_plugin; emit pluginChanged(); } QString PreviewBridge::theme() const { return m_theme; } void PreviewBridge::setTheme(const QString &theme) { if (m_theme == theme) return; m_theme = theme; emit themeChanged(); } QString PreviewBridge::plugin() const { return m_plugin; } void PreviewBridge::createFactory() { m_factory.clear(); if (m_plugin.isNull()) { setValid(false); qDebug() << "Plugin not set"; return; } qDebug() << "Searching for plugins: " << m_plugin; const auto plugins = KPluginMetaData::findPluginById("org.kde.kdecoration2", m_plugin); m_factory = KPluginFactory::loadFactory(plugins).plugin; qDebug() << "Factory: " << !m_factory.isNull(); setValid(!m_factory.isNull()); reconfigure(); } bool PreviewBridge::isValid() const { return m_valid; } void PreviewBridge::setValid(bool valid) { if (m_valid == valid) return; m_valid = valid; emit validChanged(); } KDecoration2::Decoration *PreviewBridge::createDecoration(QObject *parent) { if (!m_valid) { return nullptr; } QVariantMap args({ { QStringLiteral("bridge"), QVariant::fromValue(this) } }); if (!m_theme.isNull()) { args.insert(QStringLiteral("theme"), m_theme); } return m_factory->create<KDecoration2::Decoration>(parent, QVariantList({ args })); } KDecoration2::DecorationButton *PreviewBridge::createButton(KDecoration2::Decoration *decoration, KDecoration2::DecorationButtonType type, QObject *parent) { if (!m_valid) { return nullptr; } auto button = m_factory->create<KDecoration2::DecorationButton>(parent, QVariantList({ QVariant::fromValue(type), QVariant::fromValue(decoration) })); if (!button) { // //! support decorations that have not been updated yet to KWin 5.23 decoration plugin approach // button = m_factory->create<KDecoration2::DecorationButton>(QStringLiteral("button"), parent, QVariantList({QVariant::fromValue(type), // QVariant::fromValue(decoration)})); if (button) { // qWarning() << "Loading a KDecoration2::DecorationButton using the button keyword is deprecated in KWin 5.23, register the plugin without a keyword // instead" << m_plugin; // } qWarning() << "removed button" << (int) type << "from" << m_plugin; } return button; } void PreviewBridge::settingsFileChanged(const QString &filename) { if (!filename.endsWith(s_breezerc)) { return; } reconfigure(); } void PreviewBridge::reconfigure() { if (m_lastCreatedSettings) { emit m_lastCreatedSettings->decorationSettings()->reconfigured(); } } BridgeItem::BridgeItem(QObject *parent) : QObject(parent), m_bridge(new PreviewBridge()) { connect(m_bridge, &PreviewBridge::themeChanged, this, &BridgeItem::themeChanged); connect(m_bridge, &PreviewBridge::pluginChanged, this, &BridgeItem::pluginChanged); connect(m_bridge, &PreviewBridge::validChanged, this, &BridgeItem::validChanged); } BridgeItem::~BridgeItem() { m_bridge->deleteLater(); } 0707010000001E000081A400000000000000000000000165EE4A9F000010A0000000000000000000000000000000000000004E00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewbridge.h/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #ifndef KDECORATIONS_PREVIEW_BRIDGE_H #define KDECORATIONS_PREVIEW_BRIDGE_H #include <KDecoration2/DecorationButton> #include <KDecoration2/Private/DecorationBridge> #include <QList> #include <QPointer> class KPluginFactory; class PreviewButtonItem; class PreviewClient; class PreviewSettings; class PreviewBridge : public KDecoration2::DecorationBridge { Q_OBJECT Q_PROPERTY(QString plugin READ plugin WRITE setPlugin NOTIFY pluginChanged) Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(bool valid READ isValid NOTIFY validChanged) public: explicit PreviewBridge(QObject *parent = nullptr); virtual ~PreviewBridge(); std::unique_ptr<KDecoration2::DecoratedClientPrivate> createClient(KDecoration2::DecoratedClient *client, KDecoration2::Decoration *decoration) override; std::unique_ptr<KDecoration2::DecorationSettingsPrivate> settings(KDecoration2::DecorationSettings *parent) override; PreviewClient *lastCreatedClient() { return m_lastCreatedClient; } PreviewSettings *lastCreatedSettings() { return m_lastCreatedSettings; } void registerButton(PreviewButtonItem *button); void unregisterButton(PreviewButtonItem *button); void setPlugin(const QString &plugin); QString plugin() const; void setTheme(const QString &theme); QString theme() const; bool isValid() const; KDecoration2::Decoration *createDecoration(QObject *parent = nullptr); KDecoration2::DecorationButton *createButton(KDecoration2::Decoration *decoration, KDecoration2::DecorationButtonType type, QObject *parent = nullptr); public Q_SLOTS: void reconfigure(); Q_SIGNALS: void pluginChanged(); void themeChanged(); void validChanged(); private slots: void settingsFileChanged(const QString &filename); private: void createFactory(); void setValid(bool valid); PreviewClient *m_lastCreatedClient; PreviewSettings *m_lastCreatedSettings; QList<PreviewButtonItem *> m_previewButtons; QString m_plugin; QString m_theme; QPointer<KPluginFactory> m_factory; bool m_valid; }; class BridgeItem : public QObject { Q_OBJECT Q_PROPERTY(QString plugin READ plugin WRITE setPlugin NOTIFY pluginChanged) Q_PROPERTY(QString theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(bool valid READ isValid NOTIFY validChanged) Q_PROPERTY(PreviewBridge *bridge READ bridge CONSTANT) public: explicit BridgeItem(QObject *parent = nullptr); virtual ~BridgeItem(); void setPlugin(const QString &plugin) { m_bridge->setPlugin(plugin); } QString plugin() const { return m_bridge->plugin(); } void setTheme(const QString &theme) { m_bridge->setTheme(theme); } QString theme() const { return m_bridge->theme(); } bool isValid() const { return m_bridge->isValid(); } PreviewBridge *bridge() const { return m_bridge; } Q_SIGNALS: void pluginChanged(); void themeChanged(); void validChanged(); private: PreviewBridge *m_bridge; }; Q_DECLARE_METATYPE(PreviewBridge *) #endif 0707010000001F000081A400000000000000000000000165EE4A9F00003777000000000000000000000000000000000000005000000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewbutton.cpp/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #include "previewbutton.h" #include "padding.h" #include "previewbridge.h" #include "previewclient.h" #include "previewsettings.h" #include "previewshareddecoration.h" #include <KDecoration2/DecoratedClient> #include <KDecoration2/Decoration> #include <QDebug> #include <QEvent> #include <QPainter> PreviewButtonItem::PreviewButtonItem(QQuickItem *parent) : QQuickPaintedItem(parent), m_scheme("kdeglobals"), m_padding(new Padding(this)) { setAcceptHoverEvents(true); setFiltersChildMouseEvents(true); setAcceptedMouseButtons(Qt::MouseButtons(Qt::LeftButton)); connect(this, &PreviewButtonItem::widthChanged, this, &PreviewButtonItem::syncInternalGeometry); connect(this, &PreviewButtonItem::heightChanged, this, &PreviewButtonItem::syncInternalGeometry); connect(this, &PreviewButtonItem::localXChanged, this, &PreviewButtonItem::syncInternalGeometry); connect(this, &PreviewButtonItem::localYChanged, this, &PreviewButtonItem::syncInternalGeometry); connect(this, &PreviewButtonItem::bridgeChanged, this, &PreviewButtonItem::onButtonDamaged); connect(this, &PreviewButtonItem::sharedDecorationChanged, this, &PreviewButtonItem::onButtonDamaged); connect(this, &PreviewButtonItem::isActiveChanged, this, &PreviewButtonItem::onButtonDamaged); connect(this, &PreviewButtonItem::isKeepAboveChanged, this, &PreviewButtonItem::onButtonDamaged); connect(this, &PreviewButtonItem::isMaximizedChanged, this, &PreviewButtonItem::onButtonDamaged); connect(this, &PreviewButtonItem::isOnAllDesktopsChanged, this, &PreviewButtonItem::onButtonDamaged); connect(this, &PreviewButtonItem::schemeChanged, this, &PreviewButtonItem::onButtonDamaged); connect(this, &PreviewButtonItem::typeChanged, this, &PreviewButtonItem::onButtonDamaged); connect(m_padding, &Padding::leftChanged, this, &PreviewButtonItem::syncInternalGeometry); connect(m_padding, &Padding::rightChanged, this, &PreviewButtonItem::syncInternalGeometry); connect(m_padding, &Padding::topChanged, this, &PreviewButtonItem::syncInternalGeometry); connect(m_padding, &Padding::bottomChanged, this, &PreviewButtonItem::syncInternalGeometry); } PreviewButtonItem::~PreviewButtonItem() { if (m_bridge) { m_bridge->unregisterButton(this); } if (m_button) { m_button->deleteLater(); } } bool PreviewButtonItem::isActive() const { return m_isActive; } void PreviewButtonItem::setIsActive(bool active) { if (m_isActive == active) { return; } m_isActive = active; if (m_client) { m_client->setActive(m_isActive); } emit isActiveChanged(); } bool PreviewButtonItem::isMaximized() const { return m_isMaximized; } void PreviewButtonItem::setIsMaximized(bool maximized) { if (m_isMaximized == maximized) { return; } m_isMaximized = maximized; if (m_client && m_button && m_type == KDecoration2::DecorationButtonType::Maximize) { if (m_isMaximized) { m_client->setMaximizedVertically(true); m_client->setMaximizedHorizontally(true); } else { m_client->setMaximizedVertically(false); m_client->setMaximizedHorizontally(false); } } emit isMaximizedChanged(); } bool PreviewButtonItem::isOnAllDesktops() const { return m_isOnAllDesktops; } void PreviewButtonItem::setIsOnAllDesktops(bool onalldesktops) { if (m_isOnAllDesktops == onalldesktops) { return; } m_isOnAllDesktops = onalldesktops; if (m_client && m_button && m_type == KDecoration2::DecorationButtonType::OnAllDesktops) { if (m_isOnAllDesktops) { m_client->setDesktop(-1); } else { m_client->setDesktop(1); } } emit isOnAllDesktopsChanged(); } bool PreviewButtonItem::isKeepAbove() const { return m_isKeepAbove; } void PreviewButtonItem::setIsKeepAbove(bool keepabove) { if (m_isKeepAbove == keepabove) { return; } m_isKeepAbove = keepabove; if (m_client && m_button && m_type == KDecoration2::DecorationButtonType::KeepAbove) { if (m_isKeepAbove) { m_client->setKeepAbove(true); } else { m_client->setKeepAbove(false); } } emit isKeepAboveChanged(); } KDecoration2::DecorationButtonType PreviewButtonItem::type() const { return m_type; } Padding *PreviewButtonItem::padding() const { return m_padding; } void PreviewButtonItem::setType(int type) { setType(KDecoration2::DecorationButtonType(type)); } void PreviewButtonItem::setType(KDecoration2::DecorationButtonType type) { if (m_type == type) { return; } m_type = type; emit typeChanged(); } QString PreviewButtonItem::scheme() const { return m_scheme; } void PreviewButtonItem::setScheme(QString scheme) { if (m_scheme == scheme) { return; } m_scheme = scheme.isEmpty() ? "kdeglobals" : scheme; if (m_client) { m_client->setColorScheme(m_scheme); qDebug() << "buttons scheme update to:" << m_scheme; } emit schemeChanged(); } PreviewBridge *PreviewButtonItem::bridge() const { return m_bridge.data(); } void PreviewButtonItem::setBridge(PreviewBridge *bridge) { if (m_bridge == bridge) { return; } if (m_bridge) { m_bridge->unregisterButton(this); } m_bridge = bridge; if (m_bridge) { m_bridge->registerButton(this); } emit bridgeChanged(); } int PreviewButtonItem::typeAsInt() const { return int(m_type); } int PreviewButtonItem::localX() const { return m_localX; } void PreviewButtonItem::setLocalX(int x) { if (m_localX == x) { return; } m_localX = x; emit localXChanged(); } int PreviewButtonItem::localY() const { return m_localY; } void PreviewButtonItem::setLocalY(int y) { if (m_localY == y) { return; } m_localY = y; emit localYChanged(); } KDecoration2::Decoration *PreviewButtonItem::decoration() const { if (!m_sharedDecoration) { return nullptr; } return m_sharedDecoration->decoration(); } SharedDecoration *PreviewButtonItem::sharedDecoration() const { return m_sharedDecoration; } void PreviewButtonItem::setSharedDecoration(SharedDecoration *sharedDecoration) { if (m_sharedDecoration == sharedDecoration) { return; } m_sharedDecoration = sharedDecoration; connect(m_sharedDecoration, &SharedDecoration::decorationChanged, this, &PreviewButtonItem::createButton); emit sharedDecorationChanged(); } void PreviewButtonItem::componentComplete() { createButton(); QQuickPaintedItem::componentComplete(); } void PreviewButtonItem::createButton() { if (m_type == KDecoration2::DecorationButtonType::Custom || !m_sharedDecoration || !m_sharedDecoration->decoration() || !m_bridge) { return; } m_client = m_bridge->lastCreatedClient(); if (!m_client) { return; } m_client->setMinimizable(true); m_client->setMaximizable(true); m_client->setActive(m_isActive); m_client->setColorScheme(m_scheme); if (m_isOnAllDesktops) { m_client->setDesktop(-1); } else { m_client->setDesktop(1); } if (m_isMaximized) { m_client->setMaximizedVertically(true); m_client->setMaximizedHorizontally(true); } else { m_client->setMaximizedVertically(false); m_client->setMaximizedHorizontally(false); } if (m_button) { m_button->deleteLater(); } m_button = m_bridge->createButton(m_sharedDecoration->decoration(), m_type, this); if (!m_button) { return; } if (!m_lastAppliedDecoration.isNull()) { disconnect(m_lastAppliedDecoration.data(), &KDecoration2::Decoration::damaged, this, &PreviewButtonItem::onDecorationDamaged); } connect(m_sharedDecoration->decoration(), &KDecoration2::Decoration::damaged, this, &PreviewButtonItem::onDecorationDamaged); m_lastAppliedDecoration = m_sharedDecoration->decoration(); m_button->setEnabled(true); m_button->setVisible(true); connect(m_button, &KDecoration2::DecorationButton::geometryChanged, this, &PreviewButtonItem::onButtonDamaged); syncInternalGeometry(); } QRect PreviewButtonItem::visualGeometry() const { return m_visualGeometry; } void PreviewButtonItem::syncInternalGeometry() { int iWidth = width() - m_padding->left() - m_padding->right(); int iHeight = height() - m_padding->top() - m_padding->bottom(); m_fullGeometry = QRect(0, 0, width(), height()); m_visualGeometry = QRect(m_localX + m_padding->left(), m_localY + m_padding->top(), iWidth, iHeight); if (!m_button) { return; } m_button->setGeometry(m_visualGeometry); } void PreviewButtonItem::onButtonDamaged() { if (m_sharedDecoration && m_sharedDecoration->decoration()) { emit m_sharedDecoration->decoration()->damaged(m_visualGeometry); } else { update(); } } void PreviewButtonItem::onDecorationDamaged(const QRegion ®ion) { if (region.intersects(m_visualGeometry)) { update(); } } void PreviewButtonItem::paint(QPainter *painter) { if (!m_button) { return; } painter->translate(-m_visualGeometry.x() + m_padding->left(), -m_visualGeometry.y() + m_padding->top()); m_button->paint(painter, m_visualGeometry); } void PreviewButtonItem::mouseDoubleClickEvent(QMouseEvent *event) { if (!m_button) { return; } QCoreApplication::instance()->sendEvent(decoration(), event); } void PreviewButtonItem::mousePressEvent(QMouseEvent *event) { if (!m_button) { return; } //! this a workaround in order to send proper coordinates //! that confirm the button visual coordinates QMouseEvent e(event->type(), m_visualGeometry.center(), event->button(), event->buttons(), event->modifiers()); QCoreApplication::instance()->sendEvent(m_button, &e); } void PreviewButtonItem::mouseReleaseEvent(QMouseEvent *event) { if (!m_button) { return; } bool inItem{ m_fullGeometry.contains(event->position().x(), event->position().y()) }; //! this a workaround in order to send proper coordinates //! that confirm the button visual coordinates QMouseEvent e(event->type(), inItem ? m_visualGeometry.center() : QPoint(-5, -5), event->button(), event->buttons(), event->modifiers()); QCoreApplication::instance()->sendEvent(m_button, event); if (inItem) { emit clicked(); } } void PreviewButtonItem::mouseMoveEvent(QMouseEvent *event) { if (!m_button) { return; } //! this a workaround in order to send proper coordinates //! that confirm the button visual coordinates QMouseEvent e(event->type(), m_visualGeometry.center(), event->button(), event->buttons(), event->modifiers()); QCoreApplication::instance()->sendEvent(m_button, &e); } void PreviewButtonItem::hoverEnterEvent(QHoverEvent *event) { if (!m_button) { return; } //! this a workaround in order to send proper coordinates //! that confirm the button visual coordinates QHoverEvent e(event->type(), m_visualGeometry.center(), QPoint(m_visualGeometry.x() + event->position().x(), m_visualGeometry.y() + event->position().y()), event->modifiers()); QCoreApplication::instance()->sendEvent(m_button, &e); } void PreviewButtonItem::hoverLeaveEvent(QHoverEvent *event) { if (!m_button) { return; } //! this a workaround in order to send proper coordinates //! that confirm the button visual coordinates QHoverEvent e(event->type(), QPoint(-5, -5), m_visualGeometry.center(), event->modifiers()); QCoreApplication::instance()->sendEvent(m_button, &e); } void PreviewButtonItem::hoverMoveEvent(QHoverEvent *event) { if (!m_button) { return; } QPoint newPos(qBound((double) m_visualGeometry.left(), m_visualGeometry.left() + event->position().x(), (double) m_visualGeometry.right()), qBound((double) m_visualGeometry.top(), m_visualGeometry.top() + event->position().x(), (double) m_visualGeometry.bottom())); QPoint oldPos(qBound((double) m_visualGeometry.left(), m_visualGeometry.left() + event->oldPosF().x(), (double) m_visualGeometry.right()), qBound((double) m_visualGeometry.top(), m_visualGeometry.top() + event->oldPosF().x(), (double) m_visualGeometry.bottom())); //! this a workaround in order to send proper coordinates //! that confirm the button visual coordinates QHoverEvent e(event->type(), newPos, oldPos, event->modifiers()); QCoreApplication::instance()->sendEvent(m_button, &e); } void PreviewButtonItem::focusOutEvent(QFocusEvent *event) { QCoreApplication::instance()->sendEvent(m_button, event); } 07070100000020000081A400000000000000000000000165EE4A9F00001414000000000000000000000000000000000000004E00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewbutton.h/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #ifndef KDECORATIONS_PREVIEW_BUTTON_ITEM_H #define KDECORATIONS_PREVIEW_BUTTON_ITEM_H #include "previewshareddecoration.h" #include <KDecoration2/DecorationButton> #include <QMargins> #include <QPointer> #include <QQuickPaintedItem> class Padding; class PreviewBridge; class PreviewClient; class PreviewButtonItem : public QQuickPaintedItem { Q_OBJECT Q_PROPERTY(PreviewBridge *bridge READ bridge WRITE setBridge NOTIFY bridgeChanged) Q_PROPERTY(SharedDecoration *sharedDecoration READ sharedDecoration WRITE setSharedDecoration NOTIFY sharedDecorationChanged) Q_PROPERTY(bool isActive READ isActive WRITE setIsActive NOTIFY isActiveChanged); Q_PROPERTY(bool isMaximized READ isMaximized WRITE setIsMaximized NOTIFY isMaximizedChanged) Q_PROPERTY(bool isOnAllDesktops READ isOnAllDesktops WRITE setIsOnAllDesktops NOTIFY isOnAllDesktopsChanged) Q_PROPERTY(bool isKeepAbove READ isKeepAbove WRITE setIsKeepAbove NOTIFY isKeepAboveChanged) Q_PROPERTY(int localX READ localX WRITE setLocalX NOTIFY localXChanged) Q_PROPERTY(int localY READ localY WRITE setLocalY NOTIFY localYChanged) Q_PROPERTY(int type READ typeAsInt WRITE setType NOTIFY typeChanged) Q_PROPERTY(QString scheme READ scheme WRITE setScheme NOTIFY schemeChanged) Q_PROPERTY(Padding *padding READ padding NOTIFY paddingChanged) public: explicit PreviewButtonItem(QQuickItem *parent = nullptr); virtual ~PreviewButtonItem(); void paint(QPainter *painter) override; PreviewBridge *bridge() const; void setBridge(PreviewBridge *bridge); SharedDecoration *sharedDecoration() const; void setSharedDecoration(SharedDecoration *sharedDecoration); KDecoration2::Decoration *decoration() const; bool isActive() const; void setIsActive(bool active); bool isMaximized() const; void setIsMaximized(bool maximized); bool isOnAllDesktops() const; void setIsOnAllDesktops(bool onalldesktops); bool isKeepAbove() const; void setIsKeepAbove(bool keepabove); int localX() const; void setLocalX(int x); int localY() const; void setLocalY(int y); KDecoration2::DecorationButtonType type() const; int typeAsInt() const; void setType(KDecoration2::DecorationButtonType type); void setType(int type); QString scheme() const; void setScheme(QString scheme); Padding *padding() const; QRect visualGeometry() const; Q_SIGNALS: void bridgeChanged(); void isActiveChanged(); void isMaximizedChanged(); void isOnAllDesktopsChanged(); void isKeepAboveChanged(); void localXChanged(); void localYChanged(); void paddingChanged(); void schemeChanged(); void sharedDecorationChanged(); void typeChanged(); void clicked(); protected: void mouseDoubleClickEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void hoverEnterEvent(QHoverEvent *event) override; void hoverLeaveEvent(QHoverEvent *event) override; void hoverMoveEvent(QHoverEvent *event) override; void focusOutEvent(QFocusEvent *event) override; void componentComplete() override; private Q_SLOTS: void createButton(); void syncInternalGeometry(); void onButtonDamaged(); void onDecorationDamaged(const QRegion ®ion); private: QPointer<PreviewBridge> m_bridge; QPointer<PreviewClient> m_client; QPointer<SharedDecoration> m_sharedDecoration; QPointer<KDecoration2::Decoration> m_lastAppliedDecoration; KDecoration2::DecorationButton *m_button = nullptr; KDecoration2::DecorationButtonType m_type = KDecoration2::DecorationButtonType::Custom; bool m_isActive{ true }; bool m_isMaximized{ false }; bool m_isOnAllDesktops{ false }; bool m_isKeepAbove{ false }; int m_localX; int m_localY; QString m_scheme; QRect m_internalGeometry; QRect m_fullGeometry; QRect m_visualGeometry; Padding *m_padding; }; #endif 07070100000021000081A400000000000000000000000165EE4A9F0000384F000000000000000000000000000000000000005000000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewclient.cpp/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #include "previewclient.h" #include <KDecoration2/DecoratedClient> #include <KDecoration2/Decoration> #include <QCoreApplication> #include <QDebug> #include <QEvent> #include <QModelIndex> PreviewClient::PreviewClient(KDecoration2::DecoratedClient *c, KDecoration2::Decoration *decoration) : QObject(decoration), ApplicationMenuEnabledDecoratedClientPrivate(c, decoration), m_icon(QIcon::fromTheme(QStringLiteral("start-here-kde"))), m_iconName(m_icon.name()) // , m_palette(new KWin::Decoration::DecorationPalette(QStringLiteral("kdeglobals"))) , m_active(true), m_closeable(true), m_keepBelow(false), m_keepAbove(false), m_maximizable(true), m_maximizedHorizontally(false), m_maximizedVertically(false), m_minimizable(true), m_modal(false), m_movable(true), m_resizable(true), m_shadeable(true), m_shaded(false), m_providesContextHelp(false), m_desktop(1), m_width(0), m_height(0), m_bordersTopEdge(false), m_bordersLeftEdge(false), m_bordersRightEdge(false), m_bordersBottomEdge(false) { connect(this, &PreviewClient::captionChanged, c, &KDecoration2::DecoratedClient::captionChanged); connect(this, &PreviewClient::activeChanged, c, &KDecoration2::DecoratedClient::activeChanged); connect(this, &PreviewClient::closeableChanged, c, &KDecoration2::DecoratedClient::closeableChanged); connect(this, &PreviewClient::keepAboveChanged, c, &KDecoration2::DecoratedClient::keepAboveChanged); connect(this, &PreviewClient::keepBelowChanged, c, &KDecoration2::DecoratedClient::keepBelowChanged); connect(this, &PreviewClient::maximizableChanged, c, &KDecoration2::DecoratedClient::maximizeableChanged); connect(this, &PreviewClient::maximizedChanged, c, &KDecoration2::DecoratedClient::maximizedChanged); connect(this, &PreviewClient::maximizedVerticallyChanged, c, &KDecoration2::DecoratedClient::maximizedVerticallyChanged); connect(this, &PreviewClient::maximizedHorizontallyChanged, c, &KDecoration2::DecoratedClient::maximizedHorizontallyChanged); connect(this, &PreviewClient::minimizableChanged, c, &KDecoration2::DecoratedClient::minimizeableChanged); // connect(this, &PreviewClient::modalChanged, c, &DecoratedClient::modalChanged); connect(this, &PreviewClient::movableChanged, c, &KDecoration2::DecoratedClient::moveableChanged); connect(this, &PreviewClient::onAllDesktopsChanged, c, &KDecoration2::DecoratedClient::onAllDesktopsChanged); connect(this, &PreviewClient::resizableChanged, c, &KDecoration2::DecoratedClient::resizeableChanged); connect(this, &PreviewClient::shadeableChanged, c, &KDecoration2::DecoratedClient::shadeableChanged); connect(this, &PreviewClient::shadedChanged, c, &KDecoration2::DecoratedClient::shadedChanged); connect(this, &PreviewClient::providesContextHelpChanged, c, &KDecoration2::DecoratedClient::providesContextHelpChanged); // connect(this, &PreviewClient::onAllDesktopsChanged, c, &KDecoration2::DecoratedClient::onAllDesktopsChanged); connect(this, &PreviewClient::widthChanged, c, &KDecoration2::DecoratedClient::widthChanged); connect(this, &PreviewClient::heightChanged, c, &KDecoration2::DecoratedClient::heightChanged); connect(this, &PreviewClient::iconChanged, c, &KDecoration2::DecoratedClient::iconChanged); connect(this, &PreviewClient::paletteChanged, c, &KDecoration2::DecoratedClient::paletteChanged); // connect(this, &PreviewClient::, c, &DecoratedClient::); connect(this, &PreviewClient::maximizedVerticallyChanged, this, [this]() { emit maximizedChanged(isMaximized()); }); connect(this, &PreviewClient::maximizedHorizontallyChanged, this, [this]() { emit maximizedChanged(isMaximized()); }); connect(this, &PreviewClient::iconNameChanged, this, [this]() { m_icon = QIcon::fromTheme(m_iconName); emit iconChanged(m_icon); }); connect(this, &PreviewClient::desktopChanged, this, [this](int) { emit onAllDesktopsChanged(isOnAllDesktops()); }); /* connect(m_palette, &KWin::Decoration::DecorationPalette::changed, [this]() { emit paletteChanged(m_palette->palette()); });*/ auto emitEdgesChanged = [this, c]() { c->adjacentScreenEdgesChanged(adjacentScreenEdges()); }; connect(this, &PreviewClient::bordersTopEdgeChanged, this, emitEdgesChanged); connect(this, &PreviewClient::bordersLeftEdgeChanged, this, emitEdgesChanged); connect(this, &PreviewClient::bordersRightEdgeChanged, this, emitEdgesChanged); connect(this, &PreviewClient::bordersBottomEdgeChanged, this, emitEdgesChanged); setColorScheme("kdeglobals"); qApp->installEventFilter(this); } PreviewClient::~PreviewClient() = default; void PreviewClient::setIcon(const QIcon &pixmap) { m_icon = pixmap; emit iconChanged(m_icon); } int PreviewClient::width() const { return m_width; } int PreviewClient::height() const { return m_height; } QString PreviewClient::caption() const { return m_caption; } WId PreviewClient::decorationId() const { return 0; } int PreviewClient::desktop() const { return m_desktop; } void PreviewClient::setDesktop(int desktop) { if (desktop == 0) { desktop = 1; } if (m_desktop == desktop) { return; } m_desktop = desktop; emit desktopChanged(m_desktop); } QIcon PreviewClient::icon() const { return m_icon; } QString PreviewClient::iconName() const { return m_iconName; } bool PreviewClient::isActive() const { return m_active; } bool PreviewClient::isCloseable() const { return m_closeable; } bool PreviewClient::isKeepAbove() const { return m_keepAbove; } bool PreviewClient::isKeepBelow() const { return m_keepBelow; } bool PreviewClient::isMaximizeable() const { return m_maximizable; } bool PreviewClient::isMaximized() const { return isMaximizedHorizontally() && isMaximizedVertically(); } bool PreviewClient::isMaximizedHorizontally() const { return m_maximizedHorizontally; } bool PreviewClient::isMaximizedVertically() const { return m_maximizedVertically; } bool PreviewClient::isMinimizeable() const { return m_minimizable; } bool PreviewClient::isModal() const { return m_modal; } bool PreviewClient::isMoveable() const { return m_movable; } bool PreviewClient::isOnAllDesktops() const { return desktop() == -1; } bool PreviewClient::isResizeable() const { return m_resizable; } bool PreviewClient::isShadeable() const { return m_shadeable; } bool PreviewClient::isShaded() const { return m_shaded; } bool PreviewClient::providesContextHelp() const { return m_providesContextHelp; } QString PreviewClient::windowClass() const { return QStringLiteral("kwin_preview"); } WId PreviewClient::windowId() const { return 0; } QPalette PreviewClient::palette() const { return m_palette->palette(); } QColor PreviewClient::color(KDecoration2::ColorGroup group, KDecoration2::ColorRole role) const { return m_palette->color(group, role); } void PreviewClient::setColorScheme(QString scheme) { if (m_colorScheme == scheme && !m_colorScheme.isEmpty()) { return; } m_colorScheme = scheme; if (m_palette) { m_palette->deleteLater(); } m_palette = new DecorationPalette(scheme); emit paletteChanged(m_palette->palette()); } Qt::Edges PreviewClient::adjacentScreenEdges() const { Qt::Edges edges; if (m_bordersBottomEdge) { edges |= Qt::BottomEdge; } if (m_bordersLeftEdge) { edges |= Qt::LeftEdge; } if (m_bordersRightEdge) { edges |= Qt::RightEdge; } if (m_bordersTopEdge) { edges |= Qt::TopEdge; } return edges; } bool PreviewClient::hasApplicationMenu() const { return true; } bool PreviewClient::isApplicationMenuActive() const { return false; } bool PreviewClient::bordersBottomEdge() const { return m_bordersBottomEdge; } bool PreviewClient::bordersLeftEdge() const { return m_bordersLeftEdge; } bool PreviewClient::bordersRightEdge() const { return m_bordersRightEdge; } bool PreviewClient::bordersTopEdge() const { return m_bordersTopEdge; } void PreviewClient::setBordersBottomEdge(bool enabled) { if (m_bordersBottomEdge == enabled) { return; } m_bordersBottomEdge = enabled; emit bordersBottomEdgeChanged(enabled); } void PreviewClient::setBordersLeftEdge(bool enabled) { if (m_bordersLeftEdge == enabled) { return; } m_bordersLeftEdge = enabled; emit bordersLeftEdgeChanged(enabled); } void PreviewClient::setBordersRightEdge(bool enabled) { if (m_bordersRightEdge == enabled) { return; } m_bordersRightEdge = enabled; emit bordersRightEdgeChanged(enabled); } void PreviewClient::setBordersTopEdge(bool enabled) { if (m_bordersTopEdge == enabled) { return; } m_bordersTopEdge = enabled; emit bordersTopEdgeChanged(enabled); } #if KDECORATION2_VERSION_MAJOR > 5 || KDECORATION2_VERSION_MINOR >= 13 void PreviewClient::requestShowToolTip(const QString &text) { Q_UNUSED(text) // qDebug() << "tooltip show requested with text:" << text; } void PreviewClient::requestHideToolTip() { // qDebug() << "tooltip hide requested"; } #endif #if KDECORATION2_VERSION_MAJOR > 5 || KDECORATION2_VERSION_MINOR >= 18 QSize PreviewClient::size() const { return { m_width, m_height }; } #endif #if KDECORATION2_VERSION_MAJOR <= 5 && KDECORATION2_VERSION_MINOR <= 20 void PreviewClient::requestShowWindowMenu() { emit showWindowMenuRequested(); } #else void PreviewClient::requestShowWindowMenu(const QRect &rect) { emit showWindowMenuRequested(); } #endif void PreviewClient::requestClose() { emit closeRequested(); } void PreviewClient::requestContextHelp() { qDebug() << "context help requested"; } void PreviewClient::requestToggleMaximization(Qt::MouseButtons buttons) { if (buttons.testFlag(Qt::LeftButton)) { const bool set = !isMaximized(); setMaximizedHorizontally(set); setMaximizedVertically(set); } else if (buttons.testFlag(Qt::RightButton)) { setMaximizedHorizontally(!isMaximizedHorizontally()); } else if (buttons.testFlag(Qt::MiddleButton)) { setMaximizedVertically(!isMaximizedVertically()); } } void PreviewClient::requestMinimize() { emit minimizeRequested(); } void PreviewClient::requestToggleKeepAbove() { setKeepAbove(!isKeepAbove()); } void PreviewClient::requestToggleKeepBelow() { setKeepBelow(!isKeepBelow()); } void PreviewClient::requestShowApplicationMenu(const QRect &rect, int actionId) { Q_UNUSED(rect); Q_UNUSED(actionId); } void PreviewClient::showApplicationMenu(int actionId) { Q_UNUSED(actionId) } void PreviewClient::requestToggleOnAllDesktops() { setDesktop(isOnAllDesktops() ? 1 : -1); } void PreviewClient::requestToggleShade() { setShaded(!isShaded()); } #define SETTER(type, name, variable) \ void PreviewClient::name(type variable) \ { \ if (m_##variable == variable) \ { \ return; \ } \ m_##variable = variable; \ emit variable##Changed(m_##variable); \ } #define SETTER2(name, variable) SETTER(bool, name, variable) SETTER(const QString &, setCaption, caption) SETTER(const QString &, setIconName, iconName) SETTER(int, setWidth, width) SETTER(int, setHeight, height) SETTER2(setActive, active) SETTER2(setCloseable, closeable) SETTER2(setMaximizable, maximizable) SETTER2(setKeepBelow, keepBelow) SETTER2(setKeepAbove, keepAbove) SETTER2(setMaximizedHorizontally, maximizedHorizontally) SETTER2(setMaximizedVertically, maximizedVertically) SETTER2(setMinimizable, minimizable) SETTER2(setModal, modal) SETTER2(setMovable, movable) SETTER2(setResizable, resizable) SETTER2(setShadeable, shadeable) SETTER2(setShaded, shaded) SETTER2(setProvidesContextHelp, providesContextHelp) #undef SETTER2 #undef SETTER 07070100000022000081A400000000000000000000000165EE4A9F00002439000000000000000000000000000000000000004E00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewclient.h/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #ifndef KDECORATIONS_PREVIEW_CLIENT_H #define KDECORATIONS_PREVIEW_CLIENT_H #include "decorationpalette.h" #include <KDecoration2/Private/DecoratedClientPrivate> #include <QObject> #include <QPalette> #include <config-decoration.h> #include <kdecoration2/decoration.h> class QAbstractItemModel; class PreviewClient : public QObject , public KDecoration2::ApplicationMenuEnabledDecoratedClientPrivate { Q_OBJECT Q_PROPERTY(KDecoration2::Decoration *decoration READ decoration CONSTANT) Q_PROPERTY(QString caption READ caption WRITE setCaption NOTIFY captionChanged) Q_PROPERTY(QIcon icon READ icon WRITE setIcon NOTIFY iconChanged) Q_PROPERTY(QString iconName READ iconName WRITE setIconName NOTIFY iconNameChanged) Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activeChanged) Q_PROPERTY(bool closeable READ isCloseable WRITE setCloseable NOTIFY closeableChanged) Q_PROPERTY(bool keepAbove READ isKeepAbove WRITE setKeepAbove NOTIFY keepAboveChanged) Q_PROPERTY(bool keepBelow READ isKeepBelow WRITE setKeepBelow NOTIFY keepBelowChanged) Q_PROPERTY(bool maximizable READ isMaximizeable WRITE setMaximizable NOTIFY maximizableChanged) Q_PROPERTY(bool maximized READ isMaximized NOTIFY maximizedChanged) Q_PROPERTY(bool maximizedVertically READ isMaximizedVertically WRITE setMaximizedVertically NOTIFY maximizedVerticallyChanged) Q_PROPERTY(bool maximizedHorizontally READ isMaximizedHorizontally WRITE setMaximizedHorizontally NOTIFY maximizedHorizontallyChanged) Q_PROPERTY(bool minimizable READ isMinimizeable WRITE setMinimizable NOTIFY minimizableChanged) Q_PROPERTY(bool modal READ isModal WRITE setModal NOTIFY modalChanged) Q_PROPERTY(bool movable READ isMoveable WRITE setMovable NOTIFY movableChanged) Q_PROPERTY(int desktop READ desktop WRITE setDesktop NOTIFY desktopChanged) Q_PROPERTY(bool onAllDesktops READ isOnAllDesktops NOTIFY onAllDesktopsChanged) Q_PROPERTY(bool resizable READ isResizeable WRITE setResizable NOTIFY resizableChanged) Q_PROPERTY(bool shadeable READ isShadeable WRITE setShadeable NOTIFY shadeableChanged) Q_PROPERTY(bool shaded READ isShaded WRITE setShaded NOTIFY shadedChanged) Q_PROPERTY(bool providesContextHelp READ providesContextHelp WRITE setProvidesContextHelp NOTIFY providesContextHelpChanged) Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) Q_PROPERTY(bool bordersTopEdge READ bordersTopEdge WRITE setBordersTopEdge NOTIFY bordersTopEdgeChanged) Q_PROPERTY(bool bordersLeftEdge READ bordersLeftEdge WRITE setBordersLeftEdge NOTIFY bordersLeftEdgeChanged) Q_PROPERTY(bool bordersRightEdge READ bordersRightEdge WRITE setBordersRightEdge NOTIFY bordersRightEdgeChanged) Q_PROPERTY(bool bordersBottomEdge READ bordersBottomEdge WRITE setBordersBottomEdge NOTIFY bordersBottomEdgeChanged) public: explicit PreviewClient(KDecoration2::DecoratedClient *client, KDecoration2::Decoration *decoration); virtual ~PreviewClient(); QString caption() const override; WId decorationId() const override; WId windowId() const override; int desktop() const; QIcon icon() const override; bool isActive() const override; bool isCloseable() const override; bool isKeepAbove() const override; bool isKeepBelow() const override; bool isMaximizeable() const override; bool isMaximized() const override; bool isMaximizedVertically() const override; bool isMaximizedHorizontally() const override; bool isMinimizeable() const override; bool isModal() const override; bool isMoveable() const override; bool isOnAllDesktops() const override; bool isResizeable() const override; bool isShadeable() const override; bool isShaded() const override; bool providesContextHelp() const override; QString windowClass() const override; int width() const override; int height() const override; QPalette palette() const override; QColor color(KDecoration2::ColorGroup group, KDecoration2::ColorRole role) const override; Qt::Edges adjacentScreenEdges() const override; bool hasApplicationMenu() const override; bool isApplicationMenuActive() const override; #if KDECORATION2_VERSION_MAJOR > 5 || KDECORATION2_VERSION_MINOR >= 13 void requestShowToolTip(const QString &text) override; void requestHideToolTip() override; #endif #if KDECORATION2_VERSION_MAJOR > 5 || KDECORATION2_VERSION_MINOR >= 18 QSize size() const override; #endif #if KDECORATION2_VERSION_MAJOR <= 5 && KDECORATION2_VERSION_MINOR <= 20 void requestShowWindowMenu() override; #else void requestShowWindowMenu(const QRect &rect) override; #endif void requestClose() override; void requestContextHelp() override; void requestToggleMaximization(Qt::MouseButtons buttons) override; void requestMinimize() override; void requestToggleKeepAbove() override; void requestToggleKeepBelow() override; void requestToggleShade() override; void requestShowApplicationMenu(const QRect &rect, int actionId) override; void requestToggleOnAllDesktops() override; void showApplicationMenu(int actionId) override; void setCaption(const QString &caption); void setActive(bool active); void setCloseable(bool closeable); void setMaximizable(bool maximizable); void setKeepBelow(bool keepBelow); void setKeepAbove(bool keepAbove); void setMaximizedHorizontally(bool maximized); void setMaximizedVertically(bool maximized); void setMinimizable(bool minimizable); void setModal(bool modal); void setMovable(bool movable); void setResizable(bool resizable); void setShadeable(bool shadeable); void setShaded(bool shaded); void setProvidesContextHelp(bool contextHelp); void setDesktop(int desktop); void setColorScheme(QString scheme); void setWidth(int width); void setHeight(int height); QString iconName() const; void setIconName(const QString &icon); void setIcon(const QIcon &icon); bool bordersTopEdge() const; bool bordersLeftEdge() const; bool bordersRightEdge() const; bool bordersBottomEdge() const; void setBordersTopEdge(bool enabled); void setBordersLeftEdge(bool enabled); void setBordersRightEdge(bool enabled); void setBordersBottomEdge(bool enabled); Q_SIGNALS: void captionChanged(const QString &); void iconChanged(const QIcon &); void iconNameChanged(const QString &); void activeChanged(bool); void closeableChanged(bool); void keepAboveChanged(bool); void keepBelowChanged(bool); void maximizableChanged(bool); void maximizedChanged(bool); void maximizedVerticallyChanged(bool); void maximizedHorizontallyChanged(bool); void minimizableChanged(bool); void modalChanged(bool); void movableChanged(bool); void onAllDesktopsChanged(bool); void resizableChanged(bool); void shadeableChanged(bool); void shadedChanged(bool); void providesContextHelpChanged(bool); void desktopChanged(int); void widthChanged(int); void heightChanged(int); void paletteChanged(const QPalette &); void bordersTopEdgeChanged(bool); void bordersLeftEdgeChanged(bool); void bordersRightEdgeChanged(bool); void bordersBottomEdgeChanged(bool); void showWindowMenuRequested(); void showApplicationMenuRequested(); void minimizeRequested(); void closeRequested(); private: QString m_caption; QIcon m_icon; QString m_iconName; QString m_colorScheme; DecorationPalette *m_palette{ nullptr }; bool m_active; bool m_closeable; bool m_keepBelow; bool m_keepAbove; bool m_maximizable; bool m_maximizedHorizontally; bool m_maximizedVertically; bool m_minimizable; bool m_modal; bool m_movable; bool m_resizable; bool m_shadeable; bool m_shaded; bool m_providesContextHelp; int m_desktop; int m_width; int m_height; bool m_bordersTopEdge; bool m_bordersLeftEdge; bool m_bordersRightEdge; bool m_bordersBottomEdge; }; #endif 07070100000023000081A400000000000000000000000165EE4A9F000024AF000000000000000000000000000000000000005200000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewsettings.cpp/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #include "previewsettings.h" #include "buttonsmodel.h" #include "previewbridge.h" #include <KLocalizedString> #include <QFontDatabase> #include <memory> BorderSizesModel::BorderSizesModel(QObject *parent) : QAbstractListModel(parent) { } BorderSizesModel::~BorderSizesModel() = default; QVariant BorderSizesModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.row() < 0 || index.row() >= m_borders.count() || index.column() != 0) { return QVariant(); } if (role != Qt::DisplayRole && role != Qt::UserRole) { return QVariant(); } return QVariant::fromValue<KDecoration2::BorderSize>(m_borders.at(index.row())); } int BorderSizesModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { return 0; } return m_borders.count(); } QHash<int, QByteArray> BorderSizesModel::roleNames() const { QHash<int, QByteArray> roles; roles.insert(Qt::DisplayRole, QByteArrayLiteral("display")); return roles; } PreviewSettings::PreviewSettings(KDecoration2::DecorationSettings *parent) : QObject(), KDecoration2::DecorationSettingsPrivate(parent), m_alphaChannelSupported(true), m_onAllDesktopsAvailable(true), m_closeOnDoubleClick(false), m_leftButtons( new ButtonsModel(QVector<KDecoration2::DecorationButtonType>({ KDecoration2::DecorationButtonType::Minimize, KDecoration2::DecorationButtonType::Close, KDecoration2::DecorationButtonType::Menu, KDecoration2::DecorationButtonType::ApplicationMenu, KDecoration2::DecorationButtonType::OnAllDesktops }), this)), m_rightButtons( new ButtonsModel(QVector<KDecoration2::DecorationButtonType>({ KDecoration2::DecorationButtonType::ContextHelp, KDecoration2::DecorationButtonType::Minimize, KDecoration2::DecorationButtonType::Maximize, KDecoration2::DecorationButtonType::Close }), this)), m_availableButtons( new ButtonsModel(QVector<KDecoration2::DecorationButtonType>({ KDecoration2::DecorationButtonType::Menu, KDecoration2::DecorationButtonType::ApplicationMenu, KDecoration2::DecorationButtonType::OnAllDesktops, KDecoration2::DecorationButtonType::Minimize, KDecoration2::DecorationButtonType::Maximize, KDecoration2::DecorationButtonType::Close, KDecoration2::DecorationButtonType::ContextHelp, KDecoration2::DecorationButtonType::Shade, KDecoration2::DecorationButtonType::KeepBelow, KDecoration2::DecorationButtonType::KeepAbove }), this)), m_borderSizes(new BorderSizesModel(this)), m_borderSize(int(KDecoration2::BorderSize::Normal)), m_font(QFontDatabase::systemFont(QFontDatabase::TitleFont)) { connect(this, &PreviewSettings::alphaChannelSupportedChanged, parent, &KDecoration2::DecorationSettings::alphaChannelSupportedChanged); connect(this, &PreviewSettings::onAllDesktopsAvailableChanged, parent, &KDecoration2::DecorationSettings::onAllDesktopsAvailableChanged); connect(this, &PreviewSettings::closeOnDoubleClickOnMenuChanged, parent, &KDecoration2::DecorationSettings::closeOnDoubleClickOnMenuChanged); connect(this, &PreviewSettings::fontChanged, parent, &KDecoration2::DecorationSettings::fontChanged); auto updateLeft = [this, parent]() { parent->decorationButtonsLeftChanged(decorationButtonsLeft()); }; auto updateRight = [this, parent]() { parent->decorationButtonsRightChanged(decorationButtonsRight()); }; connect(m_leftButtons, &QAbstractItemModel::rowsRemoved, this, updateLeft); connect(m_leftButtons, &QAbstractItemModel::rowsMoved, this, updateLeft); connect(m_leftButtons, &QAbstractItemModel::rowsInserted, this, updateLeft); connect(m_rightButtons, &QAbstractItemModel::rowsRemoved, this, updateRight); connect(m_rightButtons, &QAbstractItemModel::rowsMoved, this, updateRight); connect(m_rightButtons, &QAbstractItemModel::rowsInserted, this, updateRight); } PreviewSettings::~PreviewSettings() = default; QAbstractItemModel *PreviewSettings::availableButtonsModel() const { return m_availableButtons; } QAbstractItemModel *PreviewSettings::leftButtonsModel() const { return m_leftButtons; } QAbstractItemModel *PreviewSettings::rightButtonsModel() const { return m_rightButtons; } bool PreviewSettings::isAlphaChannelSupported() const { return m_alphaChannelSupported; } bool PreviewSettings::isOnAllDesktopsAvailable() const { return m_onAllDesktopsAvailable; } void PreviewSettings::setAlphaChannelSupported(bool supported) { if (m_alphaChannelSupported == supported) { return; } m_alphaChannelSupported = supported; emit alphaChannelSupportedChanged(m_alphaChannelSupported); } void PreviewSettings::setOnAllDesktopsAvailable(bool available) { if (m_onAllDesktopsAvailable == available) { return; } m_onAllDesktopsAvailable = available; emit onAllDesktopsAvailableChanged(m_onAllDesktopsAvailable); } void PreviewSettings::setCloseOnDoubleClickOnMenu(bool enabled) { if (m_closeOnDoubleClick == enabled) { return; } m_closeOnDoubleClick = enabled; emit closeOnDoubleClickOnMenuChanged(enabled); } QVector<KDecoration2::DecorationButtonType> PreviewSettings::decorationButtonsLeft() const { return m_leftButtons->buttons(); } QVector<KDecoration2::DecorationButtonType> PreviewSettings::decorationButtonsRight() const { return m_rightButtons->buttons(); } void PreviewSettings::addButtonToLeft(int row) { QModelIndex index = m_availableButtons->index(row); if (!index.isValid()) { return; } m_leftButtons->add(index.data(Qt::UserRole).value<KDecoration2::DecorationButtonType>()); } void PreviewSettings::addButtonToRight(int row) { QModelIndex index = m_availableButtons->index(row); if (!index.isValid()) { return; } m_rightButtons->add(index.data(Qt::UserRole).value<KDecoration2::DecorationButtonType>()); } void PreviewSettings::setBorderSizesIndex(int index) { if (m_borderSize == index) { return; } m_borderSize = index; emit borderSizesIndexChanged(index); emit decorationSettings()->borderSizeChanged(borderSize()); } KDecoration2::BorderSize PreviewSettings::borderSize() const { return m_borderSizes->index(m_borderSize).data(Qt::UserRole).value<KDecoration2::BorderSize>(); } void PreviewSettings::setFont(const QFont &font) { if (m_font == font) { return; } m_font = font; emit fontChanged(m_font); } Settings::Settings(QObject *parent) : QObject(parent) { connect(this, &Settings::bridgeChanged, this, &Settings::createSettings); } Settings::~Settings() = default; void Settings::setBridge(PreviewBridge *bridge) { if (m_bridge == bridge) { return; } m_bridge = bridge; emit bridgeChanged(); } PreviewBridge *Settings::bridge() const { return m_bridge.data(); } void Settings::createSettings() { if (m_bridge.isNull()) { m_settings.reset(); } else { m_settings = std::make_shared<KDecoration2::DecorationSettings>(m_bridge.data()); m_previewSettings = m_bridge->lastCreatedSettings(); m_previewSettings->setBorderSizesIndex(m_borderSize); connect(this, &Settings::borderSizesIndexChanged, m_previewSettings, &PreviewSettings::setBorderSizesIndex); } emit settingsChanged(); } std::shared_ptr<KDecoration2::DecorationSettings> Settings::settings() const { return m_settings; } KDecoration2::DecorationSettings *Settings::settingsPointer() const { return m_settings.get(); } void Settings::setBorderSizesIndex(int index) { if (m_borderSize == index) { return; } m_borderSize = index; emit borderSizesIndexChanged(m_borderSize); } 07070100000024000081A400000000000000000000000165EE4A9F0000182E000000000000000000000000000000000000005000000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewsettings.h/* * Copyright 2014 Martin Gräßlin <mgraesslin@kde.org> * 2018 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #ifndef KDECOARTIONS_PREVIEW_SETTINGS_H #define KDECOARTIONS_PREVIEW_SETTINGS_H #include <KDecoration2/DecorationSettings> #include <KDecoration2/Private/DecorationSettingsPrivate> #include <QAbstractListModel> #include <QObject> #include <QPointer> class ButtonsModel; class PreviewBridge; class BorderSizesModel : public QAbstractListModel { Q_OBJECT public: explicit BorderSizesModel(QObject *parent = 0); virtual ~BorderSizesModel(); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QHash<int, QByteArray> roleNames() const override; private: QList<KDecoration2::BorderSize> m_borders = QList<KDecoration2::BorderSize>({ KDecoration2::BorderSize::None, KDecoration2::BorderSize::NoSides, KDecoration2::BorderSize::Tiny, KDecoration2::BorderSize::Normal, KDecoration2::BorderSize::Large, KDecoration2::BorderSize::VeryLarge, KDecoration2::BorderSize::Huge, KDecoration2::BorderSize::VeryHuge, KDecoration2::BorderSize::Oversized }); }; class PreviewSettings : public QObject , public KDecoration2::DecorationSettingsPrivate { Q_OBJECT Q_PROPERTY(bool onAllDesktopsAvailable READ isOnAllDesktopsAvailable WRITE setOnAllDesktopsAvailable NOTIFY onAllDesktopsAvailableChanged) Q_PROPERTY(bool alphaChannelSupported READ isAlphaChannelSupported WRITE setAlphaChannelSupported NOTIFY alphaChannelSupportedChanged) Q_PROPERTY(bool closeOnDoubleClickOnMenu READ isCloseOnDoubleClickOnMenu WRITE setCloseOnDoubleClickOnMenu NOTIFY closeOnDoubleClickOnMenuChanged) Q_PROPERTY(QAbstractItemModel *leftButtonsModel READ leftButtonsModel CONSTANT) Q_PROPERTY(QAbstractItemModel *rightButtonsModel READ rightButtonsModel CONSTANT) Q_PROPERTY(QAbstractItemModel *availableButtonsModel READ availableButtonsModel CONSTANT) Q_PROPERTY(QAbstractItemModel *borderSizesModel READ borderSizesModel CONSTANT) Q_PROPERTY(int borderSizesIndex READ borderSizesIndex WRITE setBorderSizesIndex NOTIFY borderSizesIndexChanged) Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged) public: explicit PreviewSettings(KDecoration2::DecorationSettings *parent); virtual ~PreviewSettings(); bool isAlphaChannelSupported() const override; bool isOnAllDesktopsAvailable() const override; bool isCloseOnDoubleClickOnMenu() const override { return m_closeOnDoubleClick; } KDecoration2::BorderSize borderSize() const override; void setOnAllDesktopsAvailable(bool available); void setAlphaChannelSupported(bool supported); void setCloseOnDoubleClickOnMenu(bool enabled); QAbstractItemModel *leftButtonsModel() const; QAbstractItemModel *rightButtonsModel() const; QAbstractItemModel *availableButtonsModel() const; QAbstractItemModel *borderSizesModel() const { return m_borderSizes; } QVector<KDecoration2::DecorationButtonType> decorationButtonsLeft() const override; QVector<KDecoration2::DecorationButtonType> decorationButtonsRight() const override; Q_INVOKABLE void addButtonToLeft(int row); Q_INVOKABLE void addButtonToRight(int row); int borderSizesIndex() const { return m_borderSize; } void setBorderSizesIndex(int index); QFont font() const override { return m_font; } void setFont(const QFont &font); Q_SIGNALS: void onAllDesktopsAvailableChanged(bool); void alphaChannelSupportedChanged(bool); void closeOnDoubleClickOnMenuChanged(bool); void borderSizesIndexChanged(int); void fontChanged(const QFont &); private: bool m_alphaChannelSupported; bool m_onAllDesktopsAvailable; bool m_closeOnDoubleClick; ButtonsModel *m_leftButtons; ButtonsModel *m_rightButtons; ButtonsModel *m_availableButtons; BorderSizesModel *m_borderSizes; int m_borderSize; QFont m_font; }; class Settings : public QObject { Q_OBJECT Q_PROPERTY(PreviewBridge *bridge READ bridge WRITE setBridge NOTIFY bridgeChanged) Q_PROPERTY(KDecoration2::DecorationSettings *settings READ settingsPointer NOTIFY settingsChanged) Q_PROPERTY(int borderSizesIndex READ borderSizesIndex WRITE setBorderSizesIndex NOTIFY borderSizesIndexChanged) public: explicit Settings(QObject *parent = nullptr); virtual ~Settings(); PreviewBridge *bridge() const; void setBridge(PreviewBridge *bridge); std::shared_ptr<KDecoration2::DecorationSettings> settings() const; KDecoration2::DecorationSettings *settingsPointer() const; int borderSizesIndex() const { return m_borderSize; } void setBorderSizesIndex(int index); Q_SIGNALS: void bridgeChanged(); void settingsChanged(); void borderSizesIndexChanged(int); private: void createSettings(); QPointer<PreviewBridge> m_bridge; std::shared_ptr<KDecoration2::DecorationSettings> m_settings; PreviewSettings *m_previewSettings = nullptr; int m_borderSize = 3; }; #endif 07070100000025000081A400000000000000000000000165EE4A9F00000CCC000000000000000000000000000000000000005A00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewshareddecoration.cpp/* * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #include "previewshareddecoration.h" #include "previewbridge.h" #include "previewbutton.h" #include "previewsettings.h" #include <KDecoration2/Decoration> SharedDecoration::SharedDecoration(QObject *parent) : QObject(parent) { connect(this, &SharedDecoration::bridgeChanged, this, &SharedDecoration::createDecoration); connect(this, &SharedDecoration::settingsChanged, this, &SharedDecoration::applySettings); } SharedDecoration::~SharedDecoration() { } PreviewBridge *SharedDecoration::bridge() const { return m_bridge.data(); } void SharedDecoration::setBridge(PreviewBridge *bridge) { if (m_bridge == bridge) { return; } if (m_bridge) { connect(m_bridge, &PreviewBridge::validChanged, this, &SharedDecoration::createDecoration); } m_bridge = bridge; connect(m_bridge, &PreviewBridge::validChanged, this, &SharedDecoration::createDecoration); emit bridgeChanged(); } KDecoration2::Decoration *SharedDecoration::decoration() const { return m_decoration; } Settings *SharedDecoration::settings() const { return m_settings.data(); } void SharedDecoration::setSettings(Settings *settings) { if (m_settings == settings) { return; } m_settings = settings; createDecoration(); emit settingsChanged(); } void SharedDecoration::applySettings() { if (!m_decoration || !m_settings) { return; } m_decoration->setSettings(m_settings->settings()); m_decoration->init(); } void SharedDecoration::createDecoration() { if (!m_bridge || !m_settings) { return; } bool newDecoration = (m_bridge->plugin() != m_lastPlugin || m_bridge->theme() != m_lastTheme); if (m_decoration && newDecoration) { m_decoration->deleteLater(); } if (newDecoration) { m_decoration = m_bridge->createDecoration(this); } if (m_decoration) { m_decoration->setSettings(m_settings->settings()); m_decoration->init(); m_decoration->setObjectName("applet-window-buttons"); } m_lastPlugin = m_bridge->plugin(); m_lastTheme = m_bridge->theme(); emit decorationChanged(); } void SharedDecoration::initDecoration() { if (m_decoration) { m_decoration->init(); } } 07070100000026000081A400000000000000000000000165EE4A9F00000865000000000000000000000000000000000000005800000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/previewshareddecoration.h/* * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.org> * * This file is part of the libappletdecoration library * * 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) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * 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, see <http://www.gnu.org/licenses/>. */ #ifndef PREVIEWSHAREDDECORATION_H #define PREVIEWSHAREDDECORATION_H #include "previewbridge.h" #include "previewsettings.h" #include <QObject> class PreviewBridge; class PreviewButton; class Settings; class SharedDecoration : public QObject { Q_OBJECT Q_PROPERTY(PreviewBridge *bridge READ bridge WRITE setBridge NOTIFY bridgeChanged) Q_PROPERTY(Settings *settings READ settings WRITE setSettings NOTIFY settingsChanged) public: explicit SharedDecoration(QObject *parent = nullptr); virtual ~SharedDecoration(); PreviewBridge *bridge() const; void setBridge(PreviewBridge *bridge); Settings *settings() const; void setSettings(Settings *settings); KDecoration2::Decoration *decoration() const; void initDecoration(); public Q_SLOTS: Q_INVOKABLE void createDecoration(); Q_SIGNALS: void bridgeChanged(); void decorationChanged(); void settingsChanged(); private Q_SLOTS: void applySettings(); private: QPointer<PreviewBridge> m_bridge; QPointer<KDecoration2::Decoration> m_decoration; QPointer<Settings> m_settings; QString m_lastPlugin; QString m_lastTheme; }; #endif 07070100000027000041ED00000000000000000000000265EE4A9F00000000000000000000000000000000000000000000004200000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/qml07070100000028000081A400000000000000000000000165EE4A9F00001308000000000000000000000000000000000000005400000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/qml/AuroraeButton.qml/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQuick 2.7 import org.kde.plasma.plasmoid 2.0 import org.kde.ksvg as KSvg import org.kde.appletdecoration 0.1 as AppletDecoration MouseArea{ id: button hoverEnabled: true property bool isActive: true property bool isOnAllDesktops: false property bool isKeepAbove: false property bool isMaximized: false readonly property bool isToggledActivated: { return ((isOnAllDesktops && buttonType === AppletDecoration.Types.OnAllDesktops) || (isKeepAbove && buttonType === AppletDecoration.Types.KeepAbove) ); } property bool monochromeIconsEnabled: false property color monochromeIconsColor: "white" property int topPadding: 0 property int bottomPadding: 0 property int leftPadding: 0 property int rightPadding: 0 property int buttonType: AppletDecoration.Types.Close property int duration: auroraeTheme ? auroraeTheme.duration : 0 property QtObject auroraeTheme: null property string buttonImagePath: auroraeTheme ? auroraeTheme.themePath + '/' + auroraeTheme.monochromePrefix + iconName + '.' + auroraeTheme.themeType : "" property string iconName: { switch(buttonType){ case AppletDecoration.Types.Close: return "close"; case AppletDecoration.Types.Minimize: return "minimize"; case AppletDecoration.Types.Maximize: return (auroraeTheme.hasRestoreButton && button.isMaximized ? "restore" : "maximize"); case AppletDecoration.Types.OnAllDesktops: return "alldesktops"; case AppletDecoration.Types.KeepAbove: return "keepabove" default: return "close"; } } property string svgNormalElementId:{ return isActive ? "active-center" : "inactive-center"; } property string svgHoveredElementId:{ return containsPress || isToggledActivated ? "pressed-center" : "hover-center"; } KSvg.Svg { id: buttonSvg imagePath: buttonImagePath } // normal icon Item { id: svgNormalItem anchors.fill: parent anchors.topMargin: topPadding anchors.bottomMargin: bottomPadding anchors.leftMargin: leftPadding anchors.rightMargin: rightPadding opacity: !containsMouse && !containsPress && !isToggledActivated ? 1 : 0 KSvg.SvgItem { x: (parent.width / 2) - (width / 2) y: (parent.height / 2 ) - (height / 2) width: auroraeTheme.buttonRatio * height height: minimumSide svg: buttonSvg elementId: svgNormalElementId readonly property int minimumSide: Math.min(parent.width,parent.height) } Behavior on opacity { NumberAnimation { duration: button.duration easing.type: Easing.Linear } } } //! monochromize icon Loader { anchors.fill: svgNormalItem active: monochromeIconsEnabled // sourceComponent: ColorOverlay { // color: monochromeIconsColor // source: svgNormalItem // } } // hovered icon KSvg.SvgItem { id: svgHoveredItem anchors.fill: parent anchors.topMargin: topPadding anchors.bottomMargin: bottomPadding anchors.leftMargin: leftPadding anchors.rightMargin: rightPadding opacity: Math.abs(svgNormalItem.opacity - 1) KSvg.SvgItem { x: (parent.width / 2) - (width / 2) y: (parent.height / 2 ) - (height / 2) width: auroraeTheme.buttonRatio * height height: minimumSide svg: buttonSvg elementId: svgHoveredElementId readonly property int minimumSide: Math.min(parent.width,parent.height) } } //! monochromize icon Loader { anchors.fill: svgHoveredItem active: monochromeIconsEnabled && svgHoveredItem.opacity>0 // sourceComponent: ColorOverlay { // color: monochromeIconsColor // source: svgHoveredItem // } } } 07070100000029000081A400000000000000000000000165EE4A9F00000063000000000000000000000000000000000000004500000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/qmldirmodule org.kde.appletdecoration plugin appletdecorationplugin AuroraeButton 0.1 AuroraeButton.qml 0707010000002A000081A400000000000000000000000165EE4A9F00001AD9000000000000000000000000000000000000004F00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/schemecolors.cpp/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. * */ #include "schemecolors.h" #include "commontools.h" #include <KConfigGroup> #include <KDirWatch> #include <KSharedConfig> #include <QDebug> #include <QDir> #include <QFileInfo> #include <config-decoration.h> using namespace Qt::StringLiterals; SchemeColors::SchemeColors(QObject *parent, QString scheme, bool plasmaTheme) : QObject(parent), m_basedOnPlasmaTheme(plasmaTheme) { QString pSchemeFile = possibleSchemeFile(scheme); if (QFileInfo(pSchemeFile).exists()) { setSchemeFile(pSchemeFile); m_schemeName = schemeName(pSchemeFile); //! track scheme file for changes //! do not create so many trackers /*KDirWatch::self()->addFile(m_schemeFile); connect(KDirWatch::self(), &KDirWatch::dirty, this, [ & ](const QString & path) { if (path == m_schemeFile) { updateScheme(); } });*/ } updateScheme(); } SchemeColors::~SchemeColors() { } QColor SchemeColors::backgroundColor() const { return m_activeBackgroundColor; } QColor SchemeColors::textColor() const { return m_activeTextColor; } QColor SchemeColors::inactiveBackgroundColor() const { return m_inactiveBackgroundColor; } QColor SchemeColors::inactiveTextColor() const { return m_inactiveTextColor; } QColor SchemeColors::highlightColor() const { return m_highlightColor; } QColor SchemeColors::highlightedTextColor() const { return m_highlightedTextColor; } QColor SchemeColors::positiveText() const { return m_positiveColor; } QColor SchemeColors::neutralText() const { return m_neutralText; } QColor SchemeColors::negativeText() const { return m_negativeText; } QColor SchemeColors::buttonTextColor() const { return m_buttonTextColor; } QColor SchemeColors::buttonBackgroundColor() const { return m_buttonBackgroundColor; } QColor SchemeColors::buttonHoverColor() const { return m_buttonHoverColor; } QColor SchemeColors::buttonFocusColor() const { return m_buttonFocusColor; } QString SchemeColors::schemeName() const { return m_schemeName; } QString SchemeColors::SchemeColors::schemeFile() const { return m_schemeFile; } void SchemeColors::setSchemeFile(QString file) { if (m_schemeFile == file) { return; } m_schemeFile = file; emit schemeFileChanged(); } QString SchemeColors::possibleSchemeFile(QString scheme) { if (scheme.startsWith("/") && scheme.endsWith("colors") && QFileInfo(scheme).exists()) { return scheme; } QString tempScheme = scheme; if (scheme == "kdeglobals") { QString settingsFile = QDir::homePath() + "/.config/kdeglobals"; if (QFileInfo(settingsFile).exists()) { KSharedConfigPtr filePtr = KSharedConfig::openConfig(settingsFile); KConfigGroup generalGroup = KConfigGroup(filePtr, u"General"_qs); #if KDECORATION2_VERSION_MAJOR > 5 || KDECORATION2_VERSION_MINOR >= 21 tempScheme = generalGroup.readEntry("ColorScheme", "BreezeLight"); #else tempScheme = generalGroup.readEntry("ColorScheme", "Breeze"); #endif } } //! remove all whitespaces and "-" from scheme in order to access correctly its file QString schemeNameSimplified = tempScheme.simplified().remove(" ").remove("-"); return standardPath("color-schemes/" + schemeNameSimplified + ".colors"); } QString SchemeColors::schemeName(QString originalFile) { if (!(originalFile.startsWith("/") && originalFile.endsWith("colors") && QFileInfo(originalFile).exists())) { return ""; } QString fileNameNoExt = originalFile; int lastSlash = originalFile.lastIndexOf("/"); if (lastSlash >= 0) { fileNameNoExt.remove(0, lastSlash + 1); } if (fileNameNoExt.endsWith(".colors")) { fileNameNoExt.remove(".colors"); } KSharedConfigPtr filePtr = KSharedConfig::openConfig(originalFile); KConfigGroup generalGroup = KConfigGroup(filePtr, u"General"_qs); return generalGroup.readEntry("Name", fileNameNoExt); } void SchemeColors::updateScheme() { if (m_schemeFile.isEmpty() || !QFileInfo(m_schemeFile).exists()) { return; } KSharedConfigPtr filePtr = KSharedConfig::openConfig(m_schemeFile); KConfigGroup wmGroup = KConfigGroup(filePtr, u"WM"_qs); KConfigGroup selGroup = KConfigGroup(filePtr, u"Colors:Selection"_qs); KConfigGroup viewGroup = KConfigGroup(filePtr, u"Colors:View"_qs); // KConfigGroup windowGroup = KConfigGroup(filePtr, "Colors:Window"); KConfigGroup buttonGroup = KConfigGroup(filePtr, u"Colors:Button"_qs); if (!m_basedOnPlasmaTheme) { m_activeBackgroundColor = wmGroup.readEntry("activeBackground", QColor()); m_activeTextColor = wmGroup.readEntry("activeForeground", QColor()); m_inactiveBackgroundColor = wmGroup.readEntry("inactiveBackground", QColor()); m_inactiveTextColor = wmGroup.readEntry("inactiveForeground", QColor()); } else { m_activeBackgroundColor = viewGroup.readEntry("BackgroundNormal", QColor()); m_activeTextColor = viewGroup.readEntry("ForegroundNormal", QColor()); m_inactiveBackgroundColor = viewGroup.readEntry("BackgroundAlternate", QColor()); m_inactiveTextColor = viewGroup.readEntry("ForegroundInactive", QColor()); } m_highlightColor = selGroup.readEntry("BackgroundNormal", QColor()); m_highlightedTextColor = selGroup.readEntry("ForegroundNormal", QColor()); m_positiveColor = selGroup.readEntry("ForegroundPositive", QColor()); m_neutralText = selGroup.readEntry("ForegroundNeutral", QColor()); ; m_negativeText = selGroup.readEntry("ForegroundNegative", QColor()); m_buttonTextColor = buttonGroup.readEntry("ForegroundNormal", QColor()); m_buttonBackgroundColor = buttonGroup.readEntry("BackgroundNormal", QColor()); m_buttonHoverColor = buttonGroup.readEntry("DecorationHover", QColor()); m_buttonFocusColor = buttonGroup.readEntry("DecorationFocus", QColor()); emit colorsChanged(); } 0707010000002B000081A400000000000000000000000165EE4A9F00000DAD000000000000000000000000000000000000004D00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/schemecolors.h/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. * */ #ifndef SCHEMECOLORS_H #define SCHEMECOLORS_H #include <QColor> #include <QObject> class SchemeColors : public QObject { Q_OBJECT Q_PROPERTY(QString schemeFile READ schemeFile NOTIFY schemeFileChanged) Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY colorsChanged) Q_PROPERTY(QColor textColor READ textColor NOTIFY colorsChanged) Q_PROPERTY(QColor inactiveBackgroundColor READ inactiveBackgroundColor NOTIFY colorsChanged) Q_PROPERTY(QColor inactiveTextColor READ inactiveTextColor NOTIFY colorsChanged) Q_PROPERTY(QColor highlightColor READ highlightColor NOTIFY colorsChanged) Q_PROPERTY(QColor highlightedTextColor READ highlightedTextColor NOTIFY colorsChanged) Q_PROPERTY(QColor positiveText READ positiveText NOTIFY colorsChanged) Q_PROPERTY(QColor neutralText READ neutralText NOTIFY colorsChanged) Q_PROPERTY(QColor negativeText READ negativeText NOTIFY colorsChanged) Q_PROPERTY(QColor buttonTextColor READ buttonTextColor NOTIFY colorsChanged) Q_PROPERTY(QColor buttonBackgroundColor READ buttonBackgroundColor NOTIFY colorsChanged) Q_PROPERTY(QColor buttonHoverColor READ buttonHoverColor NOTIFY colorsChanged) Q_PROPERTY(QColor buttonFocusColor READ buttonFocusColor NOTIFY colorsChanged) public: SchemeColors(QObject *parent, QString scheme, bool plasmaTheme = false); ~SchemeColors() override; QString schemeName() const; QString schemeFile() const; void setSchemeFile(QString file); QColor backgroundColor() const; QColor textColor() const; QColor inactiveBackgroundColor() const; QColor inactiveTextColor() const; QColor highlightColor() const; QColor highlightedTextColor() const; QColor positiveText() const; QColor neutralText() const; QColor negativeText() const; QColor buttonTextColor() const; QColor buttonBackgroundColor() const; QColor buttonHoverColor() const; QColor buttonFocusColor() const; static QString possibleSchemeFile(QString scheme); static QString schemeName(QString originalFile); signals: void colorsChanged(); void schemeFileChanged(); public slots: void updateScheme(); private: bool m_basedOnPlasmaTheme{ false }; QString m_schemeName; QString m_schemeFile; QColor m_activeBackgroundColor; QColor m_activeTextColor; QColor m_inactiveBackgroundColor; QColor m_inactiveTextColor; QColor m_highlightColor; QColor m_highlightedTextColor; QColor m_positiveColor; QColor m_neutralText; QColor m_negativeText; QColor m_buttonTextColor; QColor m_buttonBackgroundColor; QColor m_buttonHoverColor; QColor m_buttonFocusColor; }; #endif 0707010000002C000081A400000000000000000000000165EE4A9F000013C3000000000000000000000000000000000000004F00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/schemesmodel.cpp/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. * */ #include "schemesmodel.h" #include "commontools.h" #include "schemecolors.h" #include <QDebug> #include <QDir> SchemesModel::SchemesModel(QObject *parent) : QAbstractListModel(parent) { initSchemes(); } SchemesModel::~SchemesModel() { qDeleteAll(m_schemes); } QVariant SchemesModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || index.column() != 0 || index.row() < 0 || index.row() >= m_schemes.count()) { return QVariant(); } const SchemeColors *d = m_schemes[index.row()]; switch (role) { case Qt::DisplayRole: if (index.row() == 0) { return "Current"; } else if (index.row() == 1) { return "Plasma Theme"; } return d->schemeName(); case Qt::UserRole + 4: if (index.row() == 0) { return "kdeglobals"; } else if (index.row() == 1) { return "_plasmatheme_"; } return d->schemeFile(); case Qt::UserRole + 5: return d->backgroundColor(); case Qt::UserRole + 6: return d->textColor(); } return QVariant(); } int SchemesModel::rowCount(const QModelIndex &parent) const { if (parent.isValid()) { return 0; } return m_schemes.count(); } QHash<int, QByteArray> SchemesModel::roleNames() const { QHash<int, QByteArray> roles({ { Qt::DisplayRole, QByteArrayLiteral("display") }, { Qt::UserRole + 4, QByteArrayLiteral("file") }, { Qt::UserRole + 5, QByteArrayLiteral("backgroundColor") }, { Qt::UserRole + 6, QByteArrayLiteral("textColor") } }); return roles; } QColor SchemesModel::backgroundOf(const int &index) const { if (index == 0) { auto ind = indexOf(m_defaultSchemeFile); return ind >= 0 ? m_schemes[ind]->backgroundColor() : QColor("transparent"); } if (index > 0 && index < m_schemes.count()) { return m_schemes[index]->backgroundColor(); } return QColor("transparent"); } QString SchemesModel::defaultSchemeFile() const { auto ind = indexOf(m_defaultSchemeFile); return ind >= 0 ? m_schemes[ind]->schemeFile() : QString(); } void SchemesModel::initSchemes() { qDeleteAll(m_schemes); m_schemes.clear(); QString currentSchemePath = SchemeColors::possibleSchemeFile("kdeglobals"); insertSchemeInList(currentSchemePath); m_defaultSchemeFile = currentSchemePath; QStringList standardPaths = standardPathsFor("color-schemes"); QStringList registeredSchemes; for (auto path : standardPaths) { QDir directory(path); QStringList tempSchemes = directory.entryList(QStringList() << "*.colors" << "*.COLORS", QDir::Files); foreach (QString filename, tempSchemes) { if (!registeredSchemes.contains(filename)) { QString fullPath = path + "/" + filename; insertSchemeInList(fullPath); registeredSchemes << filename; } } } } void SchemesModel::insertSchemeInList(QString file) { SchemeColors *tempScheme = new SchemeColors(this, file); int atPos{ 0 }; for (int i = 0; i < m_schemes.count(); i++) { SchemeColors *s = m_schemes[i]; int result = QString::compare(tempScheme->schemeName(), s->schemeName(), Qt::CaseInsensitive); if (result < 0) { atPos = i; break; } else { atPos = i + 1; } } m_schemes.insert(atPos, tempScheme); } int SchemesModel::indexOf(QString file) const { if (file.isEmpty() || file == "kdeglobals") { return 0; } if (file == "_plasmatheme_") { return 1; } for (int i = 0; i < m_schemes.count(); i++) { SchemeColors *s = m_schemes[i]; if (s->schemeFile() == file) { return i; } } return -1; } 0707010000002D000081A400000000000000000000000165EE4A9F00000642000000000000000000000000000000000000004D00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/schemesmodel.h/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. * */ #ifndef SCHEMESMODEL_H #define SCHEMESMODEL_H #include <QAbstractListModel> class SchemeColors; class SchemesModel : public QAbstractListModel { Q_OBJECT public: explicit SchemesModel(QObject *parent = nullptr); virtual ~SchemesModel(); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QHash<int, QByteArray> roleNames() const override; Q_INVOKABLE int indexOf(QString file) const; Q_INVOKABLE QColor backgroundOf(const int &index) const; Q_INVOKABLE QString defaultSchemeFile() const; private slots: void initSchemes(); private: void insertSchemeInList(QString file); private: QString m_defaultSchemeFile; QList<SchemeColors *> m_schemes; }; #endif 0707010000002E000081A400000000000000000000000165EE4A9F0000168A000000000000000000000000000000000000005000000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/themeextended.cpp/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. * */ #include "themeextended.h" #include "commontools.h" #include "schemecolors.h" #include <KConfigGroup> #include <KDirWatch> #include <KSharedConfig> #include <QDebug> #include <QDir> #define DEFAULTCOLORSCHEME "default.colors" ExtendedTheme::ExtendedTheme(QObject *parent) : QObject(parent) { load(); connect(&m_theme, &Plasma::Theme::themeChanged, this, &ExtendedTheme::load); connect(&m_theme, &Plasma::Theme::themeChanged, this, &ExtendedTheme::themeChanged); } ExtendedTheme::~ExtendedTheme() { m_colorsScheme->deleteLater(); } void ExtendedTheme::load() { loadThemePaths(); } QObject *ExtendedTheme::colors() const { return m_colorsScheme; } void ExtendedTheme::setOriginalSchemeFile(const QString &file) { if (m_originalSchemePath == file) { return; } m_originalSchemePath = file; qDebug() << "Window Buttons : plasma theme original colors ::: " << m_originalSchemePath; updateDefaultScheme(); emit themeChanged(); } //! WM records need to be updated based on the colors that //! plasma will use in order to be consistent. Such an example //! are the Breeze color schemes that have different values for //! WM and the plasma theme records void ExtendedTheme::updateDefaultScheme() { QString defaultFilePath = m_extendedThemeDir.path() + "/" + DEFAULTCOLORSCHEME; if (QFileInfo(defaultFilePath).exists()) { QFile(defaultFilePath).remove(); } QFile(m_originalSchemePath).copy(defaultFilePath); m_colorsSchemePath = defaultFilePath; updateDefaultSchemeValues(); if (m_colorsScheme) { disconnect(m_colorsScheme, &SchemeColors::colorsChanged, this, &ExtendedTheme::themeChanged); m_colorsScheme->deleteLater(); } m_colorsScheme = new SchemeColors(this, m_colorsSchemePath, true); connect(m_colorsScheme, &SchemeColors::colorsChanged, this, &ExtendedTheme::themeChanged); qDebug() << "Window Buttons : plasma theme default colors ::: " << m_colorsSchemePath; emit colorsChanged(); } void ExtendedTheme::updateDefaultSchemeValues() { //! update WM values based on original scheme KSharedConfigPtr originalPtr = KSharedConfig::openConfig(m_originalSchemePath); KSharedConfigPtr defaultPtr = KSharedConfig::openConfig(m_colorsSchemePath); if (originalPtr && defaultPtr) { KConfigGroup normalWindowGroup(originalPtr, u"Colors:Window"_qs); KConfigGroup defaultWMGroup(defaultPtr, u"WM"_qs); defaultWMGroup.writeEntry("activeBackground", normalWindowGroup.readEntry("BackgroundNormal", QColor())); defaultWMGroup.writeEntry("activeForeground", normalWindowGroup.readEntry("ForegroundNormal", QColor())); defaultWMGroup.sync(); } } void ExtendedTheme::loadThemePaths() { m_themePath = standardPath("plasma/desktoptheme/" + m_theme.themeName()); if (QDir(m_themePath + "/widgets").exists()) { m_themeWidgetsPath = m_themePath + "/widgets"; } else { m_themeWidgetsPath = standardPath("plasma/desktoptheme/default/widgets"); } qDebug() << "Window Buttons : current plasma theme ::: " << m_theme.themeName(); qDebug() << "Window Buttons : theme path ::: " << m_themePath; qDebug() << "Window Buttons : theme widgets path ::: " << m_themeWidgetsPath; //! clear kde connections for (auto &c : m_kdeConnections) { disconnect(c); } //! assign color schemes QString themeColorScheme = m_themePath + "/colors"; if (QFileInfo(themeColorScheme).exists()) { setOriginalSchemeFile(themeColorScheme); } else { //! when plasma theme uses the kde colors //! we track when kde color scheme is changing QString kdeSettingsFile = QDir::homePath() + "/.config/kdeglobals"; KDirWatch::self()->addFile(kdeSettingsFile); m_kdeConnections[0] = connect(KDirWatch::self(), &KDirWatch::dirty, this, [&, kdeSettingsFile](const QString &path) { if (path == kdeSettingsFile) { this->setOriginalSchemeFile(SchemeColors::possibleSchemeFile("kdeglobals")); } }); m_kdeConnections[1] = connect(KDirWatch::self(), &KDirWatch::created, this, [&, kdeSettingsFile](const QString &path) { if (path == kdeSettingsFile) { this->setOriginalSchemeFile(SchemeColors::possibleSchemeFile("kdeglobals")); } }); setOriginalSchemeFile(SchemeColors::possibleSchemeFile("kdeglobals")); } } 0707010000002F000081A400000000000000000000000165EE4A9F0000072E000000000000000000000000000000000000004E00000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/themeextended.h/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. * */ #ifndef PLASMAEXTENDEDTHEME_H #define PLASMAEXTENDEDTHEME_H #include "schemecolors.h" #include <KConfigGroup> #include <KSharedConfig> #include <KSvg/FrameSvg> #include <Plasma/Theme> #include <QObject> #include <QTemporaryDir> #include <array> class ExtendedTheme : public QObject { Q_OBJECT Q_PROPERTY(QObject *colors READ colors NOTIFY colorsChanged) public: ExtendedTheme(QObject *parent = nullptr); ~ExtendedTheme() override; ; QObject *colors() const; void load(); signals: void colorsChanged(); void themeChanged(); private: void loadThemePaths(); void setOriginalSchemeFile(const QString &file); void updateDefaultScheme(); void updateDefaultSchemeValues(); private: QString m_themePath; QString m_themeWidgetsPath; QString m_colorsSchemePath; QString m_originalSchemePath; std::array<QMetaObject::Connection, 2> m_kdeConnections; QTemporaryDir m_extendedThemeDir; KConfigGroup m_themeGroup; Plasma::Theme m_theme; SchemeColors *m_colorsScheme{ nullptr }; }; #endif 07070100000030000081A400000000000000000000000165EE4A9F00000323000000000000000000000000000000000000004800000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/types.cpp/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ #include "types.h" 07070100000031000081A400000000000000000000000165EE4A9F000007D7000000000000000000000000000000000000004600000000applet-window-buttons6-1710115487.a7b95da/libappletdecoration/types.h/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of the libappletdecoration library * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ #ifndef TYPES_H #define TYPES_H #include <QMetaEnum> #include <QMetaType> #include <QObject> class Types { Q_GADGET public: Types() = delete; ~Types(){}; enum ButtonType { Menu = 0, ApplicationMenu, OnAllDesktops, Minimize, Maximize, Close, ContextHelp, Shade, KeepBelow, KeepAbove, Custom }; Q_ENUM(ButtonType) enum Actions { ActionClose = 0, ToggleMinimize, ToggleMaximize, TogglePinToAllDesktops, ToggleKeepAbove }; Q_ENUM(Actions) enum ButtonSize { TinyButton = 0, NormalButton, LargeButton, VeryLargeButton, HugeButton, VeryHugeButton, OversizedButton }; Q_ENUM(ButtonSize) enum Visibility { AlwaysVisible = 0, ActiveWindow, ActiveMaximizedWindow, ShownWindowExists }; Q_ENUM(Visibility) enum HiddenState { SlideOut = 0, EmptySpace }; Q_ENUM(HiddenState) enum ContainmentType { Loading = 0, Plasma, Latte }; Q_ENUM(ContainmentType) }; #endif 07070100000032000041ED00000000000000000000000365EE4A9F00000000000000000000000000000000000000000000003200000000applet-window-buttons6-1710115487.a7b95da/package07070100000033000041ED00000000000000000000000565EE4A9F00000000000000000000000000000000000000000000003B00000000applet-window-buttons6-1710115487.a7b95da/package/contents07070100000034000041ED00000000000000000000000265EE4A9F00000000000000000000000000000000000000000000004000000000applet-window-buttons6-1710115487.a7b95da/package/contents/code07070100000035000081A400000000000000000000000165EE4A9F00000B3A000000000000000000000000000000000000004900000000applet-window-buttons6-1710115487.a7b95da/package/contents/code/tools.js/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of Latte-Dock * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ function addButton(preparedArray, buttonType) { if (buttonType === AppletDecoration.Types.Close) { preparedArray.push({ buttonType: AppletDecoration.Types.Close, windowOperation: AppletDecoration.Types.ActionClose }); } else if (buttonType === AppletDecoration.Types.Maximize) { preparedArray.push({ buttonType: AppletDecoration.Types.Maximize, windowOperation: AppletDecoration.Types.ToggleMaximize }); } else if (buttonType === AppletDecoration.Types.Minimize) { preparedArray.push({ buttonType: AppletDecoration.Types.Minimize, windowOperation: AppletDecoration.Types.ToggleMinimize }); } else if (buttonType === AppletDecoration.Types.OnAllDesktops) { preparedArray.push({ buttonType: AppletDecoration.Types.OnAllDesktops, windowOperation: AppletDecoration.Types.TogglePinToAllDesktops }); } else if (buttonType === AppletDecoration.Types.Custom) { preparedArray.push({ buttonType: AppletDecoration.Types.Custom, windowOperation: -1 }); } else if (buttonType === AppletDecoration.Types.KeepAbove) { preparedArray.push({ buttonType: AppletDecoration.Types.KeepAbove, windowOperation: AppletDecoration.Types.ToggleKeepAbove }); } } function indexOfSplitter(listModel) { for (var i = 0; i < listModel.count; ++i) { var item = listModel.get(i); if (item.buttonType === AppletDecoration.Types.Custom) { return i; } } return -1; } function initializeControlButtonsModel(buttons, toArray, toListModel, stopOnSeparator) { toArray.length = 0; for (var i = 0; i < buttons.length; ++i) { var type = Number(buttons[i]); if (type === AppletDecoration.Types.Custom && stopOnSeparator) { break; } addButton(toArray, Number(buttons[i])); } toListModel.clear() for (var i = 0; i < toArray.length; ++i) { toListModel.append(toArray[i]); } } 07070100000036000041ED00000000000000000000000265EE4A9F00000000000000000000000000000000000000000000004200000000applet-window-buttons6-1710115487.a7b95da/package/contents/config07070100000037000081A400000000000000000000000165EE4A9F000003D7000000000000000000000000000000000000004D00000000applet-window-buttons6-1710115487.a7b95da/package/contents/config/config.qml/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-buttons * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQuick 2.0 import org.kde.plasma.configuration 2.0 ConfigModel { ConfigCategory { name: i18n("General") icon: "preferences-desktop-display-color" source: "config/ConfigGeneral.qml" } } 07070100000038000081A400000000000000000000000165EE4A9F00000ED0000000000000000000000000000000000000004B00000000applet-window-buttons6-1710115487.a7b95da/package/contents/config/main.xml<?xml version="1.0" encoding="UTF-8"?> <kcfg xmlns="http://www.kde.org/standards/kcfg/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0 http://www.kde.org/standards/kcfg/1.0/kcfg.xsd"> <kcfgfile name="" /> <group name="General"> <entry name="useCurrentDecoration" type="Bool"> <default>true</default> <label>use the system current decoration at all times. The decoration is updated accordingly when needed</label> </entry> <entry name="selectedPlugin" type="String"> <default>org.kde.breeze</default> <label>user preferred decoration plugin to use</label> </entry> <entry name="selectedScheme" type="String"> <default>_plasmatheme_</default> <label>user preferred color scheme to use with the selected plugin</label> </entry> <entry name="selectedTheme" type="String"> <label>user preferred theme to use with the selected plugin</label> </entry> <entry name="buttons" type="String"> <default>5|4|3|10|2|9</default> <label>buttons to show in applet</label> </entry> <entry name="visibility" type="Enum"> <choices> <choice name="AlwaysVisible" /> <choice name="ActiveWindow" /> <choice name="ActiveMaximizedWindow" /> </choices> <label>when the applet will be visible</label> <default>0</default> </entry> <entry name="filterByScreen" type="Bool"> <default>true</default> <label>if false active window can be on any screen</label> </entry> <entry name="perScreenActive" type="Bool"> <default>false</default> <label>Per-screen active window</label> </entry> <entry name="hiddenState" type="Enum"> <choices> <choice name="SlideOut" /> <choice name="EmptySpace" /> </choices> <label>when the applet should be hidden how it should behave</label> <default>0</default> </entry> <entry name="inactiveStateEnabled" type="Bool"> <default>false</default> <label>draw buttons in inactive state when is needed</label> </entry> <entry name="useDecorationMetrics" type="Bool"> <default>true</default> <label>use the discovered decoration metrics in case there are any in order to look consistent with window titlebars</label> </entry> <entry name="buttonSizePercentage" type="Int"> <default>100</default> <label>the buttons size relevant to panel thickness</label> </entry> <entry name="lengthFirstMargin" type="Int"> <default>0</default> <label>first margin used to increase or decrease the icons distance from surrounding applets</label> </entry> <entry name="lengthLastMargin" type="Int"> <default>0</default> <label>last margin used to increase or decrease the icons distance from surrounding applets</label> </entry> <entry name="lengthMarginsLock" type="Bool"> <default>true</default> <label>used only by the settings window in order to remember the user choice concerning the locker</label> </entry> <entry name="spacing" type="Int"> <default>4</default> <label>spacing between icons</label> </entry> <entry name="formFactor" type="Int"> <default>2</default> <label>it is used in order to inform settings window about the plasmoid form factor. 2=Horizontal and 3=Vertical</label> </entry> <entry name="containmentType" type="Enum"> <choices> <choice name="Loading" /> <choice name="Plasma" /> <choice name="Latte" /> </choices> <label>it helps to enable/disable options that are specific to plasma or Latte panels</label> <default>0</default> </entry> </group> </kcfg> 07070100000039000041ED00000000000000000000000365EE4A9F00000000000000000000000000000000000000000000003E00000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui0707010000003A000081A400000000000000000000000165EE4A9F00000CA5000000000000000000000000000000000000005600000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/LatteWindowsTracker.qml/* * Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-title * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQuick Item { id: latteWindowsTracker property bool filterByScreen: true readonly property bool existsWindowActive: selectedTracker.lastActiveWindow.isValid && !lastActiveTaskItem.isMinimized && lastActiveTaskItem.isActive readonly property bool existsWindowShown: selectedTracker.lastActiveWindow.isValid && !lastActiveTaskItem.isMinimized readonly property QtObject selectedTracker: filterByScreen ? latteBridge.windowsTracker.currentScreen : latteBridge.windowsTracker.allScreens readonly property Item lastActiveTaskItem: Item { readonly property string title: selectedTracker.lastActiveWindow.display readonly property bool isMinimized: selectedTracker.lastActiveWindow.isMinimized readonly property bool isMaximized: selectedTracker.lastActiveWindow.isMaximized readonly property bool isActive: selectedTracker.lastActiveWindow.isActive readonly property bool isOnAllDesktops: selectedTracker.lastActiveWindow.isOnAllDesktops readonly property bool isKeepAbove: selectedTracker.lastActiveWindow.isKeepAbove readonly property bool isClosable: selectedTracker.lastActiveWindow.hasOwnProperty("isClosable") ? selectedTracker.lastActiveWindow.isClosable : true readonly property bool isMinimizable: selectedTracker.lastActiveWindow.hasOwnProperty("isMinimizable") ? selectedTracker.lastActiveWindow.isMinimizable : true readonly property bool isMaximizable: selectedTracker.lastActiveWindow.hasOwnProperty("isMaximizable") ? selectedTracker.lastActiveWindow.isMaximizable : true readonly property bool isVirtualDesktopsChangeable: selectedTracker.lastActiveWindow.hasOwnProperty("isVirtualDesktopsChangeable") ? selectedTracker.lastActiveWindow.isVirtualDesktopsChangeable : true readonly property int winId: selectedTracker.lastActiveWindow.hasOwnProperty("winId") ? selectedTracker.lastActiveWindow.winId : -1 } function toggleMaximized() { selectedTracker.lastActiveWindow.requestToggleMaximized(); } function toggleMinimized() { selectedTracker.lastActiveWindow.requestToggleMinimized(); } function toggleClose() { selectedTracker.lastActiveWindow.requestClose(); } function togglePinToAllDesktops() { selectedTracker.lastActiveWindow.requestToggleIsOnAllDesktops(); } function toggleKeepAbove() { selectedTracker.lastActiveWindow.requestToggleKeepAbove(); } } 0707010000003B000081A400000000000000000000000165EE4A9F0000130F000000000000000000000000000000000000005300000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/PlasmaTasksModel.qml/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-buttons * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQml.Models 2.2 import QtQuick 2.7 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.plasmoid 2.0 import org.kde.taskmanager 0.1 as TaskManager Item { id: plasmaTasksItem property bool filterByScreen: true readonly property bool existsWindowActive: lastActiveTaskItem && tasksRepeater.count > 0 && (root.perScreenActive || lastActiveTaskItem.isActive) readonly property bool existsWindowShown: lastActiveTaskItem && tasksRepeater.count > 0 && !lastActiveTaskItem.isMinimized property Item lastActiveTaskItem: null function toggleMaximized() { if (lastActiveTaskItem) lastActiveTaskItem.toggleMaximized(); } function toggleMinimized() { if (lastActiveTaskItem) lastActiveTaskItem.toggleMinimized(); } function toggleClose() { if (lastActiveTaskItem) lastActiveTaskItem.toggleClose(); } function togglePinToAllDesktops() { if (lastActiveTaskItem) lastActiveTaskItem.togglePinToAllDesktops(); } function toggleKeepAbove() { if (lastActiveTaskItem) lastActiveTaskItem.toggleKeepAbove(); } // To get current activity name TaskManager.ActivityInfo { id: activityInfo } // To get virtual desktop name TaskManager.VirtualDesktopInfo { id: virtualDesktopInfo } TaskManager.TasksModel { id: tasksModel sortMode: TaskManager.TasksModel.SortVirtualDesktop groupMode: TaskManager.TasksModel.GroupDisabled screenGeometry: root.screenGeometry activity: activityInfo.currentActivity virtualDesktop: virtualDesktopInfo.currentDesktop filterByScreen: plasmaTasksItem.filterByScreen filterByVirtualDesktop: true filterByActivity: true } Repeater { id: tasksRepeater model: DelegateModel { model: tasksModel delegate: Item { id: task readonly property string title: display readonly property bool isMinimized: IsMinimized === true ? true : false readonly property bool isMaximized: IsMaximized === true ? true : false readonly property bool isActive: IsActive === true ? true : false readonly property bool isOnAllDesktops: IsOnAllVirtualDesktops === true ? true : false readonly property bool isKeepAbove: IsKeepAbove === true ? true : false readonly property bool isClosable: IsClosable === true ? true : false readonly property bool isMinimizable: IsMinimizable === true ? true : false readonly property bool isMaximizable: IsMaximizable === true ? true : false readonly property bool isVirtualDesktopsChangeable: IsVirtualDesktopsChangeable === true ? true : false function modelIndex() { return tasksModel.makeModelIndex(index); } function toggleMaximized() { tasksModel.requestToggleMaximized(modelIndex()); } function toggleMinimized() { tasksModel.requestToggleMinimized(modelIndex()); } function toggleClose() { tasksModel.requestClose(modelIndex()); } function togglePinToAllDesktops() { tasksModel.requestVirtualDesktops(modelIndex(), isOnAllDesktops ? [virtualDesktopInfo.currentDesktop] : []); } function toggleKeepAbove() { tasksModel.requestToggleKeepAbove(modelIndex()); } onIsActiveChanged: { if (isActive) plasmaTasksItem.lastActiveTaskItem = task; } Component.onDestruction: { if (plasmaTasksItem.lastActiveTaskItem === task) plasmaTasksItem.lastActiveTaskItem = null; } } } } } 0707010000003C000041ED00000000000000000000000265EE4A9F00000000000000000000000000000000000000000000004500000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/config0707010000003D000081A400000000000000000000000165EE4A9F00000C2F000000000000000000000000000000000000005800000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/config/ColorsComboBox.qml/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-buttons * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQuick import QtQuick.Controls import QtQuick.Layouts ComboBox { id: combobox Connections { function onClosed() { root.forceActiveFocus(); } target: popup } delegate: MouseArea { width: combobox.width height: combobox.height hoverEnabled: true onClicked: { combobox.currentIndex = index; selectedScheme = model.file; combobox.popup.close(); } Rectangle { id: delegateBackground readonly property color selectedColor: Qt.rgba(palette.highlight.r, palette.highlight.g, palette.highlight.b, 0.5) anchors.fill: parent color: { if (containsMouse) return palette.highlight; if (combobox.currentIndex === index) return selectedColor; return "transparent"; } RowLayout { id: delegateRow height: parent.height Item { Layout.leftMargin: 2 width: 1.25 * label.height height: label.height opacity: ((file == "kdeglobals") || (file == "_plasmatheme_")) ? 0 : 1 Rectangle { width: height height: 0.75 * label.height color: backgroundColor border.width: 1 border.color: containsMouse || (combobox.currentIndex === index) ? palette.highlightedText : palette.text Rectangle { anchors.horizontalCenter: parent.right anchors.verticalCenter: parent.bottom width: parent.width height: parent.height color: textColor border.width: parent.border.width border.color: parent.border.color } } } Label { id: label text: display color: containsMouse ? palette.highlightedText : palette.text } } } } } 0707010000003E000081A400000000000000000000000165EE4A9F00004214000000000000000000000000000000000000005700000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/config/ConfigGeneral.qml/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-buttons * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQuick import QtQuick.Controls import QtQuick.Layouts import org.kde.appletdecoration as AppletDecoration import org.kde.kirigami as Kirigami import org.kde.kitemmodels import org.kde.plasma.components as PlasmaComponents import org.kde.plasma.core as PlasmaCore Item { ///END Decoration Items id: root property alias cfg_useCurrentDecoration: root.useCurrent property alias cfg_selectedPlugin: root.selectedPlugin property alias cfg_selectedScheme: root.selectedScheme property alias cfg_selectedTheme: root.selectedTheme property alias cfg_buttons: root.currentButtons property alias cfg_buttonSizePercentage: buttonSizeSpn.value property alias cfg_visibility: root.visibility property alias cfg_filterByScreen: byScreenChk.checked property alias cfg_perScreenActive: stickyChk.checked property alias cfg_hiddenState: root.hiddenState property alias cfg_inactiveStateEnabled: inactiveChk.checked property alias cfg_useDecorationMetrics: decorationMetricsChk.checked property alias cfg_spacing: spacingSpn.value property alias cfg_lengthFirstMargin: lengthFirstSpn.value property alias cfg_lengthLastMargin: lengthLastSpn.value property alias cfg_lengthMarginsLock: lockItem.locked property var cfg_buttonSizePercentageDefault property var cfg_buttonsDefault property var cfg_containmentType property var cfg_containmentTypeDefault property var cfg_filterByScreenDefault property var cfg_perScreenActiveDefault property var cfg_formFactor property var cfg_formFactorDefault property var cfg_hiddenStateDefault property var cfg_inactiveStateEnabledDefault property var cfg_lengthFirstMarginDefault property var cfg_lengthLastMarginDefault property var cfg_lengthMarginsLockDefault property var cfg_selectedPluginDefault property var cfg_selectedSchemeDefault property var cfg_selectedThemeDefault property var cfg_spacingDefault property var cfg_useCurrentDecorationDefault property var cfg_useDecorationMetricsDefault property var cfg_visibilityDefault property var title // used as bridge to communicate properly between configuration and ui property bool useCurrent property int hiddenState property int visibility property string selectedPlugin property string selectedScheme property string selectedTheme property string currentButtons // used from the ui readonly property bool selectedDecorationExists: decorations.decorationExists(root.selectedPlugin, root.selectedTheme) readonly property real centerFactor: 0.3 readonly property int minimumWidth: 220 property string currentPlugin: root.useCurrent || !selectedDecorationExists ? decorations.currentPlugin : root.selectedPlugin property string currentTheme: root.useCurrent || !selectedDecorationExists ? decorations.currentTheme : root.selectedTheme ///START Decoration Items AppletDecoration.Bridge { id: bridgeItem plugin: currentPlugin theme: currentTheme } AppletDecoration.Settings { id: settingsItem bridge: bridgeItem.bridge borderSizesIndex: 0 } AppletDecoration.SharedDecoration { id: sharedDecorationItem bridge: bridgeItem.bridge settings: settingsItem } AppletDecoration.AuroraeTheme { id: auroraeThemeEngine readonly property bool isEnabled: decorations.isAurorae(root.currentPlugin, root.currentTheme) theme: isEnabled ? currentTheme : "" } AppletDecoration.DecorationsModel { id: decorations } AppletDecoration.ColorsModel { id: colorsModel } AppletDecoration.PlasmaThemeExtended { id: plasmaThemeExtended readonly property bool isActive: selectedScheme === "_plasmatheme_" } SystemPalette { id: palette } // sort decorations based on display name KSortFilterProxyModel { id: sortedDecorations sourceModel: decorations sortRoleName: 'display' sortOrder: Qt.AscendingOrder } ColumnLayout { id: mainColumn spacing: Kirigami.Units.largeSpacing Layout.fillWidth: true RowLayout { Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: i18n("Decoration:") horizontalAlignment: Text.AlignRight } DecorationsComboBox { id: decorationCmb Layout.minimumWidth: 180 Layout.preferredWidth: 0.2 * root.width Layout.maximumWidth: 300 } } RowLayout { visible: !auroraeThemeEngine.isEnabled Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: i18n("Colors:") horizontalAlignment: Text.AlignRight } ColorsComboBox { id: colorsCmbBox Layout.minimumWidth: 250 Layout.preferredWidth: 0.3 * root.width Layout.maximumWidth: 380 model: colorsModel textRole: "display" Component.onCompleted: { currentIndex = colorsModel.indexOf(plasmoid.configuration.selectedScheme); } } } GridLayout { columns: 2 Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: i18n("Buttons:") horizontalAlignment: Text.AlignRight } OrderableListView { id: activeButtons readonly property color schemesBackgroundColor: plasmaThemeExtended.isActive ? plasmaThemeExtended.colors.backgroundColor : colorsModel.backgroundOf(colorsCmbBox.currentIndex) itemWidth: 38 itemHeight: 38 buttonsStr: root.currentButtons orientation: ListView.Horizontal color: !auroraeThemeEngine.isEnabled ? schemesBackgroundColor : auroraeThemeEngine.titleBackgroundColor buttonSize: buttonSizeSpn.value buttonsFirstMargin: lengthFirstSpn.value buttonsLastMargin: lengthLastSpn.value buttonsSpacing: spacingSpn.value } } GridLayout { columns: 2 rows: 4 flow: GridLayout.TopToBottom Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) Layout.rowSpan: 4 Layout.alignment: Qt.AlignTop | Qt.AlignRight text: i18n("Show:") horizontalAlignment: Text.AlignRight } ButtonGroup { buttons: column.children } Column { id: column RadioButton { id: alwaysVisibleBtn text: i18n("Always visible") checked: root.visibility === AppletDecoration.Types.AlwaysVisible onCheckedChanged: { if (checked) root.visibility = AppletDecoration.Types.AlwaysVisible; } } RadioButton { id: activeWindowBtn text: i18n("Active window is present") checked: root.visibility === AppletDecoration.Types.ActiveWindow onCheckedChanged: { if (checked) root.visibility = AppletDecoration.Types.ActiveWindow; } } RadioButton { id: activeMaximizedBtn text: plasmoid.configuration.containmentType === AppletDecoration.Types.Latte ? i18n("Last active window is maximized") : i18n("Active window is maximized") checked: root.visibility === AppletDecoration.Types.ActiveMaximizedWindow onCheckedChanged: { if (checked) root.visibility = AppletDecoration.Types.ActiveMaximizedWindow; } } RadioButton { id: shownWindowBtn text: i18n("At least one window is shown") checked: root.visibility === AppletDecoration.Types.ShownWindowExists onCheckedChanged: { if (checked) root.visibility = AppletDecoration.Types.ShownWindowExists; } } } } GridLayout { columns: 2 rows: 2 flow: GridLayout.TopToBottom enabled: root.visibility !== AppletDecoration.Types.AlwaysVisible Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) Layout.rowSpan: 2 Layout.alignment: Qt.AlignTop | Qt.AlignRight text: i18n("Hidden State:") horizontalAlignment: Text.AlignRight } ButtonGroup { buttons: column2.children } Column { id: column2 RadioButton { id: slideOutBtn text: i18n("Slide out animation") checked: root.hiddenState === AppletDecoration.Types.SlideOut onCheckedChanged: { if (checked) root.hiddenState = AppletDecoration.Types.SlideOut; } } RadioButton { id: emptySpaceBtn text: i18n("Preserve as empty space") checked: root.hiddenState === AppletDecoration.Types.EmptySpace onCheckedChanged: { if (checked) root.hiddenState = AppletDecoration.Types.EmptySpace; } } } } GridLayout { Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: i18n("Filters:") horizontalAlignment: Text.AlignRight } CheckBox { id: byScreenChk text: i18n("Show only for windows in current screen") } } GridLayout { Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: i18n("Per-screen active window:") horizontalAlignment: Text.AlignRight } CheckBox { id: stickyChk text: i18n("Enabled") } } GridLayout { columns: 2 rows: 2 flow: GridLayout.TopToBottom Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) Layout.alignment: Qt.AlignTop | Qt.AlignRight Layout.rowSpan: 2 text: i18n("Appearance:") horizontalAlignment: Text.AlignRight } CheckBox { id: inactiveChk text: i18n("Draw buttons inactive state when needed") } } ColumnLayout { id: visualSettings GridLayout { id: visualSettingsGroup1 columns: 2 Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: i18n("Metrics:") horizontalAlignment: Text.AlignRight visible: auroraeThemeEngine.isEnabled } CheckBox { id: decorationMetricsChk text: i18n("Use from decoration if any are found") visible: auroraeThemeEngine.isEnabled } Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: i18n("Size:") horizontalAlignment: Text.AlignRight enabled: !(auroraeThemeEngine.isEnabled && decorationMetricsChk.checked) } SpinBox { id: buttonSizeSpn from: 40 to: 100 // suffix: " %" enabled: !(auroraeThemeEngine.isEnabled && decorationMetricsChk.checked) } Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: i18n("Spacing:") horizontalAlignment: Text.AlignRight enabled: !(auroraeThemeEngine.isEnabled && decorationMetricsChk.checked) } SpinBox { id: spacingSpn from: 0 to: 24 // suffix: " " + i18nc("pixels","px.") enabled: !(auroraeThemeEngine.isEnabled && decorationMetricsChk.checked) } } GridLayout { id: visualSettingsGroup2 property int lockerHeight: firstLengthLbl.height + rowSpacing / 2 columns: 3 rows: 2 flow: GridLayout.TopToBottom columnSpacing: visualSettingsGroup1.columnSpacing rowSpacing: visualSettingsGroup1.rowSpacing Label { id: firstLengthLbl Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: plasmoid.configuration.formFactor === PlasmaCore.Types.Horizontal ? i18n("Left margin:") : i18n("Top margin:") horizontalAlignment: Text.AlignRight } Label { Layout.minimumWidth: Math.max(centerFactor * root.width, minimumWidth) text: plasmoid.configuration.formFactor === PlasmaCore.Types.Horizontal ? i18n("Right margin:") : i18n("Bottom margin:") horizontalAlignment: Text.AlignRight enabled: !lockItem.locked } SpinBox { // suffix: " " + i18nc("pixels","px.") id: lengthFirstSpn property int lastValue: -1 from: 0 to: 24 onValueChanged: { if (lockItem.locked) { var step = value - lastValue > 0 ? 1 : -1; lastValue = value; lengthLastSpn.value = lengthLastSpn.value + step; } } Component.onCompleted: { lastValue = plasmoid.configuration.lengthFirstMargin; } } SpinBox { id: lengthLastSpn from: 0 to: 24 // suffix: " " + i18nc("pixels","px.") enabled: !lockItem.locked } LockItem { id: lockItem Layout.minimumWidth: 40 Layout.maximumWidth: 40 Layout.alignment: Qt.AlignTop | Qt.AlignLeft Layout.minimumHeight: visualSettingsGroup2.lockerHeight Layout.maximumHeight: Layout.minimumHeight Layout.topMargin: firstLengthLbl.height / 2 Layout.rowSpan: 2 } } } } } 0707010000003F000081A400000000000000000000000165EE4A9F00000A85000000000000000000000000000000000000005D00000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/config/DecorationsComboBox.qml/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-buttons * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQuick import QtQuick.Controls import QtQuick.Layouts import org.kde.kirigami as Kirigami ComboBox { id: combobox model: sortedDecorations textRole: "display" valueRole: "plugin" onActivated: { var index = combobox.currentIndex; if (index === -1) return ; console.log(currentTheme, combobox.currentText, combobox.currentValue); root.useCurrent = false; root.selectedPlugin = combobox.currentValue; root.selectedTheme = combobox.currentText; } Component.onCompleted: { combobox.currentIndex = combobox.find(root.currentTheme); } Connections { function onClosed() { root.forceActiveFocus(); } target: popup } delegate: MouseArea { height: combobox.height width: combobox.width hoverEnabled: true onClicked: { combobox.currentIndex = index; root.useCurrent = false; root.selectedPlugin = plugin; root.selectedTheme = theme; combobox.popup.close(); } Rectangle { id: delegateBackground readonly property color selectedColor: Qt.rgba(palette.highlight.r, palette.highlight.g, palette.highlight.b, 0.5) anchors.fill: parent color: { if (containsMouse) return palette.highlight; if (combobox.currentIndex === index) return selectedColor; return "transparent"; } Label { id: label anchors.left: parent.left anchors.leftMargin: Kirigami.Units.smallSpacing anchors.verticalCenter: parent.verticalCenter text: display color: containsMouse ? palette.highlightedText : palette.text } } } } 07070100000040000081A400000000000000000000000165EE4A9F00000ABF000000000000000000000000000000000000005200000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/config/LockItem.qml/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-buttons * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQuick import QtQuick.Controls import QtQuick.Layouts import org.kde.kirigami as Kirigami Item { id: main property bool locked: true readonly property int verticalSubHeight: height - (button.height / 2) SystemPalette { id: palette } ColumnLayout { id: column spacing: 0 opacity: locked ? 1 : 0.5 Rectangle { id: subRectTop Layout.minimumWidth: button.width / 2 + Layout.minimumHeight / 2 Layout.minimumHeight: 3 Layout.maximumWidth: Layout.minimumWidth Layout.maximumHeight: Layout.minimumHeight color: palette.text } Rectangle { Layout.leftMargin: subRectTop.Layout.minimumWidth - subRectTop.Layout.minimumHeight Layout.minimumWidth: subRectTop.Layout.minimumHeight Layout.minimumHeight: verticalSubHeight Layout.maximumWidth: Layout.minimumWidth Layout.maximumHeight: Layout.minimumHeight color: palette.text } Kirigami.Icon { id: button width: 24 height: 24 source: locked ? "lock" : "unlock" } Rectangle { Layout.leftMargin: subRectTop.Layout.minimumWidth - subRectTop.Layout.minimumHeight Layout.minimumWidth: subRectTop.Layout.minimumHeight Layout.minimumHeight: verticalSubHeight Layout.maximumWidth: Layout.minimumWidth Layout.maximumHeight: Layout.minimumHeight color: palette.text } Rectangle { Layout.minimumWidth: subRectTop.Layout.minimumWidth Layout.minimumHeight: subRectTop.Layout.minimumHeight Layout.maximumWidth: Layout.minimumWidth Layout.maximumHeight: Layout.minimumHeight color: palette.text } } MouseArea { anchors.fill: column onClicked: locked = !locked } } 07070100000041000081A400000000000000000000000165EE4A9F00003701000000000000000000000000000000000000005B00000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/config/OrderableListView.qmlimport "../../code/tools.js" as ModelTools /* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-buttons * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import QtQuick import QtQuick.Controls import QtQuick.Layouts import org.kde.appletdecoration 0.1 as AppletDecoration import org.kde.plasma.core 2.0 as PlasmaCore Rectangle { /*Rectangle{ anchors.fill: parent color: "transparent" border.color: "red" border.width: 1 }*/ id: listContent property int orientation property double itemWidth property double itemHeight property int buttonSize: 100 property int buttonsFirstMargin: 0 property int buttonsLastMargin: 0 property int buttonsSpacing: 0 property string buttonsStr property var tasksPreparedArray: [] readonly property int margin: 0 readonly property double iconHeight: itemHeight * (buttonSize / 100) - margin * 2 readonly property string appliedScheme: { if (selectedScheme === "_plasmatheme_") return plasmaThemeExtended.colors.schemeFile; else if (selectedScheme === "kdeglobals") return colorsModel.defaultSchemeFile(); return selectedScheme; } signal coordinatesChanged() signal modelOrderChanged() function initButtons() { if (!buttonsRecreator.running) buttonsRecreator.start(); } function initializeControlButtonsModel() { sharedDecorationItem.createDecoration(); var buttonsList = buttonsStr.split('|'); ModelTools.initializeControlButtonsModel(buttonsList, tasksPreparedArray, controlButtonsModel, false); listView.splitterIndex = ModelTools.indexOfSplitter(controlButtonsModel); coordinatesTimer.start(); } function buttonsListStr() { var str = ""; for (var i = 0; i < controlButtonsModel.count; ++i) { str = str + String(controlButtonsModel.get(i).buttonType); if (i !== controlButtonsModel.count - 1) str = str + "|"; } return str; } function triggerUpdateFromPlasma() { if (plasmaThemeExtended.isActive) listContent.initButtons(); } radius: 4 anchors.margins: margin Layout.minimumWidth: width Layout.preferredWidth: Layout.minimumWidth Layout.maximumWidth: Layout.maximumWidth Layout.minimumHeight: height Layout.preferredHeight: Layout.minimumHeight Layout.maximumHeight: Layout.maximumHeight width: listView.childrenRect.width + 2 * margin //(itemWidth+listView.spacing) * (orientation == ListView.Vertical ? 1 : controlButtonsModel.count) + 2 * margin height: listView.childrenRect.height + 2 * margin //(itemHeight+listView.spacing) * (orientation == ListView.Horizontal ? 1 : controlButtonsModel.count) Component.onCompleted: { initButtons(); coordinatesChanged(); } Connections { function onCurrentPluginChanged() { listContent.initButtons(); } target: root } Connections { function onThemeChanged() { triggerUpdateFromPlasma(); } target: plasmaThemeExtended } ListModel { id: controlButtonsModel } SystemPalette { id: palette } ListView { id: listView property int splitterIndex: -1 width: childrenRect.width height: itemHeight model: controlButtonsModel orientation: listContent.orientation delegate: auroraeThemeEngine.isEnabled ? auroraeButtonComponent : pluginButtonComponent currentIndex: loc.initIndex onWidthChanged: coordinatesTimer.start() moveDisplaced: Transition { NumberAnimation { properties: "x" duration: 150 easing.type: Easing.Linear } } move: Transition { NumberAnimation { properties: "x" duration: 75 easing.type: Easing.Linear } } } MouseArea { id: loc property int initButton: -1 // Original button in model property int initIndex: -1 // Original position in model property int index: listView.indexAt(mouseX, mouseY) // Item underneath cursor readonly property bool buttonIsDragged: initButton !== -1 || initIndex !== -1 anchors.fill: parent pressAndHoldInterval: 200 cursorShape: Qt.DragMoveCursor onPressAndHold: { initIndex = listView.indexAt(mouseX, mouseY); initButton = controlButtonsModel.get(initIndex).buttonType; } onReleased: { initIndex = -1; initButton = -1; } onPositionChanged: { if (containsPress && initIndex !== -1 && index !== -1 && index !== initIndex) { controlButtonsModel.move(initIndex, index, 1); initIndex = index; root.currentButtons = buttonsListStr(); listView.splitterIndex = ModelTools.indexOfSplitter(controlButtonsModel); } } } ///START Components Component { id: pluginButtonComponent Rectangle { id: decorationButton readonly property bool isVisibleButton: index >= 0 && index < listView.splitterIndex readonly property bool isFirstVisibleButton: index === 0 && listView.splitterIndex > 0 readonly property bool isLastVisibleButton: index >= 0 && index === listView.splitterIndex - 1 readonly property bool isButtonSplitter: index >= 0 && index === listView.splitterIndex property int leftMargin: 0 property int rightMargin: 0 y: (itemHeight - iconHeight) / 2 width: isButtonSplitter && !loc.buttonIsDragged ? Math.min(listContent.iconHeight / 2, 6 + buttonsLastMargin) : listContent.iconHeight + leftMargin + rightMargin height: listContent.iconHeight + 2 * listContent.margin color: { if (listView.currentIndex === index) { if (index !== listView.splitterIndex) return palette.highlight; else return "#25ff0000"; } return "transparent"; } Binding { target: decorationButton property: "leftMargin" value: { if (loc.buttonIsDragged) return buttonsSpacing / 2; if (isFirstVisibleButton) return buttonsFirstMargin; else if (isVisibleButton) return buttonsSpacing; return listContent.margin; } } Binding { target: decorationButton property: "rightMargin" value: { if (loc.buttonIsDragged) return buttonsSpacing / 2; if (isLastVisibleButton) return buttonsLastMargin; return listContent.margin; } } AppletDecoration.Button { id: cButton function updateCoordinates() { var translated = cButton.mapToItem(listView, 0, 0); cButton.localX = translated.x; cButton.localY = translated.y; } anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: parent.leftMargin opacity: listView.splitterIndex !== -1 && listView.splitterIndex < index ? 0.4 : 1 width: isButtonSplitter ? parent.width : listContent.iconHeight height: isButtonSplitter ? parent.height : listContent.iconHeight bridge: bridgeItem.bridge sharedDecoration: sharedDecorationItem type: buttonType isOnAllDesktops: false isMaximized: false scheme: appliedScheme visible: buttonType !== AppletDecoration.Types.Custom Connections { function onCoordinatesChanged() { cButton.updateCoordinates(); } target: listContent } } Rectangle { height: parent.height - listContent.margin width: 4 border.width: 1 anchors.left: parent.left color: palette.highlight border.color: palette.highlight visible: buttonType === AppletDecoration.Types.Custom opacity: 0.75 } Behavior on leftMargin { NumberAnimation { duration: 50 easing.type: Easing.Linear } } Behavior on rightMargin { NumberAnimation { duration: 50 easing.type: Easing.Linear } } } } Component { id: auroraeButtonComponent Rectangle { id: auroraeButton readonly property bool isVisibleButton: index >= 0 && index < listView.splitterIndex readonly property bool isFirstVisibleButton: index === 0 && listView.splitterIndex > 0 readonly property bool isLastVisibleButton: index >= 0 && index === listView.splitterIndex - 1 readonly property bool isButtonSplitter: index >= 0 && index === listView.splitterIndex property int leftMargin: 0 property int rightMargin: 0 y: (itemHeight - iconHeight) / 2 width: isButtonSplitter && !loc.buttonIsDragged ? Math.min(listContent.iconHeight / 2, 6 + buttonsLastMargin) : auroraeThemeEngine.buttonRatio * listContent.iconHeight + leftMargin + rightMargin height: listContent.iconHeight + 2 * listContent.margin color: { if (listView.currentIndex === index) { if (index !== listView.splitterIndex) return palette.highlight; else return "#25ff0000"; } return "transparent"; } Binding { target: auroraeButton property: "leftMargin" value: { if (loc.buttonIsDragged) return buttonsSpacing / 2; if (isFirstVisibleButton) return buttonsFirstMargin; else if (isVisibleButton) return buttonsSpacing; return listContent.margin; } } Binding { target: auroraeButton property: "rightMargin" value: { if (loc.buttonIsDragged) return buttonsSpacing / 2; if (isLastVisibleButton) return buttonsLastMargin; return listContent.margin; } } AppletDecoration.AuroraeButton { anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter anchors.leftMargin: parent.leftMargin opacity: listView.splitterIndex !== -1 && listView.splitterIndex < index ? 0.4 : 1 width: auroraeThemeEngine.buttonRatio * height height: listContent.iconHeight isOnAllDesktops: false isMaximized: false buttonType: model.buttonType auroraeTheme: auroraeThemeEngine visible: buttonType !== AppletDecoration.Types.Custom } Rectangle { anchors.left: parent.left height: parent.height width: 4 border.width: 1 color: palette.highlight border.color: palette.highlight visible: buttonType === AppletDecoration.Types.Custom opacity: 0.75 } Behavior on leftMargin { NumberAnimation { duration: 50 easing.type: Easing.Linear } } Behavior on rightMargin { NumberAnimation { duration: 50 easing.type: Easing.Linear } } } } ///END Components //! this timer is used in order to not call too many times the recreation //! of buttons with no reason. Timer { id: buttonsRecreator interval: 200 onTriggered: { initializeControlButtonsModel(); } } //! this timer is used in order to call the relative coordinates updater at the end //! of the buttons moving Timer { id: coordinatesTimer interval: 350 onTriggered: { listContent.coordinatesChanged(); } } } 07070100000042000081A400000000000000000000000165EE4A9F00005CD8000000000000000000000000000000000000004700000000applet-window-buttons6-1710115487.a7b95da/package/contents/ui/main.qml/* * Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com> * * This file is part of applet-window-buttons * * Latte-Dock 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. * * Latte-Dock 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, see <http://www.gnu.org/licenses/>. */ import "../code/tools.js" as ModelTools import QtQuick import QtQuick.Layouts import org.kde.appletdecoration as AppletDecoration import org.kde.plasma.core as PlasmaCore import org.kde.plasma.plasmoid PlasmoidItem { id: root property int animatedMinimumWidth: minimumWidth property int animatedMinimumHeight: minimumHeight property int screen: plasmoid.containment.screen readonly property bool inEditMode: latteInEditMode || plasmoid.userConfiguring || plasmoid.containment.corona.editMode readonly property bool mustHide: { if (visibility === AppletDecoration.Types.AlwaysVisible || inEditMode) return false; if (visibility === AppletDecoration.Types.ActiveWindow && !existsWindowActive) return true; if (visibility === AppletDecoration.Types.ActiveMaximizedWindow && (!isLastActiveWindowMaximized || (inPlasmaPanel && !existsWindowActive))) return true; if (visibility === AppletDecoration.Types.ShownWindowExists && !existsWindowShown) return true; return false; } readonly property bool selectedDecorationExists: decorations.decorationExists(plasmoid.configuration.selectedPlugin, plasmoid.configuration.selectedTheme) readonly property bool slideAnimationEnabled: ((visibility !== AppletDecoration.Types.AlwaysVisible) && (plasmoid.configuration.hiddenState === AppletDecoration.Types.SlideOut)) readonly property bool isEmptySpaceEnabled: plasmoid.configuration.hiddenState === AppletDecoration.Types.EmptySpace readonly property int containmentType: plasmoid.configuration.containmentType readonly property int visibility: plasmoid.configuration.visibility readonly property bool perScreenActive: plasmoid.configuration.perScreenActive readonly property int minimumWidth: { if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) { if (mustHide && !isEmptySpaceEnabled && slideAnimationEnabled && !plasmoid.userConfiguring && !latteInEditMode) return 0; } return plasmoid.formFactor === PlasmaCore.Types.Horizontal ? buttonsArea.width : -1; } readonly property int minimumHeight: { if (plasmoid.formFactor === PlasmaCore.Types.Vertical) { if (mustHide && !isEmptySpaceEnabled && slideAnimationEnabled && !plasmoid.userConfiguring && !latteInEditMode) return 0; } return plasmoid.formFactor === PlasmaCore.Types.Horizontal ? -1 : buttonsArea.height; } readonly property string buttonsStr: plasmoid.configuration.buttons // START visual properties property bool inactiveStateEnabled: inEditMode ? false : plasmoid.configuration.inactiveStateEnabled property int thickPadding: { if (auroraeThemeEngine.isEnabled && plasmoid.configuration.useDecorationMetrics) return plasmoid.formFactor === PlasmaCore.Types.Horizontal ? ((root.height - auroraeThemeEngine.buttonHeight) / 2) - 1 : ((root.width - auroraeThemeEngine.buttonHeight) / 2) - 1; //! Latte padding if (inLatte) { if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) return (root.height - (latteBridge.iconSize * (plasmoid.configuration.buttonSizePercentage / 100))) / 2; else return (root.width - (latteBridge.iconSize * (plasmoid.configuration.buttonSizePercentage / 100))) / 2; } //! Plasma panels code if (plasmoid.formFactor === PlasmaCore.Types.Horizontal) return (root.height - (root.height * (plasmoid.configuration.buttonSizePercentage / 100))) / 2; else return (root.width - (root.width * (plasmoid.configuration.buttonSizePercentage / 100))) / 2; } property int lengthFirstMargin: plasmoid.configuration.lengthFirstMargin property int lengthLastMargin: plasmoid.configuration.lengthLastMargin property int lengthFirstPadding: Math.min(lengthFirstMargin, lengthMidPadding) property int lengthMidPadding: spacing / 2 property int lengthLastPadding: Math.min(lengthLastMargin, lengthMidPadding) property int spacing: { if (auroraeThemeEngine.isEnabled && plasmoid.configuration.useDecorationMetrics) return auroraeThemeEngine.buttonSpacing; return plasmoid.configuration.spacing; } //! make sure that on startup it will always be shown readonly property bool existsWindowActive: (windowInfoLoader.item && windowInfoLoader.item.existsWindowActive) || containmentIdentifierTimer.running readonly property bool existsWindowShown: (windowInfoLoader.item && windowInfoLoader.item.existsWindowShown) || containmentIdentifierTimer.running readonly property bool isLastActiveWindowPinned: lastActiveTaskItem && existsWindowShown && lastActiveTaskItem.isOnAllDesktops readonly property bool isLastActiveWindowMaximized: lastActiveTaskItem && existsWindowShown && lastActiveTaskItem.isMaximized readonly property bool isLastActiveWindowKeepAbove: lastActiveTaskItem && existsWindowShown && lastActiveTaskItem.isKeepAbove readonly property bool isLastActiveWindowClosable: lastActiveTaskItem && existsWindowShown && lastActiveTaskItem.isClosable readonly property bool isLastActiveWindowMaximizable: lastActiveTaskItem && existsWindowShown && lastActiveTaskItem.isMaximizable readonly property bool isLastActiveWindowMinimizable: lastActiveTaskItem && existsWindowShown && lastActiveTaskItem.isMinimizable readonly property bool isLastActiveWindowVirtualDesktopsChangeable: lastActiveTaskItem && existsWindowShown && lastActiveTaskItem.isVirtualDesktopsChangeable property bool hasDesktopsButton: false property bool hasMaximizedButton: false property bool hasKeepAboveButton: false readonly property bool inPlasmaPanel: latteBridge === null readonly property bool inLatte: latteBridge !== null readonly property Item lastActiveTaskItem: windowInfoLoader.item.lastActiveTaskItem // START decoration properties property string currentPlugin: plasmoid.configuration.useCurrentDecoration || !selectedDecorationExists ? decorations.currentPlugin : plasmoid.configuration.selectedPlugin property string currentTheme: plasmoid.configuration.useCurrentDecoration || !selectedDecorationExists ? decorations.currentTheme : plasmoid.configuration.selectedTheme property string currentScheme: { if (plasmaThemeExtended.isActive) return plasmaThemeExtended.colors.schemeFile; if (enforceLattePalette && plasmoid.configuration.selectedScheme === "kdeglobals") return latteBridge.palette.scheme; return plasmoid.configuration.selectedScheme === "kdeglobals" ? colorsModel.defaultSchemeFile() : plasmoid.configuration.selectedScheme; } //BEGIN Latte Dock Communicator property QtObject latteBridge: null //END Latte Dock Communicator //BEGIN Latte based properties //! This applet is a special case and thus the latteBridge.applyPalette is not used. //! the applet relys totally to Latte to paint itself correctly at all cases, //! even when Latte informs the applets that need to use the default plasma theme. readonly property bool enforceLattePalette: latteBridge && latteBridge.palette readonly property bool latteInEditMode: latteBridge && latteBridge.inEditMode property var tasksPreparedArray: [] ///functions function initButtons() { if (!buttonsRecreator.running) buttonsRecreator.start(); } function initializeControlButtonsModel() { console.log("recreating buttons"); sharedDecorationItem.createDecoration(); var buttonsList = buttonsStr.split('|'); ModelTools.initializeControlButtonsModel(buttonsList, tasksPreparedArray, controlButtonsModel, true); } function discoverButtons() { var hasMax = false; var hasPin = false; var hasKeepAbove = false; for (var i = 0; i < tasksPreparedArray.length; ++i) { if (tasksPreparedArray[i].buttonType === AppletDecoration.Types.Maximize) hasMax = true; else if (tasksPreparedArray[i].buttonType === AppletDecoration.Types.OnAllDesktops) hasPin = true; else if (tasksPreparedArray[i].buttonType === AppletDecoration.Types.KeepAbove) hasKeepAbove = true; } hasMaximizedButton = hasMax; hasDesktopsButton = hasPin; hasKeepAboveButton = hasKeepAbove; } function performActiveWindowAction(windowOperation) { if (windowOperation === AppletDecoration.Types.ActionClose) windowInfoLoader.item.toggleClose(); else if (windowOperation === AppletDecoration.Types.ToggleMaximize) windowInfoLoader.item.toggleMaximized(); else if (windowOperation === AppletDecoration.Types.ToggleMinimize) windowInfoLoader.item.toggleMinimized(); else if (windowOperation === AppletDecoration.Types.TogglePinToAllDesktops) windowInfoLoader.item.togglePinToAllDesktops(); else if (windowOperation === AppletDecoration.Types.ToggleKeepAbove) windowInfoLoader.item.toggleKeepAbove(); } clip: true Layout.fillHeight: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? true : false Layout.fillWidth: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? false : true Layout.minimumWidth: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? animatedMinimumWidth : -1 Layout.minimumHeight: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? -1 : animatedMinimumHeight Layout.preferredHeight: Layout.minimumHeight Layout.preferredWidth: Layout.minimumWidth Layout.maximumHeight: Layout.minimumHeight Layout.maximumWidth: Layout.minimumWidth preferredRepresentation: fullRepresentation Plasmoid.onFormFactorChanged: plasmoid.configuration.formFactor = plasmoid.formFactor Plasmoid.status: { if (mustHide && !isEmptySpaceEnabled) { if ((plasmoid.formFactor === PlasmaCore.Types.Horizontal && animatedMinimumWidth === 0) || (plasmoid.formFactor === PlasmaCore.Types.Vertical && animatedMinimumHeight === 0)) return PlasmaCore.Types.HiddenStatus; } return PlasmaCore.Types.ActiveStatus; } onLatteBridgeChanged: { if (latteBridge) { plasmoid.configuration.containmentType = AppletDecoration.Types.Latte; latteBridge.actions.setProperty(plasmoid.id, "latteSideColoringEnabled", false); latteBridge.actions.setProperty(plasmoid.id, "windowsTrackingEnabled", true); } } onButtonsStrChanged: initButtons() Component.onCompleted: { if (plasmoid.configuration.buttons.indexOf("9") === -1) plasmoid.configuration.buttons = plasmoid.configuration.buttons.concat("|9"); initButtons(); containmentIdentifierTimer.start(); } Connections { target: bridgeItem onPluginChanged: initButtons() } Connections { target: buttonsRepeater onCountChanged: discoverButtons() } ListModel { id: controlButtonsModel } //! Loader { id: windowInfoLoader sourceComponent: latteBridge && latteBridge.windowsTracker && latteBridge.windowsTracker.currentScreen.lastActiveWindow && latteBridge.windowsTracker.allScreens.lastActiveWindow ? latteTrackerComponent : plasmaTasksModel Component { id: latteTrackerComponent LatteWindowsTracker { filterByScreen: plasmoid.configuration.filterByScreen } } Component { id: plasmaTasksModel PlasmaTasksModel { filterByScreen: plasmoid.configuration.filterByScreen } } } ///Decoration Items AppletDecoration.Bridge { id: bridgeItem plugin: currentPlugin theme: currentTheme } AppletDecoration.Settings { id: settingsItem bridge: bridgeItem.bridge borderSizesIndex: 0 // Normal } AppletDecoration.SharedDecoration { id: sharedDecorationItem bridge: bridgeItem.bridge settings: settingsItem } AppletDecoration.DecorationsModel { id: decorations } AppletDecoration.ColorsModel { id: colorsModel } AppletDecoration.PlasmaThemeExtended { id: plasmaThemeExtended readonly property bool isActive: plasmoid.configuration.selectedScheme === "_plasmatheme_" } AppletDecoration.AuroraeTheme { id: auroraeThemeEngine readonly property bool isEnabled: decorations.isAurorae(currentPlugin, currentTheme) theme: isEnabled ? currentTheme : "" } Grid { //when buttons are not sliding out /* Behavior on opacity { enabled: isEmptySpaceEnabled NumberAnimation { duration: 250 easing.type: Easing.InCubic } }*/ id: buttonsArea readonly property int buttonThickness: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? root.height - 2 * thickPadding : root.width - 2 * thickPadding rowSpacing: 0 columnSpacing: 0 rows: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? 1 : 0 columns: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? 0 : 1 opacity: mustHide && !inEditMode && (!root.slideAnimationEnabled || (root.slideAnimationEnabled && plasmoid.status === PlasmaCore.Types.HiddenStatus)) ? 0 : 1 //wait for slide-out animation visible: opacity === 0 ? false : true Repeater { id: buttonsRepeater model: controlButtonsModel delegate: auroraeThemeEngine.isEnabled ? auroraeButton : pluginButton } } Component { id: pluginButton AppletDecoration.Button { /*Rectangle{ anchors.fill: parent color: "transparent" border.width: 1 border.color: "red" } Rectangle{ x: cButton.padding.left y: cButton.padding.top width: cButton.width - cButton.padding.left - cButton.padding.right height: cButton.height - cButton.padding.top - cButton.padding.bottom color: "transparent" border.width: 1 border.color: "blue" }*/ //! first button //! last button id: cButton readonly property bool isVisible: { if (visibility === AppletDecoration.Types.AlwaysVisible || inEditMode) return true; if (type === AppletDecoration.Types.Close) return root.isLastActiveWindowClosable; else if (type === AppletDecoration.Types.Maximize) return root.isLastActiveWindowMaximizable; else if (type === AppletDecoration.Types.Minimize) return root.isLastActiveWindowMinimizable; else if (type === AppletDecoration.Types.OnAllDesktops) return root.isLastActiveWindowVirtualDesktopsChangeable; return true; } readonly property int firstPadding: { if (index === 0) return lengthFirstMargin; else return lengthMidPadding; } readonly property int lastPadding: { if (index >= 0 && index === buttonsRepeater.count - 1) return lengthLastMargin; else return lengthMidPadding; } width: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? buttonsArea.buttonThickness + padding.left + padding.right : buttonsArea.buttonThickness + 2 * thickPadding height: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? buttonsArea.buttonThickness + 2 * thickPadding : buttonsArea.buttonThickness + padding.top + padding.bottom bridge: bridgeItem.bridge sharedDecoration: sharedDecorationItem scheme: root.currentScheme type: buttonType isActive: { //! FIXME-TEST PERIOD: Disabled because it shows an error from c++ theme when its value is changed //! and breaks in some cases the buttons coloring through the schemeFile if (root.inactiveStateEnabled && !root.existsWindowActive) return false; return true; } isOnAllDesktops: root.isLastActiveWindowPinned isMaximized: root.isLastActiveWindowMaximized isKeepAbove: root.isLastActiveWindowKeepAbove localX: x localY: y opacity: isVisible ? 1 : 0 visible: (isVisible && !root.isEmptySpaceEnabled) || root.isEmptySpaceEnabled onClicked: { root.performActiveWindowAction(windowOperation); } padding { left: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? firstPadding : thickPadding right: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? lastPadding : thickPadding top: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? thickPadding : firstPadding bottom: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? thickPadding : lastPadding } } } Component { id: auroraeButton AppletDecoration.AuroraeButton { /* Rectangle{ anchors.fill: parent color: "transparent" border.width: 1 border.color: "red" } Rectangle{ x: aButton.leftPadding y: aButton.topPadding width: aButton.width - aButton.leftPadding - aButton.rightPadding height: aButton.height - aButton.topPadding - aButton.bottomPadding color: "transparent" border.width: 1 border.color: "blue" } */ //! first button //! last button id: aButton readonly property int firstPadding: { if (index === 0) return lengthFirstMargin; else return lengthMidPadding; } readonly property int lastPadding: { if (index >= 0 && index === buttonsRepeater.count - 1) return lengthLastMargin; else return lengthMidPadding; } readonly property bool isVisible: { if (visibility === AppletDecoration.Types.AlwaysVisible || inEditMode) return true; if (buttonType === AppletDecoration.Types.Close) return root.isLastActiveWindowClosable; else if (buttonType === AppletDecoration.Types.Maximize) return root.isLastActiveWindowMaximizable; else if (buttonType === AppletDecoration.Types.Minimize) return root.isLastActiveWindowMinimizable; else if (buttonType === AppletDecoration.Types.OnAllDesktops) return root.isLastActiveWindowVirtualDesktopsChangeable; return true; } width: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? auroraeTheme.buttonRatio * buttonsArea.buttonThickness + leftPadding + rightPadding : buttonsArea.buttonThickness + 2 * thickPadding height: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? buttonsArea.buttonThickness + 2 * thickPadding : buttonsArea.buttonThickness + topPadding + bottomPadding leftPadding: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? firstPadding : thickPadding rightPadding: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? lastPadding : thickPadding topPadding: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? thickPadding : firstPadding bottomPadding: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? thickPadding : lastPadding isActive: { //! FIXME-TEST PERIOD: Disabled because it shows an error from c++ theme when its value is changed //! and breaks in some cases the buttons coloring through the schemeFile if (root.inactiveStateEnabled && !root.existsWindowActive) return false; return true; } isOnAllDesktops: root.isLastActiveWindowPinned isMaximized: root.isLastActiveWindowMaximized isKeepAbove: root.isLastActiveWindowKeepAbove buttonType: model.buttonType auroraeTheme: auroraeThemeEngine monochromeIconsEnabled: latteBridge && latteBridge.applyPalette && auroraeThemeEngine.hasMonochromeIcons monochromeIconsColor: latteBridge ? latteBridge.palette.textColor : "transparent" opacity: isVisible ? 1 : 0 visible: (isVisible && !root.isEmptySpaceEnabled) || root.isEmptySpaceEnabled onClicked: { root.performActiveWindowAction(windowOperation); } } } ///END Visual Items //! this timer is used in order to not call too many times the recreation //! of buttons with no reason. Timer { id: buttonsRecreator interval: 200 onTriggered: initializeControlButtonsModel() } //! this timer is used in order to identify in which containment the applet is in //! it should be called only the first time an applet is created and loaded because //! afterwards the applet has no way to move between different processes such //! as Plasma and Latte Timer { id: containmentIdentifierTimer interval: 5000 onTriggered: { if (latteBridge) plasmoid.configuration.containmentType = AppletDecoration.Types.Latte; else plasmoid.configuration.containmentType = AppletDecoration.Types.Plasma; } } //START Behaviors Behavior on animatedMinimumWidth { enabled: slideAnimationEnabled && plasmoid.formFactor === PlasmaCore.Types.Horizontal NumberAnimation { duration: 250 easing.type: Easing.InCubic } } Behavior on animatedMinimumHeight { enabled: slideAnimationEnabled && plasmoid.formFactor === PlasmaCore.Types.Vertical NumberAnimation { duration: 250 easing.type: Easing.InCubic } } //END Behaviors } 07070100000043000081A400000000000000000000000165EE4A9F00000236000000000000000000000000000000000000004300000000applet-window-buttons6-1710115487.a7b95da/package/metadata.desktop[Desktop Entry] Name=Window Buttons Comment=Window buttons for your panels Encoding=UTF-8 Icon=focus-windows Keywords=window buttons Type=Service X-Plasma-API=declarativeappletscript X-Plasma-MainScript=ui/main.qml X-KDE-PluginInfo-Author=Michail Vourlakos X-KDE-PluginInfo-Category=Windows and Tasks X-KDE-PluginInfo-Email=mvourlakos@gmail.com X-KDE-PluginInfo-License=GPLv2 X-KDE-PluginInfo-Name=org.kde.windowbuttons X-KDE-PluginInfo-Version=0.11.1 X-KDE-PluginInfo-Website=https://github.com/psifidotos/applet-window-buttons X-KDE-ServiceTypes=Plasma/Applet 07070100000044000081A400000000000000000000000165EE4A9F000002D2000000000000000000000000000000000000004000000000applet-window-buttons6-1710115487.a7b95da/package/metadata.json{ "KPackageStructure": "Plasma/Applet", "KPlugin": { "Authors": [ { "Email": "mvourlakos@gmail.com", "Name": "Michail Vourlakos" } ], "Category": "Windows and Tasks", "Description": "Window buttons for your panels", "Icon": "focus-windows", "Id": "org.kde.windowbuttons", "License": "GPLv2", "Name": "Window Buttons", "Version": "0.11.1", "Website": "https://github.com/psifidotos/applet-window-buttons" }, "Keywords": "window buttons", "X-Plasma-API": "declarativeappletscript", "X-Plasma-MainScript": "ui/main.qml", "X-Plasma-API-Minimum-Version": "6.0" } 07070100000045000081A400000000000000000000000165EE4A9F00000141000000000000000000000000000000000000003700000000applet-window-buttons6-1710115487.a7b95da/uninstall.sh#!/bin/bash #Author: Michail Vourlakos #Summary: Uninstallation script #This script was written and tested on openSuSe Leap 42.1 if [ -f build/install_manifest.txt ]; then echo "Uninstallation file exists..." sudo xargs -d '\n' rm < build/install_manifest.txt else echo "Uninstallation file does not exist." fi 07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!639 blocks
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor