diff options
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx')
137 files changed, 12275 insertions, 0 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/LICENSE b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + 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 +state 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 3 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 <https://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program 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, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<https://www.gnu.org/licenses/>. + + The GNU 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. But first, please read +<https://www.gnu.org/licenses/why-not-lgpl.html>. diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/appfolders.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/appfolders.js new file mode 100644 index 0000000..8824777 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/appfolders.js @@ -0,0 +1,265 @@ +import Shell from 'gi://Shell'; +import Clutter from 'gi://Clutter'; +import Cogl from 'gi://Cogl'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import { adjustAnimationTime } from 'resource:///org/gnome/shell/misc/animationUtils.js'; + +import { PaintSignals } from '../conveniences/paint_signals.js'; +// TODO drop Tweener in favour of Clutter's `ease` (will need to extend the blur effect for it) +const Tweener = imports.tweener.tweener; + +// TODO: Drop GNOME 46 backwards compatibility +const transparent = Clutter.Color ? + Clutter.Color.from_pixel(0x00000000) : + new Cogl.Color({ + red: 0, + green: 0, + blue: 0, + alpha: 0 + }); +const FOLDER_DIALOG_ANIMATION_TIME = 200; + +const DIALOGS_STYLES = [ + "appfolder-dialogs-transparent", + "appfolder-dialogs-light", + "appfolder-dialogs-dark" +]; + +let original_zoomAndFadeIn = null; +let original_zoomAndFadeOut = null; +let sigma; +let brightness; + +let _zoomAndFadeIn = function () { + let [sourceX, sourceY] = + this._source.get_transformed_position(); + let [dialogX, dialogY] = + this.child.get_transformed_position(); + + this.child.set({ + translation_x: sourceX - dialogX, + translation_y: sourceY - dialogY, + scale_x: this._source.width / this.child.width, + scale_y: this._source.height / this.child.height, + opacity: 0, + }); + + this.set_background_color(transparent); + + let blur_effect = this.get_effect("appfolder-blur"); + + blur_effect.radius = 0; + blur_effect.brightness = 1.0; + Tweener.addTween(blur_effect, + { + radius: sigma * 2, + brightness: brightness, + time: adjustAnimationTime(FOLDER_DIALOG_ANIMATION_TIME / 1000), + transition: 'easeOutQuad' + } + ); + + this.child.ease({ + translation_x: 0, + translation_y: 0, + scale_x: 1, + scale_y: 1, + opacity: 255, + duration: FOLDER_DIALOG_ANIMATION_TIME, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + }); + + this._needsZoomAndFade = false; + + if (this._sourceMappedId === 0) { + this._sourceMappedId = this._source.connect( + 'notify::mapped', this._zoomAndFadeOut.bind(this)); + } +}; + +let _zoomAndFadeOut = function () { + if (!this._isOpen) + return; + + if (!this._source.mapped) { + this.hide(); + return; + } + + let [sourceX, sourceY] = + this._source.get_transformed_position(); + let [dialogX, dialogY] = + this.child.get_transformed_position(); + + this.set_background_color(transparent); + + let blur_effect = this.get_effect("appfolder-blur"); + Tweener.addTween(blur_effect, + { + radius: 0, + brightness: 1.0, + time: adjustAnimationTime(FOLDER_DIALOG_ANIMATION_TIME / 1000), + transition: 'easeInQuad' + } + ); + + this.child.ease({ + translation_x: sourceX - dialogX, + translation_y: sourceY - dialogY, + scale_x: this._source.width / this.child.width, + scale_y: this._source.height / this.child.height, + opacity: 0, + duration: FOLDER_DIALOG_ANIMATION_TIME, + mode: Clutter.AnimationMode.EASE_OUT_QUAD, + onComplete: () => { + this.child.set({ + translation_x: 0, + translation_y: 0, + scale_x: 1, + scale_y: 1, + opacity: 255, + }); + this.hide(); + + this._popdownCallbacks.forEach(func => func()); + this._popdownCallbacks = []; + }, + }); + + this._needsZoomAndFade = false; +}; + + +export const AppFoldersBlur = class AppFoldersBlur { + // we do not use the effects manager and dummy pipelines here because we + // really want to manage our sigma value ourself during the transition + constructor(connections, settings, _) { + this.connections = connections; + this.paint_signals = new PaintSignals(connections); + this.settings = settings; + } + + enable() { + this._log("blurring appfolders"); + + brightness = this.settings.appfolder.BRIGHTNESS; + sigma = this.settings.appfolder.SIGMA; + + let appDisplay = Main.overview._overview.controls._appDisplay; + + if (appDisplay._folderIcons.length > 0) { + this.blur_appfolders(); + } + + this.connections.connect( + appDisplay, 'view-loaded', _ => this.blur_appfolders() + ); + } + + blur_appfolders() { + let appDisplay = Main.overview._overview.controls._appDisplay; + + if (this.settings.HACKS_LEVEL === 1) + this._log("appfolders hack level 1"); + + appDisplay._folderIcons.forEach(icon => { + icon._ensureFolderDialog(); + + if (original_zoomAndFadeIn == null) { + original_zoomAndFadeIn = icon._dialog._zoomAndFadeIn; + } + if (original_zoomAndFadeOut == null) { + original_zoomAndFadeOut = icon._dialog._zoomAndFadeOut; + } + + let blur_effect = new Shell.BlurEffect({ + name: "appfolder-blur", + radius: sigma * 2, + brightness: brightness, + mode: Shell.BlurMode.BACKGROUND + }); + + icon._dialog.remove_effect_by_name("appfolder-blur"); + icon._dialog.add_effect(blur_effect); + + DIALOGS_STYLES.forEach( + style => icon._dialog._viewBox.remove_style_class_name(style) + ); + + if (this.settings.appfolder.STYLE_DIALOGS > 0) + icon._dialog._viewBox.add_style_class_name( + DIALOGS_STYLES[this.settings.appfolder.STYLE_DIALOGS - 1] + ); + + // finally override the builtin functions + icon._dialog._zoomAndFadeIn = _zoomAndFadeIn; + icon._dialog._zoomAndFadeOut = _zoomAndFadeOut; + + + // HACK + // + //`Shell.BlurEffect` does not repaint when shadows are under it. [1] + // + // This does not entirely fix this bug (shadows caused by windows + // still cause artifacts), but it prevents the shadows of the panel + // buttons to cause artifacts on the panel itself + // + // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 + + if (this.settings.HACKS_LEVEL === 1) { + this.paint_signals.disconnect_all_for_actor(icon._dialog); + this.paint_signals.connect(icon._dialog, blur_effect); + } else { + this.paint_signals.disconnect_all(); + } + }); + }; + + set_sigma(s) { + sigma = s; + if (this.settings.appfolder.BLUR) + this.blur_appfolders(); + } + + set_brightness(b) { + brightness = b; + if (this.settings.appfolder.BLUR) + this.blur_appfolders(); + } + + disable() { + this._log("removing blur from appfolders"); + + let appDisplay = Main.overview._overview.controls._appDisplay; + + if (original_zoomAndFadeIn != null) { + appDisplay._folderIcons.forEach(icon => { + if (icon._dialog) + icon._dialog._zoomAndFadeIn = original_zoomAndFadeIn; + }); + } + + if (original_zoomAndFadeOut != null) { + appDisplay._folderIcons.forEach(icon => { + if (icon._dialog) + icon._dialog._zoomAndFadeOut = original_zoomAndFadeOut; + }); + } + + appDisplay._folderIcons.forEach(icon => { + if (icon._dialog) { + icon._dialog.remove_effect_by_name("appfolder-blur"); + DIALOGS_STYLES.forEach( + s => icon._dialog._viewBox.remove_style_class_name(s) + ); + } + }); + + this.connections.disconnect_all(); + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > appfolders] ${str}`); + } +};
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/applications.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/applications.js new file mode 100644 index 0000000..e783046 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/applications.js @@ -0,0 +1,614 @@ +import Meta from 'gi://Meta'; +import Gio from 'gi://Gio'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import * as Config from 'resource:///org/gnome/shell/misc/config.js'; + +import { ApplicationsService } from '../dbus/services.js'; +import { PaintSignals } from '../conveniences/paint_signals.js'; +import { DummyPipeline } from '../conveniences/dummy_pipeline.js'; +import { Pipeline } from '../conveniences/pipeline.js'; + + +/// Converts a wildcard pattern to a RegExp object. +/// Supports * (matches any sequence) and ? (matches any single character). +/// Matching is case-insensitive. +/// +/// @param {string} pattern - The wildcard pattern (e.g., "Firefox*", "*Code*") +/// @returns {RegExp} The compiled regex pattern +function wildcardToRegex(pattern) { + // Escape special regex characters except * and ? + const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&'); + // Convert wildcards: * -> .*, ? -> . + const regex = '^' + escaped.replace(/\*/g, '.*').replace(/\?/g, '.') + '$'; + return new RegExp(regex, 'i'); +} + + +/// Compiles an array of wildcard patterns into RegExp objects. +/// Caches the results to avoid recompilation on every check. +/// +/// @param {string[]} patterns - Array of wildcard patterns +/// @param {Map} cache - Cache map storing pattern -> regex mappings +/// @returns {RegExp[]} Array of compiled regex patterns +function compilePatterns(patterns, cache) { + return patterns.map(pattern => { + if (cache.has(pattern)) { + return cache.get(pattern); + } + const regex = wildcardToRegex(pattern); + cache.set(pattern, regex); + return regex; + }); +} + + +/// Tests if a value matches any of the compiled patterns. +/// +/// @param {string} value - The value to test (e.g., wm_class) +/// @param {RegExp[]} patterns - Array of compiled regex patterns +/// @returns {boolean} True if value matches any pattern +function matchesAnyPattern(value, patterns) { + if (!value || patterns.length === 0) { + return false; + } + return patterns.some(pattern => pattern.test(value)); +} + +export const ApplicationsBlur = class ApplicationsBlur { + constructor(connections, settings, effects_manager) { + this.connections = connections; + this.settings = settings; + this.effects_manager = effects_manager; + this.paint_signals = new PaintSignals(connections); + + // stores every blurred meta window + this.meta_window_map = new Map(); + + // cache for compiled patterns to avoid recompilation + this._whitelist_pattern_cache = new Map(); + this._blacklist_pattern_cache = new Map(); + this._compiled_whitelist = []; + this._compiled_blacklist = []; + + // compile initial patterns + this._update_patterns(); + } + + /// Updates the compiled whitelist and blacklist patterns from settings. + /// Called during initialization and when whitelist/blacklist settings change. + _update_patterns() { + const whitelist = this.settings.applications.WHITELIST || []; + const blacklist = this.settings.applications.BLACKLIST || []; + + this._compiled_whitelist = compilePatterns(whitelist, this._whitelist_pattern_cache); + this._compiled_blacklist = compilePatterns(blacklist, this._blacklist_pattern_cache); + + this._log(`Patterns updated - whitelist: ${whitelist.length}, blacklist: ${blacklist.length}`); + } + + enable() { + this._log("blurring applications..."); + + // export dbus service for preferences + this.service = new ApplicationsService; + this.service.export(); + + this.mutter_gsettings = new Gio.Settings({ schema: 'org.gnome.mutter' }); + + // blur already existing windows + this.update_all_windows(); + + // blur every new window + this.connections.connect( + global.display, + 'window-created', + (_meta_display, meta_window) => { + this._log("window created"); + + if (meta_window) + this.track_new(meta_window); + } + ); + + // update window blur when focus is changed + this.focused_window_pid = null; + this.init_dynamic_opacity(); + this.connections.connect( + global.display, + 'focus-window', + (_meta_display, meta_window, _p0) => { + if (meta_window && meta_window.bms_pid != this.focused_window_pid) + this.set_focus_for_window(meta_window); + else if (!meta_window) + this.set_focus_for_window(null); + } + ); + + this.connect_to_overview(); + } + + /// Initializes the dynamic opacity for windows, without touching to the connections. + /// This is used both when enabling the component, and when changing the dynamic-opacity pref. + init_dynamic_opacity() { + if (this.settings.applications.DYNAMIC_OPACITY) { + // make the currently focused window solid + if (global.display.focus_window) + this.set_focus_for_window(global.display.focus_window); + } else { + // remove old focused window if the pref was changed + if (this.focused_window_pid) + this.set_focus_for_window(null); + } + } + + /// Connect to the overview being opened/closed to force the blur being + /// shown on every window of the workspaces viewer. + connect_to_overview() { + this.connections.disconnect_all_for(Main.overview); + + if (this.settings.applications.BLUR_ON_OVERVIEW) { + // when the overview is opened, show every window actors (which + // allows the blur to be shown too) + this.connections.connect( + Main.overview, 'showing', + _ => this.meta_window_map.forEach((meta_window, _pid) => { + let window_actor = meta_window.get_compositor_private(); + window_actor?.show(); + }) + ); + + // when the overview is closed, hide every actor that is not on the + // current workspace (to mimic the original behaviour) + this.connections.connect( + Main.overview, 'hidden', + _ => { + this.meta_window_map.forEach((meta_window, _pid) => { + let window_actor = meta_window.get_compositor_private(); + + if ( + (!meta_window.get_workspace().active) || meta_window.minimized + ) + window_actor.hide(); + }); + } + ); + } + } + + /// Iterate through all existing windows and add blur as needed. + update_all_windows() { + // Recompile patterns in case whitelist/blacklist changed + this._update_patterns(); + + // remove all previously blurred windows, in the case where the + // whitelist was changed + this.meta_window_map.forEach(((_meta_window, pid) => { + this.remove_blur(pid); + })); + + for ( + let i = 0; + i < global.workspace_manager.get_n_workspaces(); + ++i + ) { + let workspace = global.workspace_manager.get_workspace_by_index(i); + let windows = workspace.list_windows(); + + windows.forEach(meta_window => this.track_new(meta_window)); + } + } + + /// Adds the needed signals to every new tracked window, and adds blur if + /// needed. + /// Accepts only untracked meta windows (i.e no `bms_pid` set) + track_new(meta_window) { + // create a pid that will follow the window during its whole life + const pid = ("" + Math.random()).slice(2, 16); + meta_window.bms_pid = pid; + + this._log(`new window tracked, pid: ${pid}`); + + // register the blurred window + this.meta_window_map.set(pid, meta_window); + + // update the blur when wm-class is changed + this.connections.connect( + meta_window, 'notify::wm-class', + _ => this.check_blur(meta_window) + ); + + // update the clip, position, and/or size when the window changes + this.connections.connect( + meta_window, 'size-changed', + _ => this.update_size(pid) + ); + if (this.settings.applications.STATIC_BLUR) { + this.connections.connect( + meta_window, 'position-changed', + _ => this.update_size(pid) + ); + } + + // remove the blur when the window is unmanaged + this.connections.connect( + meta_window, 'unmanaging', + _ => this.untrack_meta_window(pid) + ); + + this.check_blur(meta_window); + + if (this.settings.applications.STATIC_BLUR && meta_window.get_client_type() === Meta.WindowClientType.X11) { + const window_actor = meta_window.get_compositor_private(); + window_actor.connect('child-added', _ => { + if (!meta_window.blur_actor) { + this._warn("can't move blur actor to back, it doesn't exist"); + return; + } + + window_actor.set_child_below_sibling(meta_window.blur_actor, null); + }); + } + } + + /// Updates the size of the blur actor associated to a meta window from its pid. + /// Accepts only tracked meta window (i.e `bms_pid` set), be it blurred or not. + update_size(pid) { + if (this.meta_window_map.has(pid)) { + const meta_window = this.meta_window_map.get(pid); + const blur_actor = meta_window.blur_actor; + if (blur_actor) { + if (this.settings.applications.STATIC_BLUR) { + const bg_manager = meta_window.bg_manager; + const bg_actor_monitor_index = bg_manager.backgroundActor.monitor; + const window_monitor_index = meta_window.get_monitor(); + const monitor = Main.layoutManager.monitors[window_monitor_index]; + + if (bg_actor_monitor_index !== window_monitor_index) { + this._log(`application (pid ${pid}) switching to monitor: ${window_monitor_index}`); + + // Recreate the BackgroundActor on the right monitor. This is necessary to make sure differently + // sized monitors have the correct scaled image of the wallpaper. + bg_manager._monitorIndex = window_monitor_index; + bg_manager._updateBackgroundActor(); + + // Also to fix differently sized monitor issues. + blur_actor.width = monitor.width; + blur_actor.height = monitor.height; + } + + const frame = meta_window.get_frame_rect(); + const buffer = meta_window.get_buffer_rect(); + blur_actor.x = monitor.x - buffer.x; + blur_actor.y = monitor.y - buffer.y; + + // set_clip(x-offset, y-offset, width, height) + blur_actor.set_clip(frame.x - monitor.x, frame.y - monitor.y, frame.width, frame.height); + } else { + const allocation = this.compute_allocation(meta_window); + blur_actor.x = allocation.x; + blur_actor.y = allocation.y; + blur_actor.width = allocation.width; + blur_actor.height = allocation.height; + } + } + } else + // the pid was visibly not removed + this.untrack_meta_window(pid); + } + + /// Checks if the given actor needs to be blurred. + /// Accepts only tracked meta window, be it blurred or not. + /// + /// In order to be blurred, a window either: + /// - is whitelisted in the user preferences if not enable-all + /// - is not blacklisted if enable-all + /// + /// Whitelist and blacklist support wildcard patterns: + /// - * matches any sequence of characters + /// - ? matches any single character + /// - Matching is case-insensitive + check_blur(meta_window) { + const window_wm_class = meta_window.get_wm_class(); + const enable_all = this.settings.applications.ENABLE_ALL; + if (window_wm_class) + this._log(`pid ${meta_window.bms_pid} associated to wm class name ${window_wm_class}`); + + + // if we are in blacklist mode and the window is not blacklisted + // or if we are in whitelist mode and the window is whitelisted + if ( + window_wm_class !== "" + && ((enable_all && !matchesAnyPattern(window_wm_class, this._compiled_blacklist)) + || (!enable_all && matchesAnyPattern(window_wm_class, this._compiled_whitelist)) + ) + && [ + Meta.FrameType.NORMAL, + Meta.FrameType.DIALOG, + Meta.FrameType.MODAL_DIALOG + ].includes(meta_window.get_frame_type()) + ) { + // only blur the window if it is not already done + if (!meta_window.blur_actor) + this.create_blur_effect(meta_window); + } + + // remove blur it is not explicitly whitelisted or un-blacklisted + else if (meta_window.blur_actor) + this.remove_blur(meta_window.bms_pid); + } + + /// Add the blur effect to the window. + /// Accepts only tracked meta window that is NOT already blurred. + create_blur_effect(meta_window) { + const pid = meta_window.bms_pid; + const window_actor = meta_window.get_compositor_private(); + + let blur_actor; + + if (this.settings.applications.STATIC_BLUR) { + const pipeline = new Pipeline(this.effects_manager, global.blur_my_shell._pipelines_manager, this.settings.applications.PIPELINE); + const bg_managers = []; + blur_actor = pipeline.create_background_with_effects( + meta_window.get_monitor(), bg_managers, window_actor, + 'bms-application-blurred-widget' + ); + + if (bg_managers.length > 0) meta_window.bg_manager = bg_managers[0]; + else // I've never seen this happen, but just in case + this._warn(`no bg_manager on blur creation for pid ${pid}`); + } else { + const pipeline = new DummyPipeline(this.effects_manager, this.settings.applications); + [blur_actor, meta_window.bg_manager] = pipeline.create_background_with_effect( + window_actor, 'bms-application-blurred-widget' + ); + + // if hacks are selected, force to repaint the window + if (this.settings.HACKS_LEVEL === 1) { + this._log("hack level 1"); + + this.paint_signals.disconnect_all_for_actor(blur_actor); + this.paint_signals.connect(blur_actor, pipeline.effect); + } else { + this.paint_signals.disconnect_all_for_actor(blur_actor); + } + } + + meta_window.blur_actor = blur_actor; + + // make sure window is blurred in overview + if (this.settings.applications.BLUR_ON_OVERVIEW) + this.enforce_window_visibility_on_overview_for(window_actor); + + // update the size + this.update_size(pid); + + // set the window actor's opacity + this.set_window_opacity(window_actor, this.settings.applications.OPACITY); + + // now set up the signals, for the window actor only: they are disconnected + // in `remove_blur`, whereas the signals for the meta window are disconnected + // only when the whole component is disabled + + // update the window opacity when it changes, else we don't control it fully + this.connections.connect( + window_actor, 'notify::opacity', + _ => { + if (this.focused_window_pid != pid) + this.set_window_opacity(window_actor, this.settings.applications.OPACITY); + } + ); + + // hide the blur if window becomes invisible + if (!window_actor.visible) + blur_actor.hide(); + + this.connections.connect( + window_actor, + 'notify::visible', + window_actor => { + if (window_actor.visible) + meta_window.blur_actor.show(); + else + meta_window.blur_actor.hide(); + } + ); + } + + /// With `focus=true`, tells us we are focused on said window (which can be null if + /// we are not focused anymore). It automatically removes the ancient focus. + /// With `focus=false`, just remove the focus from said window (which can still be null). + set_focus_for_window(meta_window, focus = true) { + let blur_actor = null; + let window_actor = null; + let new_pid = null; + if (meta_window) { + blur_actor = meta_window.blur_actor; + window_actor = meta_window.get_compositor_private(); + new_pid = meta_window.bms_pid; + } + + if (focus) { + // remove old focused window if any + if (this.focused_window_pid) { + const old_focused_window = this.meta_window_map.get(this.focused_window_pid); + if (old_focused_window) + this.set_focus_for_window(old_focused_window, false); + } + // set new focused window pid + this.focused_window_pid = new_pid; + // if we have blur, hide it and make the window opaque + if (this.settings.applications.DYNAMIC_OPACITY && blur_actor) { + blur_actor.hide(); + this.set_window_opacity(window_actor, 255); + } + } + // if we remove the focus and have blur, show it and make the window transparent + else if (blur_actor) { + blur_actor.show(); + this.set_window_opacity(window_actor, this.settings.applications.OPACITY); + } + } + + /// Makes sure that, when the overview is visible, the window actor will + /// stay visible no matter what. + /// We can instead hide the last child of the window actor, which will + /// improve performances without hiding the blur effect. + enforce_window_visibility_on_overview_for(window_actor) { + this.connections.connect(window_actor, 'notify::visible', + _ => { + if (this.settings.applications.BLUR_ON_OVERVIEW) { + if ( + !window_actor.visible + && Main.overview.visible + ) { + window_actor.show(); + window_actor.get_last_child().hide(); + } else if ( + window_actor.visible + ) + window_actor.get_last_child().show(); + } + } + ); + } + + /// Set the opacity of the window actor that sits on top of the blur effect. + set_window_opacity(window_actor, opacity) { + window_actor?.get_children().forEach(child => { + if (child.name !== "blur-actor" && child.opacity != opacity) + child.opacity = opacity; + }); + } + + /// Update the opacity of all window actors. + set_opacity() { + let opacity = this.settings.applications.OPACITY; + + this.meta_window_map.forEach(((meta_window, pid) => { + if (pid != this.focused_window_pid && meta_window.blur_actor) { + let window_actor = meta_window.get_compositor_private(); + this.set_window_opacity(window_actor, opacity); + } + })); + } + + /// Find the system's window scaling. + /// If `scale-monitor-framebuffer` experimental feature if on, we don't need to manage scaling. + /// Else, on wayland, we need to divide by the scale to get the correct result. + compute_scale(meta_window) { + // TODO: Drop GNOME <50 compatibility + const gnome_shell_major_version = parseInt(Config.PACKAGE_VERSION.split('.')[0]); + const scale_monitor_framebuffer = + gnome_shell_major_version >= 50 || + this.mutter_gsettings + .get_strv('experimental-features') + .includes('scale-monitor-framebuffer'); + const is_wayland = gnome_shell_major_version >= 50 || + (typeof Meta.is_wayland_compositor === 'function' + ? Meta.is_wayland_compositor() + : global.display?.is_wayland_compositor?.() ?? true); + const monitor_index = meta_window.get_monitor(); + // check if the window is using wayland, or xwayland/xorg for rendering + return !scale_monitor_framebuffer && is_wayland && meta_window.get_client_type() == 0 + ? Main.layoutManager.monitors[monitor_index].geometry_scale + : 1; + } + + /// Compute the size and position for a blur actor. + /// Coordinates are relative to window buffer's corner. + compute_allocation(meta_window) { + const scale = this.compute_scale(meta_window); + + let frame = meta_window.get_frame_rect(); + let buffer = meta_window.get_buffer_rect(); + + return { + x: (frame.x - buffer.x) / scale, + y: (frame.y - buffer.y) / scale, + width: frame.width / scale, + height: frame.height / scale + }; + } + + change_blur_type() { + this._log("resetting..."); + + this.disable(); + setTimeout(_ => this.enable(), 1); + } + + change_pipeline() { + this.update_all_windows(); + } + + /// Removes the blur actor to make a blurred window become normal again. + /// It however does not untrack the meta window itself. + /// Accepts a pid corresponding (or not) to a blurred (or not) meta window. + remove_blur(pid) { + this._log(`removing blur for pid ${pid}`); + + let meta_window = this.meta_window_map.get(pid); + if (meta_window) { + let window_actor = meta_window.get_compositor_private(); + let blur_actor = meta_window.blur_actor; + let bg_manager = meta_window.bg_manager; + + if (blur_actor && window_actor) { + // reset the opacity + this.set_window_opacity(window_actor, 255); + + // remove the blurred actor + window_actor.remove_child(blur_actor); + bg_manager._bms_pipeline.destroy(); + bg_manager.destroy(); + blur_actor.destroy(); + + // kinda untrack the blurred actor, as its presence is how we know + // whether we are blurred or not + delete meta_window.blur_actor; + delete meta_window.bg_manager; + + // disconnect the signals of the window actor + this.paint_signals.disconnect_all_for_actor(blur_actor); + this.connections.disconnect_all_for(window_actor); + } + } + } + + /// Kinda the same as `remove_blur`, but better: it also untracks the window. + /// This needs to be called when the component is being disabled, else it + /// would cause havoc by having untracked windows during normal operations, + /// which is not the point at all! + /// Accepts a pid corresponding (or not) to a blurred (or not) meta window. + untrack_meta_window(pid) { + this.remove_blur(pid); + let meta_window = this.meta_window_map.get(pid); + if (meta_window) { + this.connections.disconnect_all_for(meta_window); + this.meta_window_map.delete(pid); + } + } + + disable() { + this._log("removing blur from applications..."); + + this.service?.unexport(); + delete this.mutter_gsettings; + + this.meta_window_map.forEach((_meta_window, pid) => { + this.untrack_meta_window(pid); + }); + + this.connections.disconnect_all(); + this.paint_signals.disconnect_all(); + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > applications] ${str}`); + } + + _warn(str) { + console.warn(`[Blur my Shell > applications] ${str}`); + } +}; diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/coverflow_alt_tab.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/coverflow_alt_tab.js new file mode 100644 index 0000000..4e6062a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/coverflow_alt_tab.js @@ -0,0 +1,91 @@ +import * as Main from "resource:///org/gnome/shell/ui/main.js"; + +import { PaintSignals } from "../conveniences/paint_signals.js"; +import { Pipeline } from "../conveniences/pipeline.js"; + +export const CoverflowAltTabBlur = class CoverflowAltTabBlur { + constructor(connections, settings, effects_manager) { + this.connections = connections; + this.settings = settings; + this.paint_signals = new PaintSignals(connections); + this.effects_manager = effects_manager; + this.background_actors = []; + this.background_managers = []; + } + + enable() { + this._log("blurring coverflow alt-tab"); + + this.update_backgrounds(); + + this.connections.connect( + Main.layoutManager.uiGroup, + "child-added", + (_, child) => this.try_blur(child) + ); + + this.connections.connect(Main.layoutManager, "monitors-changed", (_) => { + this.update_backgrounds(); + }); + } + + update_backgrounds() { + this.remove_background_actors(); + + Main.layoutManager.uiGroup + .get_children() + .forEach((child) => this.try_blur(child)); + } + + try_blur(actor) { + if ( + actor.constructor.name !== "Meta_BackgroundGroup" || + actor.get_name() !== "coverflow-alt-tab-background-group" + ) { + return; + } + + this._log("found coverflow alt-tab to blur"); + + for (let i = 0; i < Main.layoutManager.monitors.length; i++) { + const pipeline = new Pipeline( + this.effects_manager, + global.blur_my_shell._pipelines_manager, + this.settings.coverflow_alt_tab.PIPELINE + ); + + const background_actor = pipeline.create_background_with_effects( + i, + this.background_managers, + actor, + "bms-coverflow-alt-tab-blurred-widget" + ); + + this.background_actors.push(background_actor); + } + } + + remove_background_actors() { + this.background_actors.forEach((actor) => actor.destroy()); + this.background_actors = []; + + this.background_managers.forEach((background_manager) => { + background_manager._bms_pipeline.destroy(); + background_manager.destroy(); + }); + this.background_managers = []; + } + + disable() { + this._log("removing blur from coverflow alt-tab"); + + this.remove_background_actors(); + this.connections.disconnect_all(); + } + + _log(str) { + if (this.settings.DEBUG) { + console.log(`[Blur my Shell > coverflow alt-tab] ${str}`); + } + } +}; diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/dash_to_dock.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/dash_to_dock.js new file mode 100644 index 0000000..4ff212c --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/dash_to_dock.js @@ -0,0 +1,421 @@ +import Meta from 'gi://Meta'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import * as Signals from 'resource:///org/gnome/shell/misc/signals.js'; + +import { PaintSignals } from '../conveniences/paint_signals.js'; + +import { Pipeline } from '../conveniences/pipeline.js'; +import { DummyPipeline } from '../conveniences/dummy_pipeline.js'; + +const DASH_STYLES = [ + "transparent-dash", + "light-dash", + "dark-dash" +]; + + +/// This type of object is created for every dash found, and talks to the main +/// DashBlur thanks to signals. +/// +/// This allows to dynamically track the created dashes for each screen. +class DashInfos { + constructor( + dash_blur, dash, dash_container, dash_background, + background, background_group, bg_manager + ) { + // the parent DashBlur object, to communicate + this.dash_blur = dash_blur; + this.dash = dash; + this.dash_container = dash_container; + this.dash_background = dash_background; + this.background = background; + this.background_group = background_group; + this.bg_manager = bg_manager; + this.settings = dash_blur.settings; + this.old_style = this.dash._background.style; + + this.dash_destroy_id = dash.connect('destroy', () => this.remove_dash_blur(false)); + this.dash_blur_connections_ids = []; + this.dash_blur_connections_ids.push( + this.dash_blur.connect('remove-dashes', () => this.remove_dash_blur()), + this.dash_blur.connect('override-style', () => this.override_style()), + this.dash_blur.connect('remove-style', () => this.remove_style()), + this.dash_blur.connect('show', () => this.background_group.show()), + this.dash_blur.connect('hide', () => this.background_group.hide()), + this.dash_blur.connect('update-size', () => this.update_size()), + this.dash_blur.connect('change-blur-type', () => this.change_blur_type()), + this.dash_blur.connect('update-pipeline', () => this.update_pipeline()) + ); + } + + // IMPORTANT: do never call this in a mutable `this.dash_blur.forEach` + remove_dash_blur(dash_not_already_destroyed = true) { + // remove the style and destroy the effects + this.remove_style(); + this.destroy_dash(dash_not_already_destroyed); + + // remove the dash infos from their list + const dash_infos_index = this.dash_blur.dashes.indexOf(this); + if (dash_infos_index >= 0) + this.dash_blur.dashes.splice(dash_infos_index, 1); + + // disconnect everything + this.dash_blur_connections_ids.forEach(id => { if (id) this.dash_blur.disconnect(id); }); + this.dash_blur_connections_ids = []; + if (this.dash_destroy_id) + this.dash.disconnect(this.dash_destroy_id); + this.dash_destroy_id = null; + } + + override_style() { + this.remove_style(); + + this.dash.set_style_class_name( + DASH_STYLES[this.settings.dash_to_dock.STYLE_DASH_TO_DOCK] + ); + } + + remove_style() { + this.dash._background.style = this.old_style; + + DASH_STYLES.forEach( + style => this.dash.remove_style_class_name(style) + ); + } + + destroy_dash(dash_not_already_destroyed = true) { + if (!dash_not_already_destroyed) + this.bg_manager.backgroundActor = null; + + this.paint_signals?.disconnect_all(); + this.dash.get_parent().remove_child(this.background_group); + this.bg_manager._bms_pipeline.destroy(); + this.bg_manager.destroy(); + this.background_group.destroy(); + } + + change_blur_type() { + this.destroy_dash(); + + let [ + background, background_group, bg_manager, paint_signals + ] = this.dash_blur.add_blur(this.dash); + + this.background = background; + this.background_group = background_group; + this.bg_manager = bg_manager; + this.paint_signals = paint_signals; + + this.dash.get_parent().insert_child_at_index(this.background_group, 0); + + this.update_size(); + } + + update_pipeline() { + this.bg_manager._bms_pipeline.change_pipeline_to( + this.settings.dash_to_dock.PIPELINE + ); + } + + update_size() { + if (this.dash_blur.is_static) { + let [x, y] = this.get_dash_position(this.dash_container, this.dash_background); + + this.background.x = -x; + this.background.y = -y; + + if (this.dash_container.get_style_class_name().includes("top")) + this.background.set_clip( + x, + y + this.dash.y + this.dash_background.y, + this.dash_background.width, + this.dash_background.height + ); + else if (this.dash_container.get_style_class_name().includes("bottom")) + this.background.set_clip( + x, + y + this.dash.y + this.dash_background.y, + this.dash_background.width, + this.dash_background.height + ); + else if (this.dash_container.get_style_class_name().includes("left")) + this.background.set_clip( + x + this.dash.x + this.dash_background.x, + y + this.dash.y + this.dash_background.y, + this.dash_background.width, + this.dash_background.height + ); + else if (this.dash_container.get_style_class_name().includes("right")) + this.background.set_clip( + x + this.dash.x + this.dash_background.x, + y + this.dash.y + this.dash_background.y, + this.dash_background.width, + this.dash_background.height + ); + } else { + this.background.width = this.dash_background.width; + this.background.height = this.dash_background.height; + + this.background.x = this.dash_background.x; + this.background.y = this.dash_background.y + this.dash.y; + } + } + + get_dash_position(dash_container, dash_background) { + var x, y; + + let monitor = Main.layoutManager.findMonitorForActor(dash_container); + let dash_box = dash_container._slider.get_child(); + + if (dash_container.get_style_class_name().includes("top")) { + x = (monitor.width - dash_background.width) / 2; + y = dash_box.y; + } else if (dash_container.get_style_class_name().includes("bottom")) { + x = (monitor.width - dash_background.width) / 2; + y = monitor.height - dash_container.height; + } else if (dash_container.get_style_class_name().includes("left")) { + x = dash_box.x; + y = dash_container.y + (dash_container.height - dash_background.height) / 2 - dash_background.y; + } else if (dash_container.get_style_class_name().includes("right")) { + x = monitor.width - dash_container.width; + y = dash_container.y + (dash_container.height - dash_background.height) / 2 - dash_background.y; + } + + return [x, y]; + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > dash] ${str}`); + } + + _warn(str) { + console.warn(`[Blur my Shell > dash] ${str}`); + } +} + +export const DashBlur = class DashBlur extends Signals.EventEmitter { + constructor(connections, settings, _) { + super(); + this.dashes = []; + this.connections = connections; + this.settings = settings; + this.paint_signals = new PaintSignals(connections); + this.is_static = this.settings.dash_to_dock.STATIC_BLUR; + this.enabled = false; + } + + enable() { + this.connections.connect(Main.uiGroup, 'child-added', (_, actor) => { + if ( + (actor.get_name() === "dashtodockContainer") && + (actor.constructor.name === 'DashToDock') + ) + this.try_blur(actor); + }); + + this.blur_existing_dashes(); + this.connect_to_overview(); + + this.update_size(); + + this.enabled = true; + } + + // Finds all existing dashes on every monitor, and call `try_blur` on them + // We cannot only blur `Main.overview.dash`, as there could be several + blur_existing_dashes() { + this._log("searching for dash"); + + // blur every dash found, filtered by name + Main.uiGroup.get_children().filter((child) => { + return (child.get_name() === "dashtodockContainer") && + (child.constructor.name === 'DashToDock'); + }).forEach(dash_container => this.try_blur(dash_container)); + } + + // Tries to blur the dash contained in the given actor + try_blur(dash_container) { + let dash_box = dash_container._slider.get_child(); + + // verify that we did not already blur that dash + if (!dash_box.get_children().some(child => + child.get_name() === "bms-dash-backgroundgroup" + )) { + this._log("dash to dock found, blurring it"); + + // finally blur the dash + let dash = dash_box.get_children().find(child => { + return child.get_name() === 'dash'; + }); + + this.dashes.push(this.blur_dash_from(dash, dash_container)); + } + } + + // Blurs the dash and returns a `DashInfos` containing its information + blur_dash_from(dash, dash_container) { + let [background, background_group, bg_manager, paint_signals] = this.add_blur(dash); + + // insert the background group to the right element + dash.get_parent().insert_child_at_index(background_group, 0); + + // updates size and position on change + this.connections.connect( + dash, + ['notify::width', 'notify::height'], + _ => this.update_size() + ); + this.connections.connect( + dash_container, + ['notify::width', 'notify::height', 'notify::y', 'notify::x'], + _ => this.update_size() + ); + + const dash_background = dash.get_children().find(child => { + return child.get_style_class_name() === 'dash-background'; + }); + + // create infos + let infos = new DashInfos( + this, + dash, + dash_container, + dash_background, + background, + background_group, + bg_manager, + paint_signals + ); + + this.update_size(); + this.update_background(); + + // returns infos + return infos; + } + + add_blur(dash) { + const monitor = Main.layoutManager.findMonitorForActor(dash); + if (!monitor) + return; + + const background_group = new Meta.BackgroundGroup({ + name: 'bms-dash-backgroundgroup', width: 0, height: 0 + }); + + let background, bg_manager, paint_signals; + let static_blur = this.settings.dash_to_dock.STATIC_BLUR; + if (static_blur) { + let bg_manager_list = []; + const pipeline = new Pipeline( + global.blur_my_shell._effects_manager, + global.blur_my_shell._pipelines_manager, + this.settings.dash_to_dock.PIPELINE + ); + background = pipeline.create_background_with_effects( + monitor.index, bg_manager_list, + background_group, 'bms-dash-blurred-widget' + ); + bg_manager = bg_manager_list[0]; + } + else { + const pipeline = new DummyPipeline( + global.blur_my_shell._effects_manager, + this.settings.dash_to_dock + ); + [background, bg_manager] = pipeline.create_background_with_effect( + background_group, 'bms-dash-blurred-widget' + ); + + paint_signals = new PaintSignals(this.connections); + + // HACK + // + //`Shell.BlurEffect` does not repaint when shadows are under it. [1] + // + // This does not entirely fix this bug (shadows caused by windows + // still cause artifacts), but it prevents the shadows of the dash + // buttons to cause artifacts on the dash itself + // + // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 + + if (this.settings.HACKS_LEVEL === 1) { + this._log("hack level 1"); + + paint_signals.disconnect_all(); + paint_signals.connect(background, pipeline.effect); + } else { + paint_signals.disconnect_all(); + } + } + + return [background, background_group, bg_manager, paint_signals]; + } + + change_blur_type() { + this.is_static = this.settings.dash_to_dock.STATIC_BLUR; + this.emit('change-blur-type'); + + this.update_background(); + } + + /// Connect when overview if opened/closed to hide/show the blur accordingly + connect_to_overview() { + this.connections.disconnect_all_for(Main.overview); + + if (this.settings.dash_to_dock.UNBLUR_IN_OVERVIEW) { + this.connections.connect( + Main.overview, 'showing', _ => this.hide() + ); + this.connections.connect( + Main.overview, 'hidden', _ => this.show() + ); + } + }; + + /// Updates the background to either remove it or not, according to the + /// user preferences. + update_background() { + this._log("updating background"); + if (this.settings.dash_to_dock.OVERRIDE_BACKGROUND) + this.emit('override-style'); + else + this.emit('remove-style'); + } + + update_pipeline() { + this.emit('update-pipeline'); + } + + update_size() { + this.emit('update-size'); + } + + show() { + this.emit('show'); + } + hide() { + this.emit('hide'); + } + + disable() { + this._log("removing blur from dashes"); + + this.emit('remove-dashes'); + + this.dashes = []; + this.connections.disconnect_all(); + + this.enabled = false; + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > dash manager] ${str}`); + } + + _warn(str) { + console.warn(`[Blur my Shell > dash manager] ${str}`); + } +};
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/lockscreen.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/lockscreen.js new file mode 100644 index 0000000..7755ba9 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/lockscreen.js @@ -0,0 +1,89 @@ +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import { UnlockDialog } from 'resource:///org/gnome/shell/ui/unlockDialog.js'; + +import { Pipeline } from '../conveniences/pipeline.js'; + +const original_createBackground = + UnlockDialog.prototype._createBackground; +const original_updateBackgroundEffects = + UnlockDialog.prototype._updateBackgroundEffects; +const original_updateBackgrounds = + UnlockDialog.prototype._updateBackgrounds; + + +export const LockscreenBlur = class LockscreenBlur { + constructor(connections, settings, effects_manager) { + this.connections = connections; + this.settings = settings; + this.effects_manager = effects_manager; + this.enabled = false; + } + + enable() { + this._log("blurring lockscreen"); + + this.update_lockscreen(); + + this.enabled = true; + } + + update_lockscreen() { + UnlockDialog.prototype._createBackground = + this._createBackground; + UnlockDialog.prototype._updateBackgroundEffects = + this._updateBackgroundEffects; + UnlockDialog.prototype._updateBackgrounds = + this._updateBackgrounds; + } + + _createBackground(monitor_index) { + let pipeline = new Pipeline( + global.blur_my_shell._effects_manager, global.blur_my_shell._pipelines_manager, + global.blur_my_shell._settings.lockscreen.PIPELINE + ); + + pipeline.create_background_with_effects( + monitor_index, + this._bgManagers, + this._backgroundGroup, + "screen-shield-background" + ); + } + + _updateBackgroundEffects() { + this._updateBackgrounds(); + } + + _updateBackgrounds() { + for (let i = 0; i < this._bgManagers.length; i++) { + this._bgManagers[i]._bms_pipeline.destroy(); + this._bgManagers[i].destroy(); + } + + this._bgManagers = []; + this._backgroundGroup.destroy_all_children(); + + for (let i = 0; i < Main.layoutManager.monitors.length; i++) + this._createBackground(i); + } + + disable() { + this._log("removing blur from lockscreen"); + + UnlockDialog.prototype._createBackground = + original_createBackground; + UnlockDialog.prototype._updateBackgroundEffects = + original_updateBackgroundEffects; + UnlockDialog.prototype._updateBackgrounds = + original_updateBackgrounds; + + this.connections.disconnect_all(); + + this.enabled = false; + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > lockscreen] ${str}`); + } +}; diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/overview.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/overview.js new file mode 100644 index 0000000..50a625e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/overview.js @@ -0,0 +1,226 @@ +import Meta from 'gi://Meta'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; + +import { WorkspaceAnimationController } from 'resource:///org/gnome/shell/ui/workspaceAnimation.js'; +const wac_proto = WorkspaceAnimationController.prototype; + +import { Pipeline } from '../conveniences/pipeline.js'; + +const OVERVIEW_COMPONENTS_STYLE = [ + "overview-components-light", + "overview-components-dark", + "overview-components-transparent" +]; + + +export const OverviewBlur = class OverviewBlur { + constructor(connections, settings, effects_manager) { + this.connections = connections; + this.settings = settings; + this.effects_manager = effects_manager; + this.overview_background_managers = []; + this.overview_background_group = new Meta.BackgroundGroup( + { name: 'bms-overview-backgroundgroup' } + ); + this.animation_background_managers = []; + this.animation_background_group = new Meta.BackgroundGroup( + { name: 'bms-animation-backgroundgroup' } + ); + this.enabled = false; + this.proto_patched = false; + } + + enable() { + this._log("blurring overview"); + + // add css class name for workspace-switch background + Main.uiGroup.add_style_class_name("blurred-overview"); + + // add css class name to make components semi-transparent if wanted + this.update_components_classname(); + + // update backgrounds when the component is enabled + this.update_backgrounds(); + + // connect to monitors change + this.connections.connect(Main.layoutManager, 'monitors-changed', + _ => this.update_backgrounds() + ); + + // part for the workspace animation switch + + // make sure not to do this part if the functions were patched prior, as + // the functions would call themselves and cause infinite recursion + if (!this.proto_patched) { + // store original workspace switching methods for restoring them on + // disable() + this._original_PrepareSwitch = wac_proto._prepareWorkspaceSwitch; + this._original_FinishSwitch = wac_proto._finishWorkspaceSwitch; + + const w_m = global.workspace_manager; + const outer_this = this; + + // create a blurred background actor for each monitor during a + // workspace switch + wac_proto._prepareWorkspaceSwitch = function (...params) { + outer_this._log("prepare workspace switch"); + outer_this._original_PrepareSwitch.apply(this, params); + + // this permits to show the blur behind windows that are on + // workspaces on the left and right + if ( + outer_this.settings.applications.BLUR + ) { + let ws_index = w_m.get_active_workspace_index(); + [ws_index - 1, ws_index + 1].forEach( + i => w_m.get_workspace_by_index(i)?.list_windows().forEach( + window => window.get_compositor_private().show() + ) + ); + } + + Main.uiGroup.insert_child_above( + outer_this.animation_background_group, + global.window_group + ); + + outer_this.animation_background_managers.forEach(bg_manager => { + if (bg_manager._bms_pipeline.actor) + if ( + Meta.prefs_get_workspaces_only_on_primary() && + bg_manager._monitorIndex !== Main.layoutManager.primaryMonitor.index + ) + bg_manager._bms_pipeline.actor.visible = false; + else + bg_manager._bms_pipeline.actor.visible = true; + }); + }; + + // remove the workspace-switch actors when the switch is done + wac_proto._finishWorkspaceSwitch = function (...params) { + outer_this._log("finish workspace switch"); + outer_this._original_FinishSwitch.apply(this, params); + + // this hides windows that are not on the current workspace + if ( + outer_this.settings.applications.BLUR + ) + for (let i = 0; i < w_m.get_n_workspaces(); i++) { + if (i != w_m.get_active_workspace_index()) + w_m.get_workspace_by_index(i)?.list_windows().forEach( + window => window.get_compositor_private().hide() + ); + } + + Main.uiGroup.remove_child(outer_this.animation_background_group); + }; + + this.proto_patched = true; + } + + this.enabled = true; + } + + update_backgrounds() { + // remove every old background + this.remove_background_actors(); + // create new backgrounds for the overview and the animation + for (let i = 0; i < Main.layoutManager.monitors.length; i++) { + const pipeline_overview = new Pipeline( + this.effects_manager, + global.blur_my_shell._pipelines_manager, + this.settings.overview.PIPELINE + ); + pipeline_overview.create_background_with_effects( + i, this.overview_background_managers, + this.overview_background_group, 'bms-overview-blurred-widget' + ); + + const pipeline_animation = new Pipeline( + this.effects_manager, + global.blur_my_shell._pipelines_manager, + this.settings.overview.PIPELINE + ); + pipeline_animation.create_background_with_effects( + i, this.animation_background_managers, + this.animation_background_group, 'bms-animation-blurred-widget' + ); + } + // add the container widget for the overview only to the overview group + Main.layoutManager.overviewGroup.insert_child_at_index(this.overview_background_group, 0); + // make sure it stays below + this.connections.connect(Main.layoutManager.overviewGroup, "child-added", (_, child) => { + if (child !== this.overview_background_group) { + if (this.overview_background_group.get_parent()) + Main.layoutManager.overviewGroup.remove_child(this.overview_background_group); + Main.layoutManager.overviewGroup.insert_child_at_index(this.overview_background_group, 0); + } + }); + } + + /// Updates the classname to style overview components with semi-transparent + /// backgrounds. + update_components_classname() { + OVERVIEW_COMPONENTS_STYLE.forEach( + style => Main.uiGroup.remove_style_class_name(style) + ); + + if (this.settings.overview.STYLE_COMPONENTS > 0) + Main.uiGroup.add_style_class_name( + OVERVIEW_COMPONENTS_STYLE[this.settings.overview.STYLE_COMPONENTS - 1] + ); + } + + remove_background_actors() { + this.overview_background_group.remove_all_children(); + this.animation_background_group.remove_all_children(); + + this.connections.disconnect_all_for(Main.layoutManager.overviewGroup); + if (this.overview_background_group.get_parent()) + Main.layoutManager.overviewGroup.remove_child(this.overview_background_group); + + this.overview_background_managers.forEach(background_manager => { + background_manager._bms_pipeline.destroy(); + background_manager.destroy(); + }); + this.animation_background_managers.forEach(background_manager => { + background_manager._bms_pipeline.destroy(); + background_manager.destroy(); + }); + this.overview_background_managers = []; + this.animation_background_managers = []; + } + + disable() { + this._log("removing blur from overview"); + + this.remove_background_actors(); + Main.uiGroup.remove_style_class_name("blurred-overview"); + OVERVIEW_COMPONENTS_STYLE.forEach( + style => Main.uiGroup.remove_style_class_name(style) + ); + + this.connections.disconnect_all(); + this.enabled = false; + } + + restore_patched_proto() { + if (this.proto_patched) { + if (this._original_PrepareSwitch) + wac_proto._prepareWorkspaceSwitch = this._original_PrepareSwitch; + if (this._original_FinishSwitch) + wac_proto._finishWorkspaceSwitch = this._original_FinishSwitch; + + this.proto_patched = false; + } + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > overview] ${str}`); + } + + _warn(str) { + console.warn(`[Blur my Shell > overview] ${str}`); + } +}; diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/panel.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/panel.js new file mode 100644 index 0000000..6c084cf --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/panel.js @@ -0,0 +1,577 @@ +import St from 'gi://St'; +import GLib from 'gi://GLib'; +import Meta from 'gi://Meta'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; + +import { PaintSignals } from '../conveniences/paint_signals.js'; + +import { Pipeline } from '../conveniences/pipeline.js'; +import { DummyPipeline } from '../conveniences/dummy_pipeline.js'; + +const DASH_TO_PANEL_UUID = 'dash-to-panel@jderose9.github.com'; +const PANEL_STYLES = [ + "transparent-panel", + "light-panel", + "dark-panel", + "contrasted-panel" +]; + +// global listener, so we don't miss the panel destruction event +let isMainPanelAlive = true; +Main.panel.connect('destroy', () => isMainPanelAlive = false); + +export const PanelBlur = class PanelBlur { + constructor(connections, settings, effects_manager) { + this.connections = connections; + this.window_signal_ids = new Map(); + this.settings = settings; + this.effects_manager = effects_manager; + this.actors_list = []; + this.enabled = false; + } + + enable() { + if (this.enabled) { + this._log("blur already enabled"); + return; + } + + this._log("blurring top panel"); + + // check for panels when Dash to Panel is activated + this.connections.connect( + Main.extensionManager, + 'extension-state-changed', + (_, extension) => { + if (extension.uuid === DASH_TO_PANEL_UUID + && extension.state === 1 + ) { + this.connections.connect( + global.dashToPanel, + 'panels-created', + _ => this.blur_dtp_panels() + ); + + this.blur_existing_panels(); + } + } + ); + + this.blur_existing_panels(); + + // connect to overview being opened/closed, and dynamically show or not + // the blur when a window is near a panel + this.connect_to_windows_and_overview(); + + // connect to workareas change + this.connections.connect(global.display, 'workareas-changed', + _ => this.reset() + ); + + this.enabled = true; + } + + reset() { + if (!this.enabled) { + this._log("reset called but blur is not enabled"); + return; + } + + this._log("resetting..."); + + this.disable(); + setTimeout(_ => this.enable(), 1); + } + + /// Check for already existing panels and blur them if they are not already + blur_existing_panels() { + // check if dash-to-panel is present + if (global.dashToPanel) { + // blur already existing ones + if (global.dashToPanel.panels) + this.blur_dtp_panels(); + + // blur main panel if requested in settings + if (this.settings.dash_to_panel.BLUR_ORIGINAL_PANEL && isMainPanelAlive) + this.maybe_blur_panel(Main.panel); + } else { + // if no dash-to-panel, blur the main and only panel + this.maybe_blur_panel(Main.panel); + } + } + + blur_dtp_panels() { + // Defer the blurring to the next idle cycle. + // This is crucial to ensure the panel actors have been allocated their + // final size and position by the compositor, avoiding race conditions + // during extension startup. + GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => { + if (!global.dashToPanel?.panels) { + return GLib.SOURCE_REMOVE; + } + + this._log("Blurring Dash to Panel panels after idle."); + + // blur every panel, except Main.panel (this is handled in blur_existing_panels() method above) + global.dashToPanel.panels.forEach(p => { + if (p.panel != Main.panel) + this.maybe_blur_panel(p.panel); + }); + + return GLib.SOURCE_REMOVE; + }); + }; + + /// Blur a panel only if it is not already blurred (contained in the list) + maybe_blur_panel(panel) { + // check if the panel is contained in the list + let actors = this.actors_list.find( + actors => actors.widgets.panel == panel + ); + + if (!actors) + // if the actors is not blurred, blur it + this.blur_panel(panel); + } + + /// Blur a panel + blur_panel(panel) { + let panel_box = panel.get_parent(); + let is_dtp_panel = false; + if (!panel_box.name) { + is_dtp_panel = true; + panel_box = panel_box.get_parent(); + } + + let monitor = Main.layoutManager.findMonitorForActor(panel); + if (!monitor) + return; + + let background_group = new Meta.BackgroundGroup( + { name: 'bms-panel-backgroundgroup', width: 0, height: 0 } + ); + + let background, bg_manager; + let static_blur = this.settings.panel.STATIC_BLUR; + if (static_blur) { + let bg_manager_list = []; + const pipeline = new Pipeline( + this.effects_manager, + global.blur_my_shell._pipelines_manager, + this.settings.panel.PIPELINE + ); + background = pipeline.create_background_with_effects( + monitor.index, bg_manager_list, + background_group, 'bms-panel-blurred-widget' + ); + bg_manager = bg_manager_list[0]; + } + else { + const pipeline = new DummyPipeline(this.effects_manager, this.settings.panel); + [background, bg_manager] = pipeline.create_background_with_effect( + background_group, 'bms-panel-blurred-widget' + ); + + let paint_signals = new PaintSignals(this.connections); + + // HACK + // + //`Shell.BlurEffect` does not repaint when shadows are under it. [1] + // + // This does not entirely fix this bug (shadows caused by windows + // still cause artifacts), but it prevents the shadows of the panel + // buttons to cause artifacts on the panel itself + // + // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 + + { + if (this.settings.HACKS_LEVEL === 1) { + this._log("panel hack level 1"); + + paint_signals.disconnect_all(); + paint_signals.connect(background, pipeline.effect); + } else { + paint_signals.disconnect_all(); + } + } + } + + // insert the background group to the panel box + panel_box.insert_child_at_index(background_group, 0); + + // the object that is used to remembering each elements that is linked to the blur effect + let actors = { + widgets: { panel, panel_box, background, background_group }, + static_blur, + monitor, + bg_manager, + is_dtp_panel + }; + this.actors_list.push(actors); + + // update the size of the actor + this.update_size(actors); + + // connect to panel, panel_box and its parent position or size change + // this should fire update_size every time one of its params change + this.connections.connect( + panel, + 'notify::position', + _ => this.update_size(actors) + ); + this.connections.connect( + panel_box, + ['notify::size', 'notify::position'], + _ => this.update_size(actors) + ); + this.connections.connect( + panel_box.get_parent(), + 'notify::position', + _ => this.update_size(actors) + ); + + // connect to the panel getting destroyed + this.connections.connect( + panel, + 'destroy', + _ => this.destroy_blur(actors, true) + ); + } + + update_size(actors) { + let panel = actors.widgets.panel; + let panel_box = actors.widgets.panel_box; + let background = actors.widgets.background; + let [width, height] = panel_box.get_size(); + + // if static blur, need to clip the background + if (actors.static_blur) { + let monitor = Main.layoutManager.findMonitorForActor(panel); + if (!monitor) + return; + + // an alternative to panel.get_transformed_position, because it + // sometimes yields NaN (probably when the actor is not fully + // positionned yet) + let [p_x, p_y] = panel_box.get_position(); + let [p_p_x, p_p_y] = panel_box.get_parent().get_position(); + let x = p_x + p_p_x - monitor.x + (width - panel.width) / 2; + let y = p_y + p_p_y - monitor.y + (height - panel.height) / 2; + + background.set_clip(x, y, panel.width, panel.height); + background.x = (width - panel.width) / 2 - x; + background.y = .5 + (height - panel.height) / 2 - y; + } else { + background.x = panel.x; + background.y = panel.y; + background.width = panel.width; + background.height = panel.height; + } + + // update the monitor panel is on + actors.monitor = Main.layoutManager.findMonitorForActor(panel); + } + + /// Connect when overview if opened/closed to hide/show the blur accordingly + /// + /// If HIDETOPBAR is set, we need just to hide the blur when showing appgrid + /// (so no shadow is cropped) + connect_to_overview() { + // may be called when panel blur is disabled, if hidetopbar + // compatibility is toggled on/off + // if this is the case, do nothing as only the panel blur interfers with + // hidetopbar + if ( + this.settings.panel.BLUR && + this.settings.panel.UNBLUR_IN_OVERVIEW + ) { + if (!this.settings.hidetopbar.COMPATIBILITY) { + this.connections.connect( + Main.overview, 'showing', _ => this.hide() + ); + this.connections.connect( + Main.overview, 'hidden', _ => this.show() + ); + } else { + let appDisplay = Main.overview._overview._controls._appDisplay; + + this.connections.connect( + appDisplay, 'show', _ => this.hide() + ); + this.connections.connect( + appDisplay, 'hide', _ => this.show() + ); + this.connections.connect( + Main.overview, 'hidden', _ => this.show() + ); + } + + } + } + + /// Connect to windows disable transparency when a window is too close + connect_to_windows() { + if ( + this.settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY + ) { + // connect to overview opening/closing + this.connections.connect(Main.overview, ['showing', 'hiding'], + _ => this.update_visibility() + ); + + // connect to session mode update + this.connections.connect(Main.sessionMode, 'updated', + _ => this.update_visibility() + ); + + // manage already-existing windows + for (const meta_window_actor of global.get_window_actors()) { + this.on_window_actor_added( + meta_window_actor.get_parent(), meta_window_actor + ); + } + + // manage windows at their creation/removal + this.connections.connect(global.window_group, 'child-added', + this.on_window_actor_added.bind(this) + ); + this.connections.connect(global.window_group, 'child-removed', + this.on_window_actor_removed.bind(this) + ); + + // connect to a workspace change + this.connections.connect(global.window_manager, 'switch-workspace', + _ => this.update_visibility() + ); + + // perform early update + this.update_visibility(); + } else { + // reset transparency for every panels + this.actors_list.forEach( + actors => this.set_should_override_panel(actors, true) + ); + } + } + + /// An helper to connect to both the windows and overview signals. + /// This is the only function that should be directly called, to prevent + /// inconsistencies with signals not being disconnected. + connect_to_windows_and_overview() { + this.disconnect_from_windows_and_overview(); + this.connect_to_overview(); + this.connect_to_windows(); + } + + /// Disconnect all the connections created by connect_to_windows + disconnect_from_windows_and_overview() { + // disconnect the connections to actors + for (const actor of [ + Main.overview, Main.sessionMode, + global.window_group, global.window_manager, + Main.overview._overview._controls._appDisplay + ]) { + this.connections.disconnect_all_for(actor); + } + + // disconnect the connections from windows + for (const [actor, ids] of this.window_signal_ids) { + for (const id of ids) { + actor.disconnect(id); + } + } + this.window_signal_ids = new Map(); + } + + /// Update the css classname of the panel for light theme + update_light_text_classname(disable = false) { + if (!isMainPanelAlive) { + this._log("cannot update light text classname, Main.panel is not alive"); + return; + } + + if (this.settings.panel.FORCE_LIGHT_TEXT && !disable) + Main.panel.add_style_class_name("panel-light-text"); + else + Main.panel.remove_style_class_name("panel-light-text"); + } + + /// Callback when a new window is added + on_window_actor_added(container, meta_window_actor) { + this.window_signal_ids.set(meta_window_actor, [ + meta_window_actor.connect('notify::allocation', + _ => this.update_visibility() + ), + meta_window_actor.connect('notify::visible', + _ => this.update_visibility() + ) + ]); + this.update_visibility(); + } + + /// Callback when a window is removed + on_window_actor_removed(container, meta_window_actor) { + for (const signalId of this.window_signal_ids.get(meta_window_actor)) { + meta_window_actor.disconnect(signalId); + } + this.window_signal_ids.delete(meta_window_actor); + this.update_visibility(); + } + + /// Update the visibility of the blur effect + update_visibility() { + if ( + isMainPanelAlive && Main.panel.has_style_pseudo_class('overview') + || !Main.sessionMode.hasWindows + ) { + this.actors_list.forEach( + actors => this.set_should_override_panel(actors, true) + ); + return; + } + + if (!Main.layoutManager.primaryMonitor) + return; + + // get all the windows in the active workspace that are visible + const workspace = global.workspace_manager.get_active_workspace(); + const windows = workspace.list_windows().filter(meta_window => + meta_window.showing_on_its_workspace() + && !meta_window.is_hidden() + && meta_window.get_window_type() !== Meta.WindowType.DESKTOP + // exclude Desktop Icons NG + && meta_window.get_gtk_application_id() !== "com.rastersoft.ding" + && meta_window.get_gtk_application_id() !== "com.desktop.ding" + ); + + // check if at least one window is near enough to each panel and act + // accordingly + const scale = St.ThemeContext.get_for_stage(global.stage).scale_factor; + this.actors_list + // do not apply for dtp panels, as it would only cause bugs and it + // can be done from its preferences anyway + .filter(actors => !actors.is_dtp_panel) + .forEach(actors => { + let panel = actors.widgets.panel; + let panel_top = panel.get_transformed_position()[1]; + let panel_bottom = panel_top + panel.get_height(); + + // check if at least a window is near enough the panel + let window_overlap_panel = false; + windows.forEach(meta_window => { + let window_monitor_i = meta_window.get_monitor(); + let same_monitor = actors.monitor.index == window_monitor_i; + + let window_vertical_pos = meta_window.get_frame_rect().y; + let window_vertical_bottom = window_vertical_pos + meta_window.get_frame_rect().height; + + // if so, and if in the same monitor, then it overlaps + if (same_monitor + && + // check if panel is on top + ((panel_top === 0 && window_vertical_pos < panel_bottom + 5 * scale) || + // check if panel is at the bottom + (panel_top > 0 && window_vertical_bottom > panel_top - 5 * scale)) + ) + window_overlap_panel = true; + }); + + // if no window overlaps, then the panel is transparent + this.set_should_override_panel( + actors, !window_overlap_panel + ); + }); + } + + /// Choose wether or not the panel background should be overriden, in + /// respect to its argument and the `override-background` setting. + set_should_override_panel(actors, should_override) { + let panel = actors.widgets.panel; + + PANEL_STYLES.forEach(style => panel.remove_style_class_name(style)); + + if ( + this.settings.panel.OVERRIDE_BACKGROUND + && + should_override + ) { + panel.add_style_class_name( + PANEL_STYLES[this.settings.panel.STYLE_PANEL] + ); + } + + // update the classname if the panel to have or have not light text + this.update_light_text_classname(!should_override); + } + + update_pipeline() { + this.actors_list.forEach(actors => + actors.bg_manager._bms_pipeline.change_pipeline_to( + this.settings.panel.PIPELINE + ) + ); + } + + show() { + this.actors_list.forEach(actors => { + actors.widgets.background.show(); + }); + } + + hide() { + this.actors_list.forEach(actors => { + actors.widgets.background.hide(); + }); + } + + // IMPORTANT: do never call this in a mutable `this.actors_list.forEach` + destroy_blur(actors, panel_already_destroyed) { + this.set_should_override_panel(actors, false); + + actors.bg_manager._bms_pipeline.destroy(); + + if (panel_already_destroyed) + actors.bg_manager.backgroundActor = null; + actors.bg_manager.destroy(); + + if (!panel_already_destroyed) { + actors.widgets.panel_box.remove_child(actors.widgets.background_group); + actors.widgets.background_group.destroy_all_children(); + actors.widgets.background_group.destroy(); + } + + let index = this.actors_list.indexOf(actors); + if (index >= 0) + this.actors_list.splice(index, 1); + } + + disable() { + if (!this.enabled) { + this._log("blur already removed"); + return; + } + + this._log("removing blur from top panel"); + + this.disconnect_from_windows_and_overview(); + + this.update_light_text_classname(true); + + const immutable_actors_list = [...this.actors_list]; + immutable_actors_list.forEach(actors => this.destroy_blur(actors, false)); + this.actors_list = []; + + this.connections.disconnect_all(); + + this.enabled = false; + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > panel] ${str}`); + } + + _warn(str) { + console.warn(`[Blur my Shell > panel] ${str}`); + } +}; diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/screenshot.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/screenshot.js new file mode 100644 index 0000000..dcf05eb --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/screenshot.js @@ -0,0 +1,110 @@ +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; + +import { Pipeline } from '../conveniences/pipeline.js'; + +export const ScreenshotBlur = class ScreenshotBlur { + constructor(connections, settings, effects_manager) { + this.connections = connections; + this.settings = settings; + this.screenshot_background_managers = []; + this.effects_manager = effects_manager; + } + + enable() { + this._log("blurring screenshot's window selector"); + + // connect to monitors change + this.connections.connect(Main.layoutManager, 'monitors-changed', + _ => this.update_backgrounds() + ); + + // update backgrounds when the component is enabled + this.update_backgrounds(); + } + + update_backgrounds() { + // remove every old background + this.remove_background_actors(); + // create new backgrounds for the screenshot window selector + for (let i = 0; i < Main.screenshotUI._windowSelectors.length; i++) { + const window_selector = Main.screenshotUI._windowSelectors[i]; + const pipeline = new Pipeline( + this.effects_manager, + global.blur_my_shell._pipelines_manager, + this.settings.screenshot.PIPELINE + ); + pipeline.create_background_with_effects( + window_selector._monitorIndex, this.screenshot_background_managers, + window_selector, 'bms-screenshot-blurred-widget', false + ); + + // prevent old `BackgroundActor` from being accessed, which creates a whole bug of logs + this.connections.connect(window_selector.get_parent(), 'destroy', _ => { + this.screenshot_background_managers.forEach(background_manager => { + if (background_manager.backgroundActor) { + let widget = background_manager.backgroundActor.get_parent(); + let parent = widget?.get_parent(); + + if (parent == window_selector) { + background_manager._bms_pipeline.destroy(); + parent.remove_child(widget); + } + } + background_manager.destroy(); + }); + + window_selector.get_children().forEach(child => { + if (child.get_name() == 'bms-screenshot-blurred-widget') + window_selector.remove_child(child); + }); + + let index = this.screenshot_background_managers.indexOf(window_selector); + this.screenshot_background_managers.splice(index, 1); + }); + } + } + + update_pipeline() { + this.screenshot_background_managers.forEach(background_manager => + background_manager._bms_pipeline.change_pipeline_to( + this.settings.screenshot.PIPELINE + ) + ); + } + + remove_background_actors() { + this.screenshot_background_managers.forEach(background_manager => { + background_manager._bms_pipeline.destroy(); + if (background_manager.backgroundActor) { + let widget = background_manager.backgroundActor.get_parent(); + widget?.get_parent()?.remove_child(widget); + } + background_manager.destroy(); + }); + + Main.screenshotUI._windowSelectors.forEach(window_selector => + window_selector.get_children().forEach(child => { + if (child.get_name() == 'bms-screenshot-blurred-widget') + window_selector.remove_child(child); + }) + ); + + this.screenshot_background_managers = []; + } + + disable() { + this._log("removing blur from screenshot's window selector"); + + this.remove_background_actors(); + this.connections.disconnect_all(); + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > screenshot] ${str}`); + } + + _warn(str) { + console.warn(`[Blur my Shell > screenshot] ${str}`); + } +}; diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/window_list.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/window_list.js new file mode 100644 index 0000000..6ab0644 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/components/window_list.js @@ -0,0 +1,148 @@ +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; + +import { PaintSignals } from '../conveniences/paint_signals.js'; +import { DummyPipeline } from '../conveniences/dummy_pipeline.js'; + + +export const WindowListBlur = class WindowListBlur { + constructor(connections, settings, effects_manager) { + this.connections = connections; + this.settings = settings; + this.paint_signals = new PaintSignals(connections); + this.effects_manager = effects_manager; + this.pipelines = []; + } + + enable() { + this._log("blurring window list"); + + // blur if window-list is found + Main.layoutManager.uiGroup.get_children().forEach( + child => this.try_blur(child) + ); + + // listen to new actors in `Main.layoutManager.uiGroup` and blur it if + // if is window-list + this.connections.connect( + Main.layoutManager.uiGroup, + 'child-added', + (_, child) => this.try_blur(child) + ); + + // connect to overview + this.connections.connect(Main.overview, 'showing', _ => { + this.hide(); + }); + this.connections.connect(Main.overview, 'hidden', _ => { + this.show(); + }); + } + + try_blur(actor) { + if ( + actor.constructor.name === "WindowList" && + actor.style !== "background:transparent;" + ) { + this._log("found window list to blur"); + + const pipeline = new DummyPipeline( + this.effects_manager, this.settings.window_list + ); + pipeline.attach_effect_to_actor(actor); + this.pipelines.push(pipeline); + + actor.set_style("background:transparent;"); + + actor._windowList.get_children().forEach( + window => this.style_window_button(window) + ); + + this.connections.connect( + actor._windowList, + 'child-added', + (_, window) => this.style_window_button(window) + ); + + this.connections.connect( + actor, + 'destroy', + _ => this.destroy_blur(pipeline, true) + ); + + + // HACK + // + //`Shell.BlurEffect` does not repaint when shadows are under it. [1] + // + // This does not entirely fix this bug (shadows caused by windows + // still cause artifacts), but it prevents the shadows of the panel + // buttons to cause artifacts on the panel itself + // + // [1]: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2857 + + if (this.settings.HACKS_LEVEL === 1) { + this._log("window list hack level 1"); + + this.paint_signals.disconnect_all_for_actor(actor); + this.paint_signals.connect(actor, pipeline.effect); + } else { + this.paint_signals.disconnect_all_for_actor(actor); + } + } + } + + style_window_button(window) { + window.get_child_at_index(0).set_style( + "box-shadow:none; background-color:rgba(0,0,0,0.2); border-radius:5px;" + ); + } + + // IMPORTANT: do never call this in a mutable `this.pipelines.forEach` + destroy_blur(pipeline, actor_destroyed = false) { + if (!actor_destroyed) { + this.remove_style(pipeline.actor); + this.paint_signals.disconnect_all_for_actor(pipeline.actor); + } + + pipeline.destroy(); + + let index = this.pipelines.indexOf(pipeline); + if (index >= 0) + this.pipelines.splice(pipeline, 1); + } + + remove_style(actor) { + if ( + actor.constructor.name === "WindowList" && + actor.style === "background:transparent;" + ) { + actor.style = null; + actor._windowList.get_children().forEach( + child => child.get_child_at_index(0).set_style(null) + ); + } + } + + hide() { + this.pipelines.forEach(pipeline => pipeline.effect?.set_enabled(false)); + } + + show() { + this.pipelines.forEach(pipeline => pipeline.effect?.set_enabled(true)); + } + + disable() { + this._log("removing blur from window list"); + + const immutable_pipelines_list = [...this.pipelines]; + immutable_pipelines_list.forEach(pipeline => this.destroy_blur(pipeline)); + + this.pipelines = []; + this.connections.disconnect_all(); + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > window list] ${str}`); + } +};
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js new file mode 100644 index 0000000..0583db3 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/connections.js @@ -0,0 +1,106 @@ +import GObject from 'gi://GObject'; + +/// An object to easily manage signals. +export const Connections = class Connections { + constructor() { + this.buffer = []; + } + + /// Adds a connection. + /// + /// Takes as arguments: + /// - an actor, which fires the signal + /// - signal(s) (string or array of strings), which are watched for + /// - a callback, which is called when the signal is fired + connect(actor, signals, handler) { + if (signals instanceof Array) { + signals.forEach(signal => { + let id = actor.connect(signal, handler); + this.process_connection(actor, id); + }); + } else { + let id = actor.connect(signals, handler); + this.process_connection(actor, id); + } + + } + + /// Process the given actor and id. + /// + /// This makes sure that the signal is disconnected when the actor is + /// destroyed, and that the signal can be managed through other Connections + /// methods. + process_connection(actor, id) { + let infos = { + actor: actor, + id: id + }; + + // remove the signal when the actor is destroyed + if ( + actor.connect && + ( + !(actor instanceof GObject.Object) || + GObject.signal_lookup('destroy', actor) + ) + ) { + let destroy_id = actor.connect('destroy', () => { + actor.disconnect(id); + actor.disconnect(destroy_id); + + let index = this.buffer.indexOf(infos); + if (index >= 0) { + this.buffer.splice(index, 1); + } + }); + infos.destroy_id = destroy_id; + } + + this.buffer.push(infos); + } + + /// Disconnects every connection found for an actor. + disconnect_all_for(actor) { + // get every connection stored for the actor + let actor_connections = this.buffer.filter( + infos => infos.actor === actor + ); + + // remove each of them + actor_connections.forEach(connection => { + // disconnect + try { + connection.actor.disconnect(connection.id); + if ('destroy_id' in connection) + connection.actor.disconnect(connection.destroy_id); + } catch (e) { + this._warn(`error removing connection: ${e}; continuing`); + } + + // remove from buffer + let index = this.buffer.indexOf(connection); + this.buffer.splice(index, 1); + }); + } + + /// Disconnect every connection for each actor. + disconnect_all() { + this.buffer.forEach(connection => { + // disconnect + try { + connection.actor.disconnect(connection.id); + if ('destroy_id' in connection) + connection.actor.disconnect(connection.destroy_id); + } catch (e) { + this._warn(`error removing connection: ${e}; continuing`); + } + }); + + // reset buffer + this.buffer = []; + } + + _warn(str) { + console.warn(`[Blur my Shell > connections] ${str}`); + } +};
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/dummy_pipeline.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/dummy_pipeline.js new file mode 100644 index 0000000..544d68c --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/dummy_pipeline.js @@ -0,0 +1,112 @@ +import St from 'gi://St'; +import Clutter from 'gi://Clutter'; + +/// A dummy `Pipeline`, for dynamic blur only. +/// Instead of a pipeline id, we take the settings of the component we want to blur. +export const DummyPipeline = class DummyPipeline { + constructor(effects_manager, settings, actor = null) { + this.effects_manager = effects_manager; + this.settings = settings; + this.effect = null; + this.attach_effect_to_actor(actor); + } + + create_background_with_effect( + background_group, + widget_name + ) { + // create the new actor + this.actor = new St.Widget({ name: widget_name }); + + this.attach_effect_to_actor(this.actor); + + // a dummy `BackgroundManager`, just to access the pipeline easily + let bg_manager = new Clutter.Actor; + bg_manager.backgroundActor = this.actor; + bg_manager._bms_pipeline = this; + + background_group.insert_child_at_index(this.actor, 0); + + return [this.actor, bg_manager]; + }; + + attach_effect_to_actor(actor) { + // set the actor + if (actor) + this.actor = actor; + else { + this.remove_pipeline_from_actor(); + return; + } + + // build the new effect to be added + this.build_effect({ + unscaled_radius: 2 * this.settings.SIGMA, + brightness: this.settings.BRIGHTNESS, + }); + + this.actor_destroy_id = this.actor.connect( + "destroy", () => this.remove_pipeline_from_actor() + ); + + // add the effect to the actor + if (this.actor) + this.actor.add_effect(this.effect); + else + this._warn(`could not add effect to actor, actor does not exist anymore`); + } + + remove_pipeline_from_actor() { + this.remove_effect(); + if (this.actor && this.actor_destroy_id) + this.actor.disconnect(this.actor_destroy_id); + this.actor_destroy_id = null; + this.actor = null; + } + + build_effect(params) { + // create the effect + this.effect = this.effects_manager.new_native_dynamic_gaussian_blur_effect(params); + + // connect to settings changes, using the true gsettings object + this._sigma_changed_id = this.settings.settings.connect( + 'changed::sigma', () => this.effect.unscaled_radius = 2 * this.settings.SIGMA + ); + this._brightness_changed_id = this.settings.settings.connect( + 'changed::brightness', () => this.effect.brightness = this.settings.BRIGHTNESS + ); + } + + repaint_effect() { + this.effect?.queue_repaint(); + } + + /// Remove every effect from the actor it is attached to. Please note that they are not + /// destroyed, but rather stored (thanks to the `EffectManager` class) to be reused later. + remove_effect() { + if (this.effect) + this.effects_manager.remove(this.effect); + this.effect = null; + + if (this._sigma_changed_id) + this.settings.settings.disconnect(this._sigma_changed_id); + if (this._brightness_changed_id) + this.settings.settings.disconnect(this._brightness_changed_id); + delete this._sigma_changed_id; + delete this._brightness_changed_id; + } + + /// Do nothing for this dummy pipeline. + /// Note: exposed to public API. + change_pipeline_to() { return; } + + /// Note: exposed to public API. + destroy() { + this.remove_effect(); + this.remove_pipeline_from_actor(); + } + + _warn(str) { + console.warn(`[Blur my Shell > dummy pip] ${str}`); + } +};
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/effects_manager.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/effects_manager.js new file mode 100644 index 0000000..947d535 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/effects_manager.js @@ -0,0 +1,90 @@ +import { get_supported_effects } from '../effects/effects.js'; + +/// An object to manage effects (by not destroying them all the time) +export const EffectsManager = class EffectsManager { + constructor(connections) { + this.connections = connections; + this.used = []; + this.SUPPORTED_EFFECTS = get_supported_effects(); + + Object.keys(this.SUPPORTED_EFFECTS).forEach(effect_name => { + // init the arrays containing each unused effect + this[effect_name + '_effects'] = []; + + // init the functions for each effect + this['new_' + effect_name + '_effect'] = function (params) { + let effect; + if (this[effect_name + '_effects'].length > 0) { + effect = this[effect_name + '_effects'].splice(0, 1)[0]; + effect.set({ + ...this.SUPPORTED_EFFECTS[effect_name].class.default_params, ...params + }); + } else + effect = new this.SUPPORTED_EFFECTS[effect_name].class({ + ...this.SUPPORTED_EFFECTS[effect_name].class.default_params, ...params + }); + + this.used.push(effect); + this.connect_to_destroy(effect); + return effect; + }; + }); + } + + connect_to_destroy(effect) { + effect.old_actor = effect.get_actor(); + if (effect.old_actor) + effect.old_actor_id = effect.old_actor.connect('destroy', _ => { + this.remove(effect, true); + }); + + this.connections.connect(effect, 'notify::actor', _ => { + let actor = effect.get_actor(); + + if (effect.old_actor && actor != effect.old_actor) + effect.old_actor.disconnect(effect.old_actor_id); + + if (actor && actor != effect.old_actor) { + effect.old_actor_id = actor.connect('destroy', _ => { + this.remove(effect, true); + }); + } + }); + } + + // IMPORTANT: do never call this in a mutable `this.used.forEach` + remove(effect, actor_already_destroyed = false) { + if (!actor_already_destroyed) + try { + effect.get_actor()?.remove_effect(effect); + } catch (e) { + this._warn(`could not remove the effect, continuing: ${e}`); + } + if (effect.old_actor) + effect.old_actor.disconnect(effect.old_actor_id); + delete effect.old_actor; + delete effect.old_actor_id; + + let index = this.used.indexOf(effect); + if (index >= 0) { + this.used.splice(index, 1); + + Object.keys(this.SUPPORTED_EFFECTS).forEach(effect_name => { + if (effect instanceof this.SUPPORTED_EFFECTS[effect_name].class) + this[effect_name + '_effects'].push(effect); + }); + } + } + + destroy_all() { + const immutable_used_list = [...this.used]; + immutable_used_list.forEach(effect => this.remove(effect)); + Object.keys(this.SUPPORTED_EFFECTS).forEach(effect_name => { + this[effect_name + '_effects'].splice(0, this[effect_name + '_effects'].length); + }); + } + + _warn(str) { + console.warn(`[Blur my Shell > effects mng] ${str}`); + } +}; diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/keys.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/keys.js new file mode 100644 index 0000000..fcde72b --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/keys.js @@ -0,0 +1,190 @@ +import { Type } from './settings.js'; + +// This lists the preferences keys +export const KEYS = [ + { + component: "general", schemas: [ + { type: Type.PIPELINES, name: "pipelines" }, + { type: Type.I, name: "hacks-level" }, + { type: Type.B, name: "debug" }, + ] + }, + { + component: "overview", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.S, name: "pipeline" }, + { type: Type.I, name: "style-components" }, + ] + }, + { + component: "appfolder", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.I, name: "style-dialogs" }, + ] + }, + { + component: "panel", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "static-blur" }, + { type: Type.S, name: "pipeline" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.B, name: "unblur-in-overview" }, + { type: Type.B, name: "force-light-text" }, + { type: Type.B, name: "override-background" }, + { type: Type.I, name: "style-panel" }, + { type: Type.B, name: "override-background-dynamically" }, + ] + }, + { + component: "dash-to-dock", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "static-blur" }, + { type: Type.S, name: "pipeline" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.B, name: "unblur-in-overview" }, + { type: Type.B, name: "override-background" }, + { type: Type.I, name: "style-dash-to-dock" }, + ] + }, + { + component: "applications", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.B, name: "static-blur" }, + { type: Type.S, name: "pipeline" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.I, name: "opacity" }, + { type: Type.B, name: "dynamic-opacity" }, + { type: Type.B, name: "blur-on-overview" }, + { type: Type.B, name: "enable-all" }, + { type: Type.AS, name: "whitelist" }, + { type: Type.AS, name: "blacklist" }, + ] + }, + { + component: "lockscreen", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.S, name: "pipeline" }, + ] + }, + { + component: "window-list", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.S, name: "pipeline" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + ] + }, + { + component: "coverflow-alt-tab", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.S, name: "pipeline" }, + ] + }, + { + component: "screenshot", schemas: [ + { type: Type.B, name: "blur" }, + { type: Type.S, name: "pipeline" }, + ] + }, + { + component: "hidetopbar", schemas: [ + { type: Type.B, name: "compatibility" }, + ] + }, + { + component: "dash-to-panel", schemas: [ + { type: Type.B, name: "blur-original-panel" }, + ] + }, +]; + + +// This lists the deprecated preferences keys +export const DEPRECATED_KEYS = [ + { + component: "general", schemas: [ + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + { type: Type.B, name: "color-and-noise" }, + ] + }, + { + component: "overview", schemas: [ + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "appfolder", schemas: [ + { type: Type.B, name: "customize" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "panel", schemas: [ + { type: Type.B, name: "customize" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "dash-to-dock", schemas: [ + { type: Type.B, name: "customize" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + { type: Type.I, name: "corner-radius" }, + ] + }, + { + component: "applications", schemas: [ + { type: Type.B, name: "customize" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "lockscreen", schemas: [ + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "window-list", schemas: [ + { type: Type.B, name: "customize" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, + { + component: "screenshot", schemas: [ + { type: Type.B, name: "customize" }, + { type: Type.I, name: "sigma" }, + { type: Type.D, name: "brightness" }, + { type: Type.C, name: "color" }, + { type: Type.D, name: "noise-amount" }, + { type: Type.D, name: "noise-lightness" }, + ] + }, +];
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/paint_signals.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/paint_signals.js new file mode 100644 index 0000000..5fbfee4 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/paint_signals.js @@ -0,0 +1,91 @@ +import GObject from 'gi://GObject'; +import Clutter from 'gi://Clutter'; + + +export const PaintSignals = class PaintSignals { + constructor(connections) { + this.buffer = []; + this.connections = connections; + } + + connect(actor, blur_effect) { + let paint_effect = new EmitPaintSignal(); + let infos = { + actor: actor, + paint_effect: paint_effect + }; + let counter = 0; + + actor.add_effect(paint_effect); + this.connections.connect(paint_effect, 'update-blur', () => { + try { + // checking if blur_effect.queue_repaint() has been recently called + if (counter === 0) { + counter = 2; + blur_effect.queue_repaint(); + } + else counter--; + } catch (e) { } + }); + + // remove the actor from buffer when it is destroyed + if ( + actor.connect && + ( + !(actor instanceof GObject.Object) || + GObject.signal_lookup('destroy', actor) + ) + ) + this.connections.connect(actor, 'destroy', () => { + const immutable_buffer = [...this.buffer]; + immutable_buffer.forEach(infos => { + if (infos.actor === actor) { + // remove from buffer + let index = this.buffer.indexOf(infos); + this.buffer.splice(index, 1); + } + }); + }); + + this.buffer.push(infos); + } + + disconnect_all_for_actor(actor) { + const immutable_buffer = [...this.buffer]; + immutable_buffer.forEach(infos => { + if (infos.actor === actor) { + this.connections.disconnect_all_for(infos.paint_effect); + infos.actor.remove_effect(infos.paint_effect); + + // remove from buffer + let index = this.buffer.indexOf(infos); + this.buffer.splice(index, 1); + } + }); + } + + disconnect_all() { + this.buffer.forEach(infos => { + this.connections.disconnect_all_for(infos.paint_effect); + infos.actor.remove_effect(infos.paint_effect); + }); + + this.buffer = []; + } +}; + +export const EmitPaintSignal = GObject.registerClass({ + GTypeName: 'EmitPaintSignal', + Signals: { + 'update-blur': { + param_types: [] + }, + } +}, + class EmitPaintSignal extends Clutter.Effect { + vfunc_paint(node, paint_context, paint_flags) { + this.emit("update-blur"); + super.vfunc_paint(node, paint_context, paint_flags); + } + } +);
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js new file mode 100644 index 0000000..84b1d7a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipeline.js @@ -0,0 +1,223 @@ +import St from 'gi://St'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import * as Background from 'resource:///org/gnome/shell/ui/background.js'; + +/// A `Pipeline` object is a handy way to manage the effects attached to an actor. It only manages +/// one actor at a time (so blurring multiple widgets will need multiple `Pipeline`), and is +/// linked to a `pipeline_id` that has been (hopefully) defined in the settings. +/// +/// It communicates with the settings through the `PipelinesManager` object, and receives different +/// signals (with `pipeline_id` being an unique string): +/// - `'pipeline_id'::pipeline-updated`, handing a new pipeline descriptor object, when the pipeline +/// has been changed enough that it needs to rebuild the effects configuration +/// - `'pipeline_id'::pipeline-destroyed`, when the pipeline has been destroyed; thus making the +/// `Pipeline` change its id to `pipeline_default` +/// +/// And each effect, with an unique `id`, is connected to the `PipelinesManager` for the signals: +/// - `'pipeline_id'::effect-'id'-key-removed`, handing the key that was removed +/// - `'pipeline_id'::effect-'id'-key-updated`, handing the key that was changed and its new value +/// - `'pipeline_id'::effect-'id'-key-added`, handing the key that was added and its value +export const Pipeline = class Pipeline { + constructor(effects_manager, pipelines_manager, pipeline_id, actor = null) { + this.effects_manager = effects_manager; + this.pipelines_manager = pipelines_manager; + this.effects = []; + this.set_pipeline_id(pipeline_id); + this.attach_pipeline_to_actor(actor); + } + + /// Create a background linked to the monitor with index `monitor_index`, with a + /// `BackgroundManager` that is appended to the list `background_managers`. The background actor + /// will be given the name `widget_name` and inserted into the given `background_group`. + /// If `use_absolute_position` is false, then the position used is at (0,0); useful when the + /// positioning is relative. + /// Note: exposed to public API. + create_background_with_effects( + monitor_index, + background_managers, + background_group, + widget_name, + use_absolute_position = true + ) { + let monitor = Main.layoutManager.monitors[monitor_index]; + + // create the new actor + this.actor = new St.Widget({ + name: widget_name, + x: use_absolute_position ? monitor.x : 0, + y: .5 + (use_absolute_position ? monitor.y : 0), // add 1 to correct z-position + z_position: 1, // seems to fix the multi-monitor glitch + width: monitor.width, + height: monitor.height + }); + + // remove the effects, wether or not we attach the pipeline to the actor: if they are fired + // while the actor has changed, this could go bad + this.remove_all_effects(); + if (this.pipeline_id) + this.attach_pipeline_to_actor(this.actor); + + let bg_manager = new Background.BackgroundManager({ + container: this.actor, + monitorIndex: monitor_index, + controlPosition: false, + }); + bg_manager._bms_pipeline = this; + + background_managers.push(bg_manager); + background_group.insert_child_at_index(this.actor, 0); + + return this.actor; + }; + + /// Set the pipeline id, correctly connecting the `Pipeline` object to listen the pipelines + /// manager for pipeline-wide changes. This does not update the effects in consequence, call + /// `change_pipeline_to` instead if you want to reconstruct the effects too. + set_pipeline_id(pipeline_id) { + // disconnect ancient signals + this.remove_connections(); + + // change the id + this.pipeline_id = pipeline_id; + + // connect to settings changes + this._pipeline_changed_id = this.pipelines_manager.connect( + this.pipeline_id + '::pipeline-updated', + (_, new_pipeline) => this.update_effects_from_pipeline(new_pipeline) + ); + this._pipeline_destroyed_id = this.pipelines_manager.connect( + this.pipeline_id + '::pipeline-destroyed', + _ => this.change_pipeline_to("pipeline_default") + ); + } + + /// Disconnect the signals for the pipeline changes. Please note that the signals related to the + /// effects are stored with them and removed with `remove_all_effects`. + remove_connections() { + if (this._pipeline_changed_id) + this.pipelines_manager.disconnect(this._pipeline_changed_id); + if (this._pipeline_destroyed_id) + this.pipelines_manager.disconnect(this._pipeline_destroyed_id); + this._pipeline_changed_id = null; + this._pipeline_destroyed_id = null; + } + + /// Attach a Pipeline object with `pipeline_id` already set to an actor. + attach_pipeline_to_actor(actor) { + // set the actor + if (actor) + this.actor = actor; + else { + this.remove_pipeline_from_actor(); + return; + } + + // attach the pipeline + let pipeline = this.pipelines_manager.pipelines[this.pipeline_id]; + if (!pipeline) { + this._warn(`could not attach pipeline to actor, pipeline "${this.pipeline_id}" not found`); + // do not recurse... + if ("pipeline_default" in this.pipelines_manager.pipelines) { + this.set_pipeline_id("pipeline_default"); + pipeline = this.pipelines_manager.pipelines["pipeline_default"]; + } else + return; + } + + this.actor_destroy_id = this.actor.connect( + "destroy", () => this.remove_pipeline_from_actor() + ); + + // update the effects + this.update_effects_from_pipeline(pipeline); + } + + remove_pipeline_from_actor() { + this.remove_all_effects(); + if (this.actor && this.actor_destroy_id) + this.actor.disconnect(this.actor_destroy_id); + this.actor_destroy_id = null; + this.actor = null; + } + + /// Update the effects from the given pipeline object, the hard way. + update_effects_from_pipeline(pipeline) { + // remove all effects + this.remove_all_effects(); + + // build the new effects to be added + pipeline.effects.forEach(effect => { + if ('new_' + effect.type + '_effect' in this.effects_manager) + this.build_effect(effect); + else + this._warn(`could not add effect to actor, effect "${effect.type}" not found`); + }); + this.effects.reverse(); + + // add the effects to the actor + if (this.actor) + this.effects.forEach(effect => this.actor.add_effect(effect)); + else + this._warn(`could not add effect to actor, actor does not exist anymore`); + } + + /// Given an `effect_infos` object containing the effect type, id and params, build an effect + /// and append it to the effects list + build_effect(effect_infos) { + let effect = this.effects_manager['new_' + effect_infos.type + '_effect'](effect_infos.params); + this.effects.push(effect); + + // connect to settings changes + effect._effect_key_removed_id = this.pipelines_manager.connect( + this.pipeline_id + '::effect-' + effect_infos.id + '-key-removed', + (_, key) => effect[key] = effect.constructor.default_params[key] + ); + effect._effect_key_updated_id = this.pipelines_manager.connect( + this.pipeline_id + '::effect-' + effect_infos.id + '-key-updated', + (_, key, value) => effect[key] = value + ); + effect._effect_key_added_id = this.pipelines_manager.connect( + this.pipeline_id + '::effect-' + effect_infos.id + '-key-added', + (_, key, value) => effect[key] = value + ); + } + + /// Remove every effect from the actor it is attached to. Please note that they are not + /// destroyed, but rather stored (thanks to the `EffectManager` class) to be reused later. + remove_all_effects() { + this.effects.forEach(effect => { + this.effects_manager.remove(effect); + [ + effect._effect_key_removed_id, + effect._effect_key_updated_id, + effect._effect_key_added_id + ].forEach( + id => { if (id) this.pipelines_manager.disconnect(id); } + ); + delete effect._effect_key_removed_id; + delete effect._effect_key_updated_id; + delete effect._effect_key_added_id; + }); + this.effects = []; + } + + /// Change the pipeline id, and update the effects according to this change. + /// Note: exposed to public API. + change_pipeline_to(pipeline_id) { + this.set_pipeline_id(pipeline_id); + this.attach_pipeline_to_actor(this.actor); + } + + /// Resets the `Pipeline` object to a sane state, removing every effect and signal. + /// Note: exposed to public API. + destroy() { + this.remove_all_effects(); + this.remove_connections(); + this.remove_pipeline_from_actor(); + this.pipeline_id = null; + } + + _warn(str) { + console.warn(`[Blur my Shell > pipeline] ${str}`); + } +};
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipelines_manager.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipelines_manager.js new file mode 100644 index 0000000..0fdfe9e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/pipelines_manager.js @@ -0,0 +1,168 @@ +const Signals = imports.signals; + +/// The `PipelinesManager` object permits to store the list of pipelines and their effects in +/// memory. It is meant to *always* be in sync with the `org.gnome.shell.extensions.blur-my-shell`'s +/// `pipelines` gschema. However, we do not want to re-create every effect each time this schema is +/// changed, so the pipelines manager handles it, and dispatches the updates with targeted signals. +/// +/// It is only connected to ONE signal (the pipelines schema being changed), and emits numerous +/// which are connected to by both the different `Pipeline` objects in the extension, and by the +/// different pages of the extension preferences. +/// It emits three different types of signals: +/// +/// - general changes to the pipelines list, connected to by the extension preferences: +/// - `pipeline-list-changed`, when the list of pipelines has changed (by creation or deletion) +/// - `pipeline-names-changed`, when the name of a pipeline is changed +/// +/// - signals that are targeted towards a given pipeline, with `pipeline_id` being its unique id: +/// - `'pipeline_id'::pipeline-updated`, handing a new pipeline descriptor object, when the +/// pipeline has been changed quite a bit (added/destroyed/reordered the effects) +/// - `'pipeline_id'::pipeline-destroyed`, when the pipeline has been destroyed +/// - `'pipeline_id'::pipeline-renamed`, handing the new name, when the pipeline has been +/// renamed, which is only important for the preferences +/// +/// - signals that are targeted towards a given effect, with `effect_id` being its unique id, and +/// `pipeline_id` the unique id of the pipeline it is attached to: +/// - `'pipeline_id'::effect-'effect_id'-key-removed`, handing the key that was removed +/// - `'pipeline_id'::effect-'effect_id'-key-updated`, handing the key that was changed and its +/// new value +/// - `'pipeline_id'::effect-'effect_id'-key-added`, handing the key that was added and its +/// value +export class PipelinesManager { + constructor(settings) { + this.settings = settings; + this.pipelines = this.settings.PIPELINES; + this.settings.PIPELINES_changed(_ => this.on_pipeline_update()); + } + + create_pipeline(name, effects = []) { + // select a random id for the pipeline + let id = "pipeline_" + ("" + Math.random()).slice(2, 16); + // add a random ID for each effect, to help tracking them + effects.forEach(effect => effect.id = "effect_" + ("" + Math.random()).slice(2, 16)); + + this.pipelines[id] = { name, effects }; + this.settings.PIPELINES = this.pipelines; + this._emit('pipeline-created', id, this.pipelines[id]); + this._emit('pipeline-list-changed'); + return id; + } + + duplicate_pipeline(id) { + if (!(id in this.pipelines)) { + this._warn(`could not duplicate pipeline, id ${id} does not exist`); + return; + } + const pipeline = this.pipelines[id]; + this.create_pipeline(pipeline.name + " - duplicate", [...pipeline.effects]); + this.settings.PIPELINES = this.pipelines; + } + + delete_pipeline(id) { + if (!(id in this.pipelines)) { + this._warn(`could not delete pipeline, id ${id} does not exist`); + return; + } + if (id == "pipeline_default") { + this._warn(`could not delete pipeline "pipeline_default" as it is immutable`); + return; + } + delete this.pipelines[id]; + this.settings.PIPELINES = this.pipelines; + this._emit(id + '::pipeline-destroyed'); + this._emit('pipeline-list-changed'); + } + + update_pipeline_effects(id, effects, emit_update_signal = true) { + if (!(id in this.pipelines)) { + this._warn(`could not update pipeline effects, id ${id} does not exist`); + return; + } + this.pipelines[id].effects = [...effects]; + this.settings.PIPELINES = this.pipelines; + if (emit_update_signal) + this._emit(id + '::pipeline-updated'); + } + + rename_pipeline(id, name) { + if (!(id in this.pipelines)) { + this._warn(`could not rename pipeline, id ${id} does not exist`); + return; + } + this.pipelines[id].name = name.slice(); + this.settings.PIPELINES = this.pipelines; + this._emit(id + '::pipeline-renamed', name); + this._emit('pipeline-names-changed'); + } + + on_pipeline_update() { + const old_pipelines = this.pipelines; + this.pipelines = this.settings.PIPELINES; + + for (var pipeline_id in old_pipelines) { + // if we find a pipeline that does not exist anymore, signal it + if (!(pipeline_id in this.pipelines)) { + this._emit(pipeline_id + '::pipeline-destroyed'); + continue; + } + + const old_pipeline = old_pipelines[pipeline_id]; + const new_pipeline = this.pipelines[pipeline_id]; + + // verify if both pipelines have effects in the same order + // if they have, then check for their parameters + if ( + old_pipeline.effects.length == new_pipeline.effects.length && + old_pipeline.effects.every((effect, i) => effect.id === new_pipeline.effects[i].id) + ) { + for (let i = 0; i < old_pipeline.effects.length; i++) { + const old_effect = old_pipeline.effects[i]; + const new_effect = new_pipeline.effects[i]; + const id = old_effect.id; + for (let key in old_effect.params) { + // if a key was removed, we emit to tell the effect to use the default value + if (!(key in new_effect.params)) + this._emit( + pipeline_id + '::effect-' + id + '-key-removed', key + ); + // if a key was updated, we emit to tell the effect to change its value + else if (old_effect.params[key] != new_effect.params[key]) + this._emit( + pipeline_id + '::effect-' + id + '-key-updated', key, new_effect.params[key] + ); + } + for (let key in new_effect.params) { + // if a key was added, we emit to tell the effect the key and its value + if (!(key in old_effect.params)) + this._emit( + pipeline_id + '::effect-' + id + '-key-added', key, new_effect.params[key] + ); + } + } + } + // if either the order has changed, or there are new effects, then rebuild it + else + this._emit(pipeline_id + '::pipeline-updated', new_pipeline); + } + } + + destroy() { + this.settings.PIPELINES_disconnect(); + } + + _emit(signal, ...args) { + this.emit(signal, ...args); + this._log(`signal: '${signal}', arguments: ${args}`); + } + + _log(str) { + if (this.settings.DEBUG) + console.log(`[Blur my Shell > pipelines] ${str}`); + } + + _warn(str) { + console.warn(`[Blur my Shell > pipelines] ${str}`); + } +} + +Signals.addSignalMethods(PipelinesManager.prototype);
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings.js new file mode 100644 index 0000000..53f8497 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings.js @@ -0,0 +1,363 @@ +import GLib from 'gi://GLib'; +const Signals = imports.signals; + +/// An enum non-extensively describing the type of gsettings key. +export const Type = { + B: 'Boolean', + I: 'Integer', + D: 'Double', + S: 'String', + C: 'Color', + AS: 'StringArray', + PIPELINES: 'Pipelines' +}; + +/// An object to get and manage the gsettings preferences. +/// +/// Should be initialized with an array of keys, for example: +/// +/// let settings = new Settings([ +/// { type: Type.I, name: "panel-corner-radius" }, +/// { type: Type.B, name: "debug" } +/// ]); +/// +/// Each {type, name} object represents a gsettings key, which must be created +/// in the gschemas.xml file of the extension. +export const Settings = class Settings { + constructor(keys, settings) { + this.settings = settings; + this.keys = keys; + + this.keys.forEach(bundle => { + let component = this; + let component_settings = settings; + if (bundle.component !== "general") { + let bundle_component = bundle.component.replaceAll('-', '_'); + this[bundle_component] = { + settings: this.settings.get_child(bundle.component) + }; + component = this[bundle_component]; + component_settings = settings.get_child(bundle.component); + } + + + bundle.schemas.forEach(key => { + let property_name = this.get_property_name(key.name); + + switch (key.type) { + case Type.B: + Object.defineProperty(component, property_name, { + get() { + return component_settings.get_boolean(key.name); + }, + set(v) { + component_settings.set_boolean(key.name, v); + } + }); + break; + + case Type.I: + Object.defineProperty(component, property_name, { + get() { + return component_settings.get_int(key.name); + }, + set(v) { + component_settings.set_int(key.name, v); + } + }); + break; + + case Type.D: + Object.defineProperty(component, property_name, { + get() { + return component_settings.get_double(key.name); + }, + set(v) { + component_settings.set_double(key.name, v); + } + }); + break; + + case Type.S: + Object.defineProperty(component, property_name, { + get() { + return component_settings.get_string(key.name); + }, + set(v) { + component_settings.set_string(key.name, v); + } + }); + break; + + case Type.C: + Object.defineProperty(component, property_name, { + // returns the array [red, blue, green, alpha] with + // values between 0 and 1 + get() { + let val = component_settings.get_value(key.name); + return val.deep_unpack(); + }, + // takes an array [red, blue, green, alpha] with + // values between 0 and 1 + set(v) { + let val = new GLib.Variant("(dddd)", v); + component_settings.set_value(key.name, val); + } + }); + break; + + case Type.AS: + Object.defineProperty(component, property_name, { + get() { + let val = component_settings.get_value(key.name); + return val.deep_unpack(); + }, + set(v) { + let val = new GLib.Variant("as", v); + component_settings.set_value(key.name, val); + } + }); + break; + + case Type.PIPELINES: + Object.defineProperty(component, property_name, { + get() { + let pips = component_settings.get_value(key.name).deep_unpack(); + Object.keys(pips).forEach(pipeline_id => { + let pipeline = pips[pipeline_id]; + + if (!('name' in pipeline)) { + this._warn('impossible to get pipelines, pipeline has not name, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + let name = pipeline.name.deep_unpack(); + if (typeof name !== 'string') { + this._warn('impossible to get pipelines, pipeline name is not a string, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + + if (!('effects' in pipeline)) { + this._warn('impossible to get pipelines, pipeline has not effects, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + let effects = pipeline.effects.deep_unpack(); + if (!Array.isArray(effects)) { + this._warn('impossible to get pipelines, pipeline effects is not an array, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + + effects = effects.map(effect => effect.deep_unpack()); + effects.forEach(effect => { + if (!('type' in effect)) { + this._warn('impossible to get pipelines, effect has not type, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + let type = effect.type.deep_unpack(); + if (typeof type !== 'string') { + this._warn('impossible to get pipelines, effect type is not a string, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + + if (!('id' in effect)) { + this._warn('impossible to get pipelines, effect has not id, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + let id = effect.id.deep_unpack(); + if (typeof id !== 'string') { + this._warn('impossible to get pipelines, effect id is not a string, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + + let params = {}; + if ('params' in effect) + params = effect.params.deep_unpack(); + if (!(params && typeof params === 'object' && params.constructor === Object)) { + this._warn('impossible to get pipelines, effect params is not an object, resetting'); + component[property_name + '_reset'](); + return component[property_name]; + } + Object.keys(params).forEach(param_key => { + params[param_key] = params[param_key].deep_unpack(); + }); + + effect.type = type; + effect.id = id; + effect.params = params; + }); + pipeline.name = name; + pipeline.effects = effects; + }); + return pips; + }, + set(pips) { + let pipelines = {}; + Object.keys(pips).forEach(pipeline_id => { + let pipeline = pips[pipeline_id]; + if (!(pipeline && typeof pipeline === 'object' && pipeline.constructor === Object)) { + this._warn('impossible to set pipelines, pipeline is not an object'); + return; + } + + if (!('name' in pipeline)) { + this._warn('impossible to set pipelines, pipeline has no name'); + return; + } + if (typeof pipeline.name !== 'string') { + this._warn('impossible to set pipelines, pipeline name is not a string'); + return; + } + + if (!('effects' in pipeline)) { + this._warn('impossible to set pipelines, pipeline has no effect'); + return; + } + if (!Array.isArray(pipeline.effects)) { + this._warn('impossible to set pipelines, effects is not an array'); + return; + } + + let gvariant_effects = []; + pipeline.effects.forEach(effect => { + if (!(effect instanceof Object)) { + this._warn('impossible to set pipelines, effect is not an object'); + return; + } + + if (!('type' in effect)) { + this._warn('impossible to set pipelines, effect has not type'); + return; + } + if (typeof effect.type !== 'string') { + this._warn('impossible to set pipelines, effect type is not a string'); + return; + } + + if (!('id' in effect)) { + this._warn('impossible to set pipelines, effect has not id'); + return; + } + if (typeof effect.id !== 'string') { + this._warn('impossible to set pipelines, effect id is not a string'); + return; + } + + let params = {}; + if ('params' in effect) { + params = effect.params; + } + let gvariant_params = {}; + Object.keys(params).forEach(param_key => { + let param = params[param_key]; + if (typeof param === 'boolean') + gvariant_params[param_key] = GLib.Variant.new_boolean(param); + else if (typeof param === 'number') { + if (Number.isInteger(param)) + gvariant_params[param_key] = GLib.Variant.new_int32(param); + else + gvariant_params[param_key] = GLib.Variant.new_double(param); + } else if (typeof param === 'string') + gvariant_params[param_key] = GLib.Variant.new_string(param); + else if (Array.isArray(param) && param.length == 4) + gvariant_params[param_key] = new GLib.Variant("(dddd)", param); + else + this._warn('impossible to set pipeline, effect parameter type is unknown'); + }); + + gvariant_effects.push( + new GLib.Variant("a{sv}", { + type: GLib.Variant.new_string(effect.type), + id: GLib.Variant.new_string(effect.id), + params: new GLib.Variant("a{sv}", gvariant_params) + }) + ); + }); + + pipelines[pipeline_id] = { + name: GLib.Variant.new_string(pipeline.name), + effects: new GLib.Variant("av", gvariant_effects) + }; + }); + let val = new GLib.Variant("a{sa{sv}}", pipelines); + component_settings.set_value(key.name, val); + } + }); + break; + } + + + component[property_name + '_reset'] = function () { + return component_settings.reset(key.name); + }; + + component[property_name + '_signal_ids'] = []; + component[property_name + '_changed'] = function (cb) { + component[property_name + '_signal_ids'].push( + component_settings.connect('changed::' + key.name, cb) + ); + }; + + component[property_name + '_disconnect'] = function () { + component[property_name + '_signal_ids'].forEach( + id => component_settings.disconnect(id) + ); + component[property_name + '_signal_ids'] = []; + }; + }); + }); + }; + + /// Reset the preferences. + reset() { + this.keys.forEach(bundle => { + let component = this; + if (bundle.component !== "general") { + let bundle_component = bundle.component.replaceAll('-', '_'); + component = this[bundle_component]; + } + + bundle.schemas.forEach(key => { + let property_name = this.get_property_name(key.name); + component[property_name + '_reset'](); + }); + }); + + this.emit('reset', true); + } + + /// From the gschema name, returns the name of the associated property on + /// the Settings object. + get_property_name(name) { + return name.replaceAll('-', '_').toUpperCase(); + } + + /// Remove all connections managed by the Settings object, i.e. created with + /// `settings.PROPERTY_changed(callback)`. + disconnect_all_settings() { + this.keys.forEach(bundle => { + let component = this; + if (bundle.component !== "general") { + let bundle_component = bundle.component.replaceAll('-', '_'); + component = this[bundle_component]; + } + + bundle.schemas.forEach(key => { + let property_name = this.get_property_name(key.name); + component[property_name + '_disconnect'](); + }); + }); + } + + _warn(str) { + console.warn(`[Blur my Shell > settings] ${str}`); + } +}; + +Signals.addSignalMethods(Settings.prototype);
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings_updater.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings_updater.js new file mode 100644 index 0000000..2affbc1 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/settings_updater.js @@ -0,0 +1,40 @@ +import { Settings } from './settings.js'; +import { KEYS, DEPRECATED_KEYS } from './keys.js'; + +const CURRENT_SETTINGS_VERSION = 2; + +export function update_from_old_settings(gsettings) { + const preferences = new Settings(KEYS, gsettings); + const deprecated_preferences = new Settings(DEPRECATED_KEYS, gsettings); + const old_version = preferences.settings.get_int('settings-version'); + + if (old_version < CURRENT_SETTINGS_VERSION) { + // set artifacts hacks to be 1 at most, as it should be suitable now that most big bugs have + // been resolved (and especially because hack levels to 2 now means disabling clipped + // redraws entirely, which is very much not what we want for users that update) + if (preferences.HACKS_LEVEL > 1) + preferences.HACKS_LEVEL = 1; + + // enable dash-to-dock blurring, as most disabled it due to the lack of rounded corners; set + // it to static blur by default too and with transparent background + preferences.dash_to_dock.BLUR = true; + preferences.dash_to_dock.STATIC_BLUR = true; + preferences.dash_to_dock.STYLE_DASH_TO_DOCK = 0; + + // 'customize' has been removed: we merge the current used settings + ['appfolder', 'panel', 'dash_to_dock', 'applications', 'window_list'].forEach( + component_name => { + const deprecated_component = deprecated_preferences[component_name]; + const new_component = preferences[component_name]; + if (!deprecated_component.CUSTOMIZE) { + new_component.SIGMA = deprecated_preferences.SIGMA; + new_component.BRIGHTNESS = deprecated_preferences.BRIGHTNESS; + } + }); + + // remove old preferences in order not to clutter the gsettings + deprecated_preferences.reset(); + } + + preferences.settings.set_int('settings-version', CURRENT_SETTINGS_VERSION); +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js new file mode 100644 index 0000000..0277e0e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/conveniences/utils.js @@ -0,0 +1,38 @@ +import GLib from 'gi://GLib'; + +export const IS_IN_PREFERENCES = typeof global === 'undefined'; + +// Taken from https://github.com/Schneegans/Burn-My-Windows/blob/main/src/utils.js +// This method can be used to import a module in the GNOME Shell process only. This +// is useful if you want to use a module in extension.js, but not in the preferences +// process. This method returns null if it is called in the preferences process. +export async function import_in_shell_only(module) { + if (IS_IN_PREFERENCES) + return null; + return (await import(module)).default; +} + +// In use for the effects, to prevent boilerplate code +export function setup_params(outer_this, params) { + // setup each parameter, either with the given or the default value + for (const params_name in outer_this.constructor.default_params) { + outer_this["_" + params_name] = null; + outer_this[params_name] = params_name in params ? + params[params_name] : + outer_this.constructor.default_params[params_name]; + } +}; + +export const get_shader_source = (Shell, shader_filename, self_uri) => { + if (!Shell) + return; + const shader_path = GLib.filename_from_uri( + GLib.uri_resolve_relative(self_uri, shader_filename, GLib.UriFlags.NONE) + )[0]; + try { + return Shell.get_file_contents_utf8_sync(shader_path); + } catch (e) { + console.warn(`[Blur my Shell > effect] error loading shader from ${shader_path}: ${e}`); + return null; + } +};
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/client.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/client.js new file mode 100644 index 0000000..3867b3a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/client.js @@ -0,0 +1,58 @@ +import Gio from 'gi://Gio'; + +const bus_name = 'org.gnome.Shell'; +const iface_name = 'dev.aunetx.BlurMyShell'; +const obj_path = '/dev/aunetx/BlurMyShell'; + + +/// Call pick() from the DBus service, it will open the Inspector from +/// gnome-shell to pick an actor on stage. +export function pick() { + Gio.DBus.session.call( + bus_name, + obj_path, + iface_name, + 'pick', + null, + null, + Gio.DBusCallFlags.NO_AUTO_START, + -1, + null, + null + ); +} + +/// Connect to DBus 'picking' signal, which will be emitted when the inspector +/// is picking a window. +export function on_picking(cb) { + const id = Gio.DBus.session.signal_subscribe( + bus_name, + iface_name, + 'picking', + obj_path, + null, + Gio.DBusSignalFlags.NONE, + _ => { + cb(); + Gio.DBus.session.signal_unsubscribe(id); + } + ); +} + +/// Connect to DBus 'picked' signal, which will be emitted when a window is +/// picked. +export function on_picked(cb) { + const id = Gio.DBus.session.signal_subscribe( + bus_name, + iface_name, + 'picked', + obj_path, + null, + Gio.DBusSignalFlags.NONE, + (conn, sender, obj_path, iface, signal, params) => { + const val = params.get_child_value(0); + cb(val.get_string()[0]); + Gio.DBus.session.signal_unsubscribe(id); + } + ); +} diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/iface.xml b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/iface.xml new file mode 100644 index 0000000..4f298ad --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/iface.xml @@ -0,0 +1,12 @@ +<node> + <interface name="dev.aunetx.BlurMyShell"> + <!-- This method is called in preferences to pick a window --> + <method name="pick" /> + <!-- When window is picking, send a signal to preferences --> + <signal name="picking"></signal> + <!-- If window is picked, send a signal to preferences --> + <signal name="picked"> + <arg name="window" type="s" /> + </signal> + </interface> +</node>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/services.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/services.js new file mode 100644 index 0000000..4b1f4f0 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/dbus/services.js @@ -0,0 +1,93 @@ +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import * as LookingGlass from 'resource:///org/gnome/shell/ui/lookingGlass.js'; + + +export const ApplicationsService = class ApplicationsService { + constructor() { + let decoder = new TextDecoder(); + let path = GLib.filename_from_uri(GLib.uri_resolve_relative( + import.meta.url, 'iface.xml', GLib.UriFlags.NONE) + )[0]; + let [, buffer] = GLib.file_get_contents(path); + let iface = decoder.decode(buffer); + GLib.free(buffer); + + this.DBusImpl = Gio.DBusExportedObject.wrapJSObject(iface, this); + } + + /// Pick Window for Preferences Page, exported to DBus client. + pick() { + // emit `picking` signal to know we are listening + const send_picking_signal = _ => + this.DBusImpl.emit_signal( + 'picking', + null + ); + + // emit `picked` signal to send wm_class + const send_picked_signal = wm_class => + this.DBusImpl.emit_signal( + 'picked', + new GLib.Variant('(s)', [wm_class]) + ); + + // notify the preferences that we are listening + send_picking_signal(); + + // A very interesting way to pick a window: + // 1. Open LookingGlass to mask all event handles of window + // 2. Use inspector to pick window, thats is also lookingGlass do + // 3. Close LookingGlass when done + // It will restore event handles of window + + // open then hide LookingGlass + const looking_class = Main.createLookingGlass(); + looking_class.open(); + looking_class.hide(); + + // inspect window now + const inspector = new LookingGlass.Inspector(Main.createLookingGlass()); + inspector.connect('target', (me, target, x, y) => { + // remove border effect when window is picked. + const effect_name = 'lookingGlass_RedBorderEffect'; + target + .get_effects() + .filter(e => e.toString().includes(effect_name)) + .forEach(e => target.remove_effect(e)); + + // get wm_class_instance property of window, then pass it to DBus + // client + const type_str = target.toString(); + + let actor = target; + if (type_str.includes('MetaSurfaceActor')) + actor = target.get_parent(); + + if (!actor.toString().includes('WindowActor')) + actor = actor.get_parent(); + + if (!actor.toString().includes('WindowActor')) + return send_picked_signal('window-not-found'); + + send_picked_signal( + actor.meta_window.get_wm_class() ?? 'window-not-found' + ); + }); + + // close LookingGlass when we're done + inspector.connect('closed', _ => looking_class.close()); + } + + export() { + this.DBusImpl.export( + Gio.DBus.session, + '/dev/aunetx/BlurMyShell' + ); + }; + + unexport() { + this.DBusImpl.unexport(); + } +}; diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl new file mode 100644 index 0000000..5df6512 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.glsl @@ -0,0 +1,111 @@ +uniform sampler2D tex; +uniform float red; +uniform float green; +uniform float blue; +uniform float blend; +uniform int mode; + +const int NORMAL = 0; +const int MULTIPLY = 1; +const int SCREEN = 2; +const int OVERLAY = 3; +const int DARKEN = 4; +const int LIGHTEN = 5; +const int PLUS_DARKER = 6; +const int PLUS_LIGHTER = 7; +const int COLOR_DODGE = 8; +const int COLOR_BURN = 9; +const int HARD_LIGHT = 10; +const int SOFT_LIGHT = 11; +const int DIFFERENCE = 12; +const int EXCLUSION = 13; +const int HUE = 14; +const int SATURATION = 15; +const int COLOR = 16; +const int LUMINOSITY = 17; + +vec3 rgb_to_hsl(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsl_to_rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +float soft_light_channel(float base, float _blend) { + if (_blend < 0.5) { + return base - (1.0 - 2.0 * _blend) * base * (1.0 - base); + } else { + float d = (base < 0.25) + ? ((16.0 * base - 12.0) * base + 4.0) * base + : sqrt(base); + return base + (2.0 * _blend - 1.0) * (d - base); + } +} + +vec3 get_blend(vec3 base, vec3 _blend) { + if (mode == MULTIPLY) return base * _blend; + if (mode == SCREEN) return 1 - (1 - base) * (1 - _blend); + if (mode == OVERLAY) { + vec3 result; + result.r = base.r < 0.5 ? (2.0 * base.r * _blend.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - _blend.r)); + result.g = base.g < 0.5 ? (2.0 * base.g * _blend.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - _blend.g)); + result.b = base.b < 0.5 ? (2.0 * base.b * _blend.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - _blend.b)); + return result; + } + if (mode == DARKEN) return min(base, _blend); + if (mode == LIGHTEN) return max(base, _blend); + if (mode == PLUS_DARKER) return base + _blend - 1; + if (mode == PLUS_LIGHTER) return base + _blend; + if (mode == COLOR_DODGE) return base / (1 - _blend); + if (mode == COLOR_BURN) return 1 - (1 - base) / _blend; + if (mode == HARD_LIGHT) { + vec3 result; + result.r = _blend.r < 0.5 ? (2.0 * base.r * _blend.r) : (1.0 - 2.0 * (1.0 - base.r) * (1.0 - _blend.r)); + result.g = _blend.g < 0.5 ? (2.0 * base.g * _blend.g) : (1.0 - 2.0 * (1.0 - base.g) * (1.0 - _blend.g)); + result.b = _blend.b < 0.5 ? (2.0 * base.b * _blend.b) : (1.0 - 2.0 * (1.0 - base.b) * (1.0 - _blend.b)); + return result; + } + if (mode == SOFT_LIGHT) { + return vec3(soft_light_channel(base.r, _blend.r), soft_light_channel(base.g, _blend.g), soft_light_channel(base.b, _blend.b)); + } + if (mode == DIFFERENCE) return abs(base - _blend); + if (mode == EXCLUSION) return 0.5 - 2 * (base - 0.5) * (_blend - 0.5); + if (mode == HUE) { + vec3 base_hsl = rgb_to_hsl(base); + vec3 blend_hsl = rgb_to_hsl(_blend); + return hsl_to_rgb(vec3(blend_hsl.x, base_hsl.y, base_hsl.z)); + } + if (mode == SATURATION) { + vec3 base_hsl = rgb_to_hsl(base); + vec3 blend_hsl = rgb_to_hsl(_blend); + return hsl_to_rgb(vec3(base_hsl.x, blend_hsl.y, base_hsl.z)); + } + if (mode == COLOR) { + vec3 base_hsl = rgb_to_hsl(base); + vec3 blend_hsl = rgb_to_hsl(_blend); + return hsl_to_rgb(vec3(blend_hsl.x, blend_hsl.y, base_hsl.z)); + } + if (mode == LUMINOSITY) { + vec3 base_hsl = rgb_to_hsl(base); + vec3 blend_hsl = rgb_to_hsl(_blend); + return hsl_to_rgb(vec3(base_hsl.x, base_hsl.y, blend_hsl.z)); + } + return _blend; // For NORMAL +} + +void main() { + vec4 c = texture2D(tex, cogl_tex_coord_in[0].st); + vec3 pix_color = c.xyz; + vec3 color = get_blend(pix_color, vec3(red, green, blue)); + + cogl_color_out = vec4(mix(pix_color, color, blend), 1.); +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js new file mode 100644 index 0000000..1f4bdf4 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/color.js @@ -0,0 +1,168 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; + +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'color.glsl'; +const DEFAULT_PARAMS = { + color: [0.0, 0.0, 0.0, 0.0], + blend_mode: 0 +}; + + +export const ColorEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "ColorEffect", + Properties: { + 'red': GObject.ParamSpec.double( + `red`, + `Red`, + `Red value in shader`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.0, + ), + 'green': GObject.ParamSpec.double( + `green`, + `Green`, + `Green value in shader`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.0, + ), + 'blue': GObject.ParamSpec.double( + `blue`, + `Blue`, + `Blue value in shader`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.0, + ), + 'blend': GObject.ParamSpec.double( + `blend`, + `Blend`, + `Amount of blending between the colors`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.0, + ), + 'blend_mode': GObject.ParamSpec.int( + `blend_mode`, + `Blend mode`, + `Blend mode`, + GObject.ParamFlags.READWRITE, + 0, 17, + 0, + ) + } + // Normal (0), Multiply (1), Screen (2), Overlay (3), Darken (4), Lighten (5), Plus darker (6), Plus lighter (7), Color dodge (8), + // Color burn (9), Hard light (10), Soft light (11), Difference (12), Exclusion (13), Hue (14), Saturation (15), Color (16), + // Luminosity (17) + }, class ColorEffect extends Clutter.ShaderEffect { + constructor(params) { + // initialize without color as a parameter + const { color, ...parent_params } = params; + super(parent_params); + + this._red = null; + this._green = null; + this._blue = null; + this._blend = null; + this._blend_mode = null; + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + + // set params; utils.setup_params doesn't work here with color + this.color = 'color' in params ? color : this.constructor.default_params.color; + this.blend_mode = 'blend_mode' in params ? params.blend_mode : this.constructor.default_params.blend_mode; + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get red() { + return this._red; + } + + set red(value) { + if (this._red !== value) { + this._red = value; + + this.set_uniform_value('red', parseFloat(this._red - 1e-6)); + } + } + + get green() { + return this._green; + } + + set green(value) { + if (this._green !== value) { + this._green = value; + + this.set_uniform_value('green', parseFloat(this._green - 1e-6)); + } + } + + get blue() { + return this._blue; + } + + set blue(value) { + if (this._blue !== value) { + this._blue = value; + + this.set_uniform_value('blue', parseFloat(this._blue - 1e-6)); + } + } + + get blend() { + return this._blend; + } + + set blend(value) { + if (this._blend !== value) { + this._blend = value; + + this.set_uniform_value('blend', parseFloat(this._blend - 1e-6)); + this.set_enabled(this.blend > 0); + } + } + + get blend_mode() { + return this._blend_mode; + } + + set blend_mode(value) { + if (this._blend_mode !== value) { + this._blend_mode = value; + + this.set_uniform_value('mode', this._blend_mode); + } + } + + set color(rgba) { + let [r, g, b, a] = rgba; + this.red = r; + this.green = g; + this.blue = b; + this.blend = a; + } + + get color() { + return [this.red, this.green, this.blue, this.blend]; + } + + /// False set function, only cares about the color. Too hard to change. + set(params) { + this.color = params.color; + this.blend_mode = params.blend_mode; + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl new file mode 100644 index 0000000..760798a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.glsl @@ -0,0 +1,93 @@ +// Heavily based on https://github.com/yilozt/rounded-window-corners +// which is itself based on upstream Mutter code + +uniform sampler2D tex; +uniform float radius; +uniform float width; +uniform float height; +uniform bool corners_top; +uniform bool corners_bottom; + +uniform float clip_x0; +uniform float clip_y0; +uniform float clip_width; +uniform float clip_height; + +float circle_bounds(vec2 p, vec2 center, float clip_radius) { + vec2 delta = p - center; + float dist_squared = dot(delta, delta); + + float outer_radius = clip_radius + 0.5; + if (dist_squared >= (outer_radius * outer_radius)) + return 0.0; + + float inner_radius = clip_radius - 0.5; + if (dist_squared <= (inner_radius * inner_radius)) + return 1.0; + + return outer_radius - sqrt(dist_squared); +} + +vec4 getTexture(vec2 uv) { + if (uv.x < 2. / width) + uv.x = 2. / width; + + if (uv.y < 2. / height) + uv.y = 2. / height; + + if (uv.x > 1. - 3. / width) + uv.x = 1. - 3. / width; + + if (uv.y > 1. - 3. / height) + uv.y = 1. - 3. / height; + + return texture2D(tex, uv); +} + +float rounded_rect_coverage(vec2 p, vec4 bounds, float clip_radius) { + // Outside the bounds + if (p.x < bounds.x || p.x > bounds.z || p.y < bounds.y || p.y > bounds.w) { + return 0.; + } + + vec2 center; + + float center_left = bounds.x + clip_radius; + float center_right = bounds.z - clip_radius; + + if (p.x < center_left) + center.x = center_left + 2.; + else if (p.x > center_right) + center.x = center_right - 1.; + else + return 1.0; + + float center_top = bounds.y + clip_radius; + float center_bottom = bounds.w - clip_radius; + + if (corners_top && p.y < center_top) + center.y = center_top + 2.; + else if (corners_bottom && p.y > center_bottom) + center.y = center_bottom - 1.; + else + return 1.0; + + return circle_bounds(p, center, clip_radius); +} + +void main(void) { + vec2 uv = cogl_tex_coord_in[0].xy; + vec2 pos = uv * vec2(width, height); + vec4 c = getTexture(uv); + + vec4 bounds; + if (clip_width < 0. || clip_height < 0.) { + bounds = vec4(clip_x0, clip_y0, clip_x0 + width, clip_y0 + height); + } else { + bounds = vec4(clip_x0, clip_y0, clip_x0 + clip_width, clip_y0 + clip_height); + } + + float alpha = rounded_rect_coverage(pos, bounds, radius); + + cogl_color_out = vec4(c.rgb * alpha, min(alpha, c.a)); +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js new file mode 100644 index 0000000..109be12 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/corner.js @@ -0,0 +1,211 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const St = await utils.import_in_shell_only('gi://St'); +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'corner.glsl'; +const DEFAULT_PARAMS = { + radius: 12, width: 0, height: 0, + corners_top: true, corners_bottom: true, + clip: [0, 0, -1, -1] +}; + + +export const CornerEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "CornerEffect", + Properties: { + 'radius': GObject.ParamSpec.double( + `radius`, + `Corner Radius`, + `Corner Radius`, + GObject.ParamFlags.READWRITE, + 0, Number.MAX_SAFE_INTEGER, + 12, + ), + 'width': GObject.ParamSpec.double( + `width`, + `Width`, + `Width`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'height': GObject.ParamSpec.double( + `height`, + `Height`, + `Height`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'corners_top': GObject.ParamSpec.boolean( + `corners_top`, + `Round top corners`, + `Round top corners`, + GObject.ParamFlags.READWRITE, + true, + ), + 'corners_bottom': GObject.ParamSpec.boolean( + `corners_bottom`, + `Round bottom corners`, + `Round bottom corners`, + GObject.ParamFlags.READWRITE, + true, + ), + // FIXME this works but it logs an error, because I'm not a double... + // I don't want to fiddle with GVariants again + 'clip': GObject.ParamSpec.double( + `clip`, + `Clip`, + `Clip`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + } + }, class CornerEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + this._clip_x0 = null; + this._clip_y0 = null; + this._clip_width = null; + this._clip_height = null; + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + + const theme_context = St.ThemeContext.get_for_stage(global.stage); + theme_context.connectObject('notify::scale-factor', _ => this.update_radius(), this); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get radius() { + return this._radius; + } + + set radius(value) { + if (this._radius !== value) { + this._radius = value; + + this.update_radius(); + } + } + + update_radius() { + const theme_context = St.ThemeContext.get_for_stage(global.stage); + let radius = Math.min( + this.radius * theme_context.scale_factor, + this.width / 2, this.height / 2 + ); + if (this._clip_width >= 0 || this._clip_height >= 0) + radius = Math.min(radius, this._clip_width / 2, this._clip_height / 2); + + this.set_uniform_value('radius', parseFloat(radius - 1e-6)); + } + + get width() { + return this._width; + } + + set width(value) { + if (this._width !== value) { + this._width = value; + + this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6)); + this.update_radius(); + } + } + + get height() { + return this._height; + } + + set height(value) { + if (this._height !== value) { + this._height = value; + + this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6)); + this.update_radius(); + } + } + + get corners_top() { + return this._corners_top; + } + + set corners_top(value) { + if (this._corners_top !== value) { + this._corners_top = value; + + this.set_uniform_value('corners_top', this._corners_top ? 1 : 0); + } + } + + get corners_bottom() { + return this._corners_bottom; + } + + set corners_bottom(value) { + if (this._corners_bottom !== value) { + this._corners_bottom = value; + + this.set_uniform_value('corners_bottom', this._corners_bottom ? 1 : 0); + } + } + + get clip() { + return [this._clip_x0, this._clip_y0, this._clip_width, this._clip_height]; + } + + set clip(value) { + [this._clip_x0, this._clip_y0, this._clip_width, this._clip_height] = value; + this.set_uniform_value('clip_x0', parseFloat(this._clip_x0 - 1e-6)); + this.set_uniform_value('clip_y0', parseFloat(this._clip_y0 - 1e-6)); + this.set_uniform_value('clip_width', parseFloat(this._clip_width + 3 - 1e-6)); + this.set_uniform_value('clip_height', parseFloat(this._clip_height + 3 - 1e-6)); + this.update_radius(); + } + + vfunc_set_actor(actor) { + if (this._actor_connection_size_id) { + let old_actor = this.get_actor(); + old_actor?.disconnect(this._actor_connection_size_id); + } + if (this._actor_connection_clip_rect_id) { + let old_actor = this.get_actor(); + old_actor?.disconnect(this._actor_connection_clip_rect_id); + } + + if (actor) { + this.width = actor.width; + this.height = actor.height; + this._actor_connection_size_id = actor.connect('notify::size', _ => { + this.width = actor.width; + this.height = actor.height; + }); + + this.clip = actor.has_clip ? actor.get_clip() : [0, 0, -10, -10]; + this._actor_connection_clip_rect_id = actor.connect('notify::clip-rect', _ => { + this.clip = actor.has_clip ? actor.get_clip() : [0, 0, -10, -10]; + }); + } + else { + this._actor_connection_size_id = null; + this._actor_connection_clip_rect_id = null; + } + + super.vfunc_set_actor(actor); + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl new file mode 100644 index 0000000..64c1682 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.glsl @@ -0,0 +1,71 @@ +uniform sampler2D tex; +uniform int operation; +uniform float width; +uniform float height; + +#define CORRECTION 2.25 +#define SIZE_ADDITION 3 + +vec4 get_texture_at_position(vec2 position) { + vec2 raw_position = position + vec2(CORRECTION, CORRECTION); + vec2 raw_uv = raw_position / vec2(width + SIZE_ADDITION, height + SIZE_ADDITION); + + return texture2D(tex, raw_uv); +} + +vec4 try_get_texture_at_position(vec2 position, inout int count) { + if (any(greaterThanEqual(position, vec2(width, height))) || + any(lessThan(position, vec2(0, 0)))) { + return vec4(0); + } else { + count++; + return get_texture_at_position(position); + } +} + +ivec2 get_corrected_position() { + vec2 raw_uv = cogl_tex_coord0_in.st; + vec2 raw_position = raw_uv * vec2(width + SIZE_ADDITION, height + SIZE_ADDITION); + return ivec2(raw_position - vec2(CORRECTION, CORRECTION)); +} + +void main() { + ivec2 corrected_position = get_corrected_position(); + + // 1-step derivative + if (operation == 0) { + vec4 color = vec4(0); + int c = 0; + color += try_get_texture_at_position(corrected_position + vec2(0, 1), c); + color -= try_get_texture_at_position(corrected_position + vec2(0, 0), c); + color += try_get_texture_at_position(corrected_position + vec2(1, 0), c); + color -= try_get_texture_at_position(corrected_position + vec2(0, 0), c); + if (c < 4) { + color = vec4(0); + } + cogl_color_out = vec4(color.xyz, 1); + } else + // 2-step derivative + if (operation == 1) { + vec4 color = vec4(0); + int c = 0; + color += try_get_texture_at_position(corrected_position + vec2(0, 1), c); + color -= try_get_texture_at_position(corrected_position + vec2(0, -1), c); + color += try_get_texture_at_position(corrected_position + vec2(1, 0), c); + color -= try_get_texture_at_position(corrected_position + vec2(-1, 0), c); + if (c < 4) { + color = vec4(0); + } + cogl_color_out = vec4(color.xyz / 2, 1); + } else + // laplacian + if (operation == 2) { + vec4 color = vec4(0); + color = -4 * get_texture_at_position(corrected_position); + color += get_texture_at_position(corrected_position + vec2(0, 1)); + color += get_texture_at_position(corrected_position + vec2(0, -1)); + color += get_texture_at_position(corrected_position + vec2(1, 0)); + color += get_texture_at_position(corrected_position + vec2(-1, 0)); + cogl_color_out = vec4(color.xyz, 1); + } +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js new file mode 100644 index 0000000..04d6100 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/derivative.js @@ -0,0 +1,120 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'derivative.glsl'; +const DEFAULT_PARAMS = { + operation: 0, width: 0, height: 0 +}; + + +export const DerivativeEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "DerivativeEffect", + Properties: { + 'operation': GObject.ParamSpec.int( + `operation`, + `Operation`, + `Operation`, + GObject.ParamFlags.READWRITE, + 0, 2, + 0, + ), + 'width': GObject.ParamSpec.double( + `width`, + `Width`, + `Width`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'height': GObject.ParamSpec.double( + `height`, + `Height`, + `Height`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ) + } + }, class DerivativeEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get operation() { + return this._operation; + } + + set operation(value) { + if (this._operation !== value) { + this._operation = value; + + this.set_uniform_value('operation', this._operation); + } + } + + get width() { + return this._width; + } + + set width(value) { + if (this._width !== value) { + this._width = value; + + this.set_uniform_value('width', parseFloat(this._width - 1e-6)); + } + } + + get height() { + return this._height; + } + + set height(value) { + if (this._height !== value) { + this._height = value; + + this.set_uniform_value('height', parseFloat(this._height - 1e-6)); + } + } + + vfunc_set_actor(actor) { + if (this._actor_connection_size_id) { + let old_actor = this.get_actor(); + old_actor?.disconnect(this._actor_connection_size_id); + } + if (actor) { + this.width = actor.width; + this.height = actor.height; + this._actor_connection_size_id = actor.connect('notify::size', _ => { + this.width = actor.width; + this.height = actor.height; + }); + } + else + this._actor_connection_size_id = null; + + super.vfunc_set_actor(actor); + } + + vfunc_paint_target(paint_node, paint_context) { + // force setting nearest-neighbour texture filtering + this.get_pipeline().set_layer_filters(0, 9728, 9728); + + super.vfunc_paint_target(paint_node, paint_context); + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl new file mode 100644 index 0000000..9871268 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.glsl @@ -0,0 +1,76 @@ +uniform sampler2D tex; +uniform int divider; +uniform float width; +uniform float height; +uniform int downsampling_mode; + +#define CORRECTION 2.25 +#define SIZE_ADDITION 3 + +vec4 get_texture_at_position(vec2 position) { + vec2 raw_position = position + vec2(CORRECTION, CORRECTION); + vec2 raw_uv = raw_position / vec2(width + SIZE_ADDITION, height + SIZE_ADDITION); + + return texture2D(tex, raw_uv); +} + +vec2 get_corrected_position() { + vec2 raw_uv = cogl_tex_coord0_in.st; + vec2 raw_position = raw_uv * vec2(width + SIZE_ADDITION, height + SIZE_ADDITION); + return raw_position - vec2(CORRECTION, CORRECTION); +} + +void main() { + ivec2 corrected_position = ivec2(get_corrected_position()); + vec2 multiplied_position = corrected_position * divider; + + if (any(greaterThan(multiplied_position, vec2(width, height)))) { + discard; + } + + // mode 0: boxcar downsampling + if (downsampling_mode == 0) { + + vec4 color = vec4(0.); + int count = 0; + for (int i = 0; i < divider; i++) { + for (int j = 0; j < divider; j++) { + vec2 lookup_position = multiplied_position + vec2(i, j); + if (all(greaterThanEqual(lookup_position, vec2(0, 0))) && + all(lessThan(lookup_position, vec2(width, height)))) { + color += get_texture_at_position(lookup_position); + count += 1; + } + } + } + cogl_color_out = color / count; + + } else + // mode 1: triangular downsampling + if (downsampling_mode == 1) { + + vec4 color = vec4(0.); + int count = 0; + int force = 1; + for (int i = 0; i < divider; i++) { + for (int j = 0; j < divider; j++) { + vec2 lookup_position = multiplied_position + vec2(i, j); + if (all(greaterThanEqual(lookup_position, vec2(0, 0))) && + all(lessThan(lookup_position, vec2(width, height)))) { + force = 1 + divider - int(abs(divider - i - j)); + color += get_texture_at_position(lookup_position) * force; + count += force; + } + } + } + cogl_color_out = color / count; + + } else + // mode 2: Dirac downsampling + if (downsampling_mode == 2) { + + vec2 lookup_position = min(multiplied_position + vec2(divider, divider) / 2, vec2(width - 1, height - 1)); + cogl_color_out = get_texture_at_position(lookup_position); + + } +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js new file mode 100644 index 0000000..8103486 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/downscale.js @@ -0,0 +1,140 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'downscale.glsl'; +const DEFAULT_PARAMS = { + divider: 8, downsampling_mode: 0, width: 0, height: 0 +}; + + +export const DownscaleEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "DownscaleEffect", + Properties: { + 'divider': GObject.ParamSpec.int( + `divider`, + `Divider`, + `Divider`, + GObject.ParamFlags.READWRITE, + 0, 64, + 8, + ), + 'downsampling_mode': GObject.ParamSpec.int( + `downsampling_mode`, + `Downsampling mode`, + `Downsampling mode`, + GObject.ParamFlags.READWRITE, + 0, 2, + 0, + ), + 'width': GObject.ParamSpec.double( + `width`, + `Width`, + `Width`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'height': GObject.ParamSpec.double( + `height`, + `Height`, + `Height`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ) + } + }, class DownscaleEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get divider() { + return this._divider; + } + + set divider(value) { + if (this._divider !== value) { + this._divider = value; + + this.set_uniform_value('divider', this._divider); + } + } + + get downsampling_mode() { + return this._downsampling_mode; + } + + set downsampling_mode(value) { + if (this._downsampling_mode !== value) { + this._downsampling_mode = value; + + this.set_uniform_value('downsampling_mode', this._downsampling_mode); + } + } + + get width() { + return this._width; + } + + set width(value) { + if (this._width !== value) { + this._width = value; + + this.set_uniform_value('width', parseFloat(this._width - 1e-6)); + } + } + + get height() { + return this._height; + } + + set height(value) { + if (this._height !== value) { + this._height = value; + + this.set_uniform_value('height', parseFloat(this._height - 1e-6)); + } + } + + vfunc_set_actor(actor) { + if (this._actor_connection_size_id) { + let old_actor = this.get_actor(); + old_actor?.disconnect(this._actor_connection_size_id); + } + if (actor) { + this.width = actor.width; + this.height = actor.height; + this._actor_connection_size_id = actor.connect('notify::size', _ => { + this.width = actor.width; + this.height = actor.height; + }); + } + else + this._actor_connection_size_id = null; + + super.vfunc_set_actor(actor); + } + + vfunc_paint_target(paint_node, paint_context) { + // force setting nearest-neighbour texture filtering + this.get_pipeline().set_layer_filters(0, 9728, 9728); + + super.vfunc_paint_target(paint_node, paint_context); + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js new file mode 100644 index 0000000..e35588d --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/effects.js @@ -0,0 +1,362 @@ +import { NativeDynamicBlurEffect } from '../effects/native_dynamic_gaussian_blur.js'; +import { NativeStaticBlurEffect } from '../effects/native_static_gaussian_blur.js'; +import { GaussianBlurEffect } from '../effects/gaussian_blur.js'; +import { MonteCarloBlurEffect } from '../effects/monte_carlo_blur.js'; +import { ColorEffect } from '../effects/color.js'; +import { NoiseEffect } from '../effects/noise.js'; +import { CornerEffect } from '../effects/corner.js'; +import { DownscaleEffect } from './downscale.js'; +import { UpscaleEffect } from './upscale.js'; +import { PixelizeEffect } from './pixelize.js'; +import { DerivativeEffect } from './derivative.js'; +import { RgbToHslEffect } from './rgb_to_hsl.js'; +import { HslToRgbEffect } from './hsl_to_rgb.js'; + +// We do in this way because I've not found another way to store our preferences in a dictionnary +// while calling `gettext` on it while in preferences. Not so pretty, but works. +export function get_effects_groups(_ = _ => "") { + return { + blur_effects: { + name: _("Blur effects"), + contains: [ + "native_static_gaussian_blur", + "gaussian_blur", + "monte_carlo_blur" + ] + }, + texture_effects: { + name: _("Texture effects"), + contains: [ + "downscale", + "upscale", + "pixelize", + "derivative", + "noise", + "color", + "rgb_to_hsl", + "hsl_to_rgb" + ] + }, + shape_effects: { + name: _("Shape effects"), + contains: [ + "corner" + ] + } + }; +}; + +export function get_supported_effects(_ = () => "") { + return { + native_dynamic_gaussian_blur: { + class: NativeDynamicBlurEffect + }, + + native_static_gaussian_blur: { + class: NativeStaticBlurEffect, + name: _("Native gaussian blur"), + description: _("An optimized blur effect that smoothly blends pixels within a given radius."), + is_advanced: false, + editable_params: { + unscaled_radius: { + name: _("Radius"), + description: _("The intensity of the blur effect."), + type: "float", + min: 0., + max: 100., + increment: 1.0, + big_increment: 10., + digits: 0 + }, + brightness: { + name: _("Brightness"), + description: _("The brightness of the blur effect, a high value might make the text harder to read."), + type: "float", + min: 0., + max: 1., + increment: 0.01, + big_increment: 0.1, + digits: 2 + }, + } + }, + + gaussian_blur: { + class: GaussianBlurEffect, + name: _("Gaussian blur (advanced effect)"), + description: _("A blur effect that smoothly blends pixels within a given radius. This effect is more precise, but way less optimized."), + is_advanced: true, + editable_params: { + radius: { + name: _("Radius"), + description: _("The intensity of the blur effect. The bigger it is, the slower it will be."), + type: "float", + min: 0., + max: 100., + increment: .1, + big_increment: 10., + digits: 1 + }, + brightness: { + name: _("Brightness"), + description: _("The brightness of the blur effect, a high value might make the text harder to read."), + type: "float", + min: 0., + max: 1., + increment: 0.01, + big_increment: 0.1, + digits: 2 + }, + } + }, + + monte_carlo_blur: { + class: MonteCarloBlurEffect, + name: _("Monte Carlo blur"), + description: _("A blur effect that mimics a random walk, by picking pixels further and further away from its origin and mixing them all together."), + is_advanced: false, + editable_params: { + radius: { + name: _("Radius"), + description: _("The maximum travel distance for each step in the random walk. A higher value will make the blur more randomized."), + type: "float", + min: 0., + max: 10., + increment: 0.01, + big_increment: 0.1, + digits: 2 + }, + iterations: { + name: _("Iterations"), + description: _("The number of iterations. The more there are, the smoother the blur is."), + type: "integer", + min: 0, + max: 50, + increment: 1 + }, + brightness: { + name: _("Brightness"), + description: _("The brightness of the blur effect, a high value might make the text harder to read."), + type: "float", + min: 0., + max: 1., + increment: 0.01, + big_increment: 0.1, + digits: 2 + }, + use_base_pixel: { + name: _("Use base pixel"), + description: _("Whether or not the original pixel is counted for the blur. If it is, the image will be more legible."), + type: "boolean" + }, + prefer_closer_pixels: { + name: _("Prefer closer pixels"), + description: _("Whether or not the pixels that are closer to the original pixel will have more weight."), + type: "boolean" + } + } + }, + + color: { + class: ColorEffect, + name: _("Color"), + description: _("An effect that blends a color into the pipeline."), + is_advanced: false, + // TODO make this RGB + blend + editable_params: { + color: { + name: _("Color"), + description: _("The color to blend in. The blending amount is controled by the opacity of the color."), + type: "rgba" + }, + blend_mode: { + name: _("Blend mode"), + description: _("How the color is blended in."), + type: "dropdown", + options: [ + _("Normal"), + _("Multiply"), + _("Screen"), + _("Overlay"), + _("Darken"), + _("Lighten"), + _("Plus darker"), + _("Plus lighter"), + _("Color dodge"), + _("Color burn"), + _("Hard light"), + _("Soft light"), + _("Difference"), + _("Exclusion"), + _("Hue"), + _("Saturation"), + _("Color"), + _("Luminosity") + ] + } + } + }, + + pixelize: { + class: PixelizeEffect, + name: _("Pixelize"), + description: _("An effect that pixelizes the image."), + is_advanced: false, + editable_params: { + factor: { + name: _("Factor"), + description: _("How much to scale down the image."), + type: "integer", + min: 1, + max: 50, + increment: 1 + }, + downsampling_mode: { + name: _("Downsampling mode"), + description: _("The downsampling method that is used."), + type: "dropdown", + options: [ + _("Boxcar"), + _("Triangular"), + _("Dirac") + ] + } + } + }, + + downscale: { + class: DownscaleEffect, + name: _("Downscale (advanced effect)"), + description: _("An effect that downscales the image and put it on the top-left corner."), + is_advanced: true, + editable_params: { + divider: { + name: _("Factor"), + description: _("How much to scale down the image."), + type: "integer", + min: 1, + max: 50, + increment: 1 + }, + downsampling_mode: { + name: _("Downsampling mode"), + description: _("The downsampling method that is used."), + type: "dropdown", + options: [ + _("Boxcar"), + _("Triangular"), + _("Dirac") + ] + } + } + }, + + upscale: { + class: UpscaleEffect, + name: _("Upscale (advanced effect)"), + description: _("An effect that upscales the image from the top-left corner."), + is_advanced: true, + editable_params: { + factor: { + name: _("Factor"), + description: _("How much to scale up the image."), + type: "integer", + min: 1, + max: 50, + increment: 1 + } + } + }, + + derivative: { + class: DerivativeEffect, + name: _("Derivative"), + description: _("Apply a spatial derivative, or a laplacian."), + is_advanced: false, + editable_params: { + operation: { + name: _("Operation"), + description: _("The mathematical operation to apply."), + type: "dropdown", + options: [ + _("1-step derivative"), + _("2-step derivative"), + _("Laplacian") + ] + } + } + }, + + noise: { + class: NoiseEffect, + name: _("Noise"), + description: _("An effect that adds a random noise. Prefer the Monte Carlo blur for a more organic effect if needed."), + is_advanced: false, + editable_params: { + noise: { + name: _("Noise"), + description: _("The amount of noise to add."), + type: "float", + min: 0., + max: 1., + increment: 0.01, + big_increment: 0.1, + digits: 2 + }, + lightness: { + name: _("Lightness"), + description: _("The luminosity of the noise. A setting of '1.0' will make the effect transparent."), + type: "float", + min: 0., + max: 2., + increment: 0.01, + big_increment: 0.1, + digits: 2 + } + } + }, + + rgb_to_hsl: { + class: RgbToHslEffect, + name: _("RGB to HSL (advanced effect)"), + description: _("Converts the image from RGBA colorspace to HSLA."), + is_advanced: true, + editable_params: {} + }, + + hsl_to_rgb: { + class: HslToRgbEffect, + name: _("HSL to RGB (advanced effect)"), + description: _("Converts the image from HSLA colorspace to RGBA."), + is_advanced: true, + editable_params: {} + }, + + corner: { + class: CornerEffect, + name: _("Corner"), + description: _("An effect that draws corners. Add it last not to have the other effects perturb the corners."), + is_advanced: false, + editable_params: { + radius: { + name: _("Radius"), + description: _("The radius of the corner. GNOME apps use a radius of 12 px by default."), + type: "integer", + min: 0, + max: 50, + increment: 1, + }, + corners_top: { + name: _("Top corners"), + description: _("Whether or not to round the top corners."), + type: "boolean" + }, + corners_bottom: { + name: _("Bottom corners"), + description: _("Whether or not to round the bottom corners."), + type: "boolean" + } + } + } + }; +};
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl new file mode 100644 index 0000000..809cc93 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.glsl @@ -0,0 +1,70 @@ +uniform sampler2D tex; +uniform float sigma; +uniform int dir; +uniform float brightness; +uniform float width; +uniform float height; + +vec4 getTexture(vec2 uv) { + if (uv.x < 3. / width) + uv.x = 3. / width; + + if (uv.y < 3. / height) + uv.y = 3. / height; + + if (uv.x > 1. - 3. / width) + uv.x = 1. - 3. / width; + + if (uv.y > 1. - 3. / height) + uv.y = 1. - 3. / height; + + return texture2D(tex, uv); +} + +void main(void) { + vec2 uv = cogl_tex_coord_in[0].xy; + vec2 direction = vec2(dir, (1.0 - dir)); + + float pixel_step; + if (dir == 0) + pixel_step = 1.0 / height; + else + pixel_step = 1.0 / width; + + vec3 gauss_coefficient; + gauss_coefficient.x = 1.0 / (sqrt(2.0 * 3.14159265) * sigma); + gauss_coefficient.y = exp(-0.5 / (sigma * sigma)); + gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y; + + float gauss_coefficient_total = gauss_coefficient.x; + + vec4 ret = getTexture(uv) * gauss_coefficient.x; + gauss_coefficient.xy *= gauss_coefficient.yz; + + int n_steps = int(ceil(1.5 * sigma)) * 2; + + for (int i = 1; i <= n_steps; i += 2) { + float coefficient_subtotal = gauss_coefficient.x; + gauss_coefficient.xy *= gauss_coefficient.yz; + coefficient_subtotal += gauss_coefficient.x; + + float gauss_ratio = gauss_coefficient.x / coefficient_subtotal; + + float foffset = float(i) + gauss_ratio; + vec2 offset = direction * foffset * pixel_step; + + ret += getTexture(uv + offset) * coefficient_subtotal; + ret += getTexture(uv - offset) * coefficient_subtotal; + + gauss_coefficient_total += 2.0 * coefficient_subtotal; + gauss_coefficient.xy *= gauss_coefficient.yz; + } + vec4 outColor = ret / gauss_coefficient_total; + + // apply brightness on the second pass (dir==0 comes last) + if (dir == 0) { + outColor.rgb *= brightness; + } + + cogl_color_out = outColor; +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js new file mode 100644 index 0000000..113a6fd --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/gaussian_blur.js @@ -0,0 +1,213 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const St = await utils.import_in_shell_only('gi://St'); +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'gaussian_blur.glsl'; +const DEFAULT_PARAMS = { + radius: 30, brightness: .6, + width: 0, height: 0, direction: 0, chained_effect: null +}; + + +export const GaussianBlurEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "GaussianBlurEffect", + Properties: { + 'radius': GObject.ParamSpec.double( + `radius`, + `Radius`, + `Blur radius`, + GObject.ParamFlags.READWRITE, + 0.0, 2000.0, + 30.0, + ), + 'brightness': GObject.ParamSpec.double( + `brightness`, + `Brightness`, + `Blur brightness`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.6, + ), + 'width': GObject.ParamSpec.double( + `width`, + `Width`, + `Width`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'height': GObject.ParamSpec.double( + `height`, + `Height`, + `Height`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'direction': GObject.ParamSpec.int( + `direction`, + `Direction`, + `Direction`, + GObject.ParamFlags.READWRITE, + 0, 1, + 0, + ), + 'chained_effect': GObject.ParamSpec.object( + `chained_effect`, + `Chained Effect`, + `Chained Effect`, + GObject.ParamFlags.READWRITE, + GObject.Object, + ), + } + }, class GaussianBlurEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + + const theme_context = St.ThemeContext.get_for_stage(global.stage); + theme_context.connectObject( + 'notify::scale-factor', _ => + this.set_uniform_value('sigma', + parseFloat(this.radius * theme_context.scale_factor / 2 - 1e-6) + ), + this + ); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get radius() { + return this._radius; + } + + set radius(value) { + if (this._radius !== value) { + this._radius = value; + + const scale_factor = St.ThemeContext.get_for_stage(global.stage).scale_factor; + + // like Clutter, we use the assumption radius = 2*sigma + this.set_uniform_value('sigma', parseFloat(this._radius * scale_factor / 2 - 1e-6)); + this.set_enabled(this.radius > 0.); + + if (this.chained_effect) + this.chained_effect.radius = value; + } + } + + get brightness() { + return this._brightness; + } + + set brightness(value) { + if (this._brightness !== value) { + this._brightness = value; + + this.set_uniform_value('brightness', parseFloat(this._brightness - 1e-6)); + + if (this.chained_effect) + this.chained_effect.brightness = value; + } + } + + get width() { + return this._width; + } + + set width(value) { + if (this._width !== value) { + this._width = value; + + this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6)); + + if (this.chained_effect) + this.chained_effect.width = value; + } + } + + get height() { + return this._height; + } + + set height(value) { + if (this._height !== value) { + this._height = value; + + this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6)); + + if (this.chained_effect) + this.chained_effect.height = value; + } + } + + get direction() { + return this._direction; + } + + set direction(value) { + if (this._direction !== value) + this._direction = value; + } + + get chained_effect() { + return this._chained_effect; + } + + set chained_effect(value) { + this._chained_effect = value; + } + + vfunc_set_actor(actor) { + if (this._actor_connection_size_id) { + let old_actor = this.get_actor(); + old_actor?.disconnect(this._actor_connection_size_id); + } + if (actor) { + this.width = actor.width; + this.height = actor.height; + this._actor_connection_size_id = actor.connect('notify::size', _ => { + this.width = actor.width; + this.height = actor.height; + }); + } + else + this._actor_connection_size_id = null; + + super.vfunc_set_actor(actor); + + if (this.direction == 0) { + if (this.chained_effect) + this.chained_effect.get_actor()?.remove_effect(this.chained_effect); + else + this.chained_effect = new GaussianBlurEffect({ + radius: this.radius, + brightness: this.brightness, + width: this.width, + height: this.height, + direction: 1 + }); + if (actor !== null) + actor.add_effect(this.chained_effect); + } + } + + vfunc_paint_target(paint_node, paint_context) { + this.set_uniform_value("dir", this.direction); + + super.vfunc_paint_target(paint_node, paint_context); + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl new file mode 100644 index 0000000..58d2694 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.glsl @@ -0,0 +1,14 @@ +uniform sampler2D tex; + +vec3 hsl_to_rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +void main(void) { + vec2 uv = cogl_tex_coord_in[0].xy; + vec4 hsla = texture2D(tex, uv); + vec4 rgba = vec4(hsl_to_rgb(hsla.xyz), hsla.w); + cogl_color_out = rgba; +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js new file mode 100644 index 0000000..fe53114 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/hsl_to_rgb.js @@ -0,0 +1,31 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'hsl_to_rgb.glsl'; +const DEFAULT_PARAMS = {}; + + +export const HslToRgbEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "HslToRgbEffect", + Properties: {} + }, class HslToRgbEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl new file mode 100644 index 0000000..27b3806 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.glsl @@ -0,0 +1,52 @@ +uniform sampler2D tex; +uniform float radius; +uniform int iterations; +uniform float brightness; +uniform float width; +uniform float height; +uniform bool use_base_pixel; +uniform bool prefer_closer_pixels; + +float srand(vec2 a) { + return sin(dot(a, vec2(1233.224, 1743.335))); +} + +float rand(inout float r) { + r = fract(3712.65 * r + 0.61432); + return (r - 0.5) * 2.0; +} + +void main() { + vec2 uv = cogl_tex_coord0_in.st; + vec2 p = 16 * radius / vec2(width, height); + float r = srand(uv); + + vec2 rv; + vec2 dir; + vec2 new_uv; + int strength; + + int count = 0; + vec4 c = vec4(0.); + + for (int i = 0; i < iterations; i++) { + rv.x = rand(r); + rv.y = rand(r) * 3.141592; + dir = vec2(cos(rv.y), sin(rv.y)); + new_uv = uv + rv.x * dir * p; + if (new_uv.x > 2. / width && new_uv.y > 2. / height && new_uv.x < 1. - 3. / width && new_uv.y < 1. - 3. / height) { + strength = prefer_closer_pixels ? (iterations - i)^2 : 1; + c += strength * texture2D(tex, new_uv); + count += strength; + } + } + + if (count == 0 || use_base_pixel) { + strength = prefer_closer_pixels ? (iterations + 1)^2 : 1; + c += strength * texture2D(tex, uv); + count += strength; + } + + c.xyz *= brightness; + cogl_color_out = c / count; +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js new file mode 100644 index 0000000..0da56ed --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/monte_carlo_blur.js @@ -0,0 +1,207 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const St = await utils.import_in_shell_only('gi://St'); +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'monte_carlo_blur.glsl'; +const DEFAULT_PARAMS = { + radius: 2., iterations: 5, brightness: .6, + width: 0, height: 0, use_base_pixel: true, + prefer_closer_pixels: true, +}; + + +export const MonteCarloBlurEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "MonteCarloBlurEffect", + Properties: { + 'radius': GObject.ParamSpec.double( + `radius`, + `Radius`, + `Blur radius`, + GObject.ParamFlags.READWRITE, + 0.0, 2000.0, + 2.0, + ), + 'iterations': GObject.ParamSpec.int( + `iterations`, + `Iterations`, + `Blur iterations`, + GObject.ParamFlags.READWRITE, + 0, 64, + 5, + ), + 'brightness': GObject.ParamSpec.double( + `brightness`, + `Brightness`, + `Blur brightness`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.6, + ), + 'width': GObject.ParamSpec.double( + `width`, + `Width`, + `Width`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'height': GObject.ParamSpec.double( + `height`, + `Height`, + `Height`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'use_base_pixel': GObject.ParamSpec.boolean( + `use_base_pixel`, + `Use base pixel`, + `Use base pixel`, + GObject.ParamFlags.READWRITE, + true, + ), + 'prefer_closer_pixels': GObject.ParamSpec.boolean( + `prefer_closer_pixels`, + `Prefer closer pixels`, + `Prefer closer pixels`, + GObject.ParamFlags.READWRITE, + true, + ), + } + }, class MonteCarloBlurEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + + const theme_context = St.ThemeContext.get_for_stage(global.stage); + theme_context.connectObject( + 'notify::scale-factor', + _ => this.set_uniform_value('radius', + parseFloat(this._radius * theme_context.scale_factor - 1e-6) + ), + this + ); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get radius() { + return this._radius; + } + + set radius(value) { + if (this._radius !== value) { + this._radius = value; + + const scale_factor = St.ThemeContext.get_for_stage(global.stage).scale_factor; + + this.set_uniform_value('radius', parseFloat(this._radius * scale_factor - 1e-6)); + this.set_enabled(this.radius > 0. && this.iterations > 0); + } + } + + get iterations() { + return this._iterations; + } + + set iterations(value) { + if (this._iterations !== value) { + this._iterations = value; + + this.set_uniform_value('iterations', this._iterations); + this.set_enabled(this.radius > 0. && this.iterations > 0); + } + } + + get brightness() { + return this._brightness; + } + + set brightness(value) { + if (this._brightness !== value) { + this._brightness = value; + + this.set_uniform_value('brightness', parseFloat(this._brightness - 1e-6)); + } + } + + get width() { + return this._width; + } + + set width(value) { + if (this._width !== value) { + this._width = value; + + this.set_uniform_value('width', parseFloat(this._width + 3.0 - 1e-6)); + } + } + + get height() { + return this._height; + } + + set height(value) { + if (this._height !== value) { + this._height = value; + + this.set_uniform_value('height', parseFloat(this._height + 3.0 - 1e-6)); + } + } + + get use_base_pixel() { + return this._use_base_pixel; + } + + set use_base_pixel(value) { + if (this._use_base_pixel !== value) { + this._use_base_pixel = value; + + this.set_uniform_value('use_base_pixel', this._use_base_pixel ? 1 : 0); + } + } + + get prefer_closer_pixels() { + return this._prefer_closer_pixels; + } + + set prefer_closer_pixels(value) { + if (this._prefer_closer_pixels !== value) { + this._prefer_closer_pixels = value; + + this.set_uniform_value('prefer_closer_pixels', this._prefer_closer_pixels ? 1 : 0); + } + } + + vfunc_set_actor(actor) { + if (this._actor_connection_size_id) { + let old_actor = this.get_actor(); + old_actor?.disconnect(this._actor_connection_size_id); + } + if (actor) { + this.width = actor.width; + this.height = actor.height; + this._actor_connection_size_id = actor.connect('notify::size', _ => { + this.width = actor.width; + this.height = actor.height; + }); + } + else + this._actor_connection_size_id = null; + + super.vfunc_set_actor(actor); + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js new file mode 100644 index 0000000..556ffa4 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_dynamic_gaussian_blur.js @@ -0,0 +1,43 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const St = await utils.import_in_shell_only('gi://St'); +const Shell = await utils.import_in_shell_only('gi://Shell'); + +const DEFAULT_PARAMS = { + unscaled_radius: 30, brightness: 0.6 +}; + + +export const NativeDynamicBlurEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "NativeDynamicBlurEffect" + }, class NativeDynamicBlurEffect extends Shell.BlurEffect { + constructor(params) { + const { unscaled_radius, brightness, ...parent_params } = params; + super({ ...parent_params, mode: Shell.BlurMode.BACKGROUND }); + + this._theme_context = St.ThemeContext.get_for_stage(global.stage); + this._theme_context.connectObject( + 'notify::scale-factor', + _ => this.radius = this.unscaled_radius * this._theme_context.scale_factor, + this + ); + + utils.setup_params(this, params); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get unscaled_radius() { + return this._unscaled_radius; + } + + set unscaled_radius(value) { + this._unscaled_radius = value; + this.radius = value * this._theme_context.scale_factor; + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js new file mode 100644 index 0000000..fe003f5 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/native_static_gaussian_blur.js @@ -0,0 +1,43 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const St = await utils.import_in_shell_only('gi://St'); +const Shell = await utils.import_in_shell_only('gi://Shell'); + +const DEFAULT_PARAMS = { + unscaled_radius: 30, brightness: 0.6 +}; + + +export const NativeStaticBlurEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "NativeStaticBlurEffect" + }, class NativeStaticBlurEffect extends Shell.BlurEffect { + constructor(params) { + const { unscaled_radius, brightness, ...parent_params } = params; + super({ ...parent_params, mode: Shell.BlurMode.ACTOR }); + + this._theme_context = St.ThemeContext.get_for_stage(global.stage); + this._theme_context.connectObject( + 'notify::scale-factor', + _ => this.radius = this.unscaled_radius * this._theme_context.scale_factor, + this + ); + + utils.setup_params(this, params); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get unscaled_radius() { + return this._unscaled_radius; + } + + set unscaled_radius(value) { + this._unscaled_radius = value; + this.radius = value * this._theme_context.scale_factor; + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl new file mode 100644 index 0000000..6d701b6 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.glsl @@ -0,0 +1,20 @@ +uniform sampler2D tex; +uniform float noise; +uniform float lightness; + +float PHI = 1.61803398874989484820459; +float SEED = 24; + +float noise_gen(in vec2 xy) { + float r = fract(tan(distance(xy * PHI, xy) * SEED) * xy.x); + r = r != r ? 0.0 : r; + return r; +} + +void main() { + vec4 c = texture2D(tex, cogl_tex_coord_in[0].st); + vec3 pix_color = c.xyz; + float blend = noise * (1. - noise_gen(gl_FragCoord.xy)); + + cogl_color_out = vec4(mix(pix_color, lightness * pix_color, blend), 1.); +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js new file mode 100644 index 0000000..3049fa1 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/noise.js @@ -0,0 +1,76 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'noise.glsl'; +const DEFAULT_PARAMS = { + noise: 0.4, lightness: 0.4 +}; + + +export const NoiseEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "NoiseEffect", + Properties: { + 'noise': GObject.ParamSpec.double( + `noise`, + `Noise`, + `Amount of noise integrated with the image`, + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 0.4, + ), + 'lightness': GObject.ParamSpec.double( + `lightness`, + `Lightness`, + `Lightness of the grey used for the noise`, + GObject.ParamFlags.READWRITE, + 0.0, 2.0, + 0.4, + ), + } + }, class NoiseEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get noise() { + return this._noise; + } + + set noise(value) { + if (this._noise !== value) { + this._noise = value; + + this.set_uniform_value('noise', parseFloat(this._noise - 1e-6)); + this.set_enabled(this.noise > 0. && this.lightness != 1); + } + } + + get lightness() { + return this._lightness; + } + + set lightness(value) { + if (this._lightness !== value) { + this._lightness = value; + + this.set_uniform_value('lightness', parseFloat(this._lightness - 1e-6)); + this.set_enabled(this.noise > 0. && this.lightness != 1); + } + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js new file mode 100644 index 0000000..e9cad9b --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/pixelize.js @@ -0,0 +1,88 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +import { UpscaleEffect } from './upscale.js'; +import { DownscaleEffect } from './downscale.js'; + +const DEFAULT_PARAMS = { + factor: 8, downsampling_mode: 0 +}; + + +export const PixelizeEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "PixelizeEffect", + Properties: { + 'factor': GObject.ParamSpec.int( + `factor`, + `Factor`, + `Factor`, + GObject.ParamFlags.READWRITE, + 0, 64, + 8, + ), + 'downsampling_mode': GObject.ParamSpec.int( + `downsampling_mode`, + `Downsampling mode`, + `Downsampling mode`, + GObject.ParamFlags.READWRITE, + 0, 2, + 0, + ) + } + }, class PixelizeEffect extends Clutter.Effect { + constructor(params) { + super(); + + this.upscale_effect = new UpscaleEffect({}); + this.downscale_effect = new DownscaleEffect({}); + + utils.setup_params(this, params); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get factor() { + // should be the same as `this.downscale_effect.divider` + return this.upscale_effect.factor; + } + + set factor(value) { + this.upscale_effect.factor = value; + this.downscale_effect.divider = value; + } + + get downsampling_mode() { + return this.downscale_effect.downsampling_mode; + } + + set downsampling_mode(value) { + this.downscale_effect.downsampling_mode = value; + } + + vfunc_set_actor(actor) { + // deattach effects from old actor + this.upscale_effect?.actor?.remove_effect(this.upscale_effect); + this.downscale_effect?.actor?.remove_effect(this.downscale_effect); + // attach effects to new actor + if (actor) { + if (this.upscale_effect) + actor.add_effect(this.upscale_effect); + if (this.downscale_effect) + actor.add_effect(this.downscale_effect); + } + + super.vfunc_set_actor(actor); + } + + vfunc_set_enabled(is_enabled) { + this.upscale_effect?.set_enabled(is_enabled); + this.downscale_effect?.set_enabled(is_enabled); + super.vfunc_set_enabled(is_enabled); + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl new file mode 100644 index 0000000..b7a35ac --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.glsl @@ -0,0 +1,18 @@ +uniform sampler2D tex; + +vec3 rgb_to_hsl(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +void main(void) { + vec2 uv = cogl_tex_coord_in[0].xy; + vec4 rgba = texture2D(tex, uv); + vec4 hsla = vec4(rgb_to_hsl(rgba.xyz), rgba.w); + cogl_color_out = hsla; +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js new file mode 100644 index 0000000..5c4eb05 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/rgb_to_hsl.js @@ -0,0 +1,31 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'rgb_to_hsl.glsl'; +const DEFAULT_PARAMS = {}; + + +export const RgbToHslEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "RgbToHslEffect", + Properties: {} + }, class RgbToHslEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl new file mode 100644 index 0000000..5cc06ec --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.glsl @@ -0,0 +1,57 @@ +uniform sampler2D tex; +uniform int factor; +uniform float width; +uniform float height; + +#define CORRECTION 2.25 +#define SIZE_ADDITION 3 + +vec4 get_texture_at_position(vec2 position) { + vec2 raw_position = position + vec2(CORRECTION, CORRECTION); + vec2 raw_uv = raw_position / vec2(width + SIZE_ADDITION, height + SIZE_ADDITION); + + return texture2D(tex, raw_uv); +} + +ivec2 get_corrected_position() { + vec2 raw_uv = cogl_tex_coord0_in.st; + vec2 raw_position = raw_uv * vec2(width + SIZE_ADDITION, height + SIZE_ADDITION); + return ivec2(raw_position - vec2(CORRECTION, CORRECTION)); +} + +void main() { + ivec2 corrected_position = get_corrected_position(); + + vec2 adjusted_position = corrected_position / factor; + + cogl_color_out = get_texture_at_position(adjusted_position); + + // round + if (distance(corrected_position, (floor(adjusted_position) + 0.5) * factor) < factor / 2.5) { + //cogl_color_out = get_texture_at_position(adjusted_position); + } else { + //cogl_color_out = vec4(0, 0, 0, 1); + } + + // square + if (mod(corrected_position.x, factor) >= 2 && mod(corrected_position.y, factor) >= 2) { + //cogl_color_out = get_texture_at_position(adjusted_position); + } else { + //cogl_color_out = vec4(0, 0, 0, 1); + } + + // local mix + vec4 color = vec4(0); + int count = 0; + for (int i = -1; i <= 1; i++) { + for (int j = -1; j <= 1; j++) { + vec2 lookup_position = adjusted_position + vec2(i, j); + if (all(greaterThanEqual(lookup_position, vec2(0, 0))) && + all(lessThan(lookup_position, vec2(width, height) / factor))) { + color += get_texture_at_position(lookup_position); + count += 1; + } + } + } + //cogl_color_out = color / count; +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js new file mode 100644 index 0000000..fb719c3 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/effects/upscale.js @@ -0,0 +1,120 @@ +import GObject from 'gi://GObject'; + +import * as utils from '../conveniences/utils.js'; +const Shell = await utils.import_in_shell_only('gi://Shell'); +const Clutter = await utils.import_in_shell_only('gi://Clutter'); + +const SHADER_FILENAME = 'upscale.glsl'; +const DEFAULT_PARAMS = { + factor: 8, width: 0, height: 0 +}; + + +export const UpscaleEffect = utils.IS_IN_PREFERENCES ? + { default_params: DEFAULT_PARAMS } : + new GObject.registerClass({ + GTypeName: "UpscaleEffect", + Properties: { + 'factor': GObject.ParamSpec.int( + `factor`, + `Factor`, + `Factor`, + GObject.ParamFlags.READWRITE, + 0, 64, + 8, + ), + 'width': GObject.ParamSpec.double( + `width`, + `Width`, + `Width`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ), + 'height': GObject.ParamSpec.double( + `height`, + `Height`, + `Height`, + GObject.ParamFlags.READWRITE, + 0.0, Number.MAX_SAFE_INTEGER, + 0.0, + ) + } + }, class UpscaleEffect extends Clutter.ShaderEffect { + constructor(params) { + super(params); + + utils.setup_params(this, params); + + // set shader source + this._source = utils.get_shader_source(Shell, SHADER_FILENAME, import.meta.url); + if (this._source) + this.set_shader_source(this._source); + } + + static get default_params() { + return DEFAULT_PARAMS; + } + + get factor() { + return this._factor; + } + + set factor(value) { + if (this._factor !== value) { + this._factor = value; + + this.set_uniform_value('factor', this._factor); + } + } + + get width() { + return this._width; + } + + set width(value) { + if (this._width !== value) { + this._width = value; + + this.set_uniform_value('width', parseFloat(this._width - 1e-6)); + } + } + + get height() { + return this._height; + } + + set height(value) { + if (this._height !== value) { + this._height = value; + + this.set_uniform_value('height', parseFloat(this._height - 1e-6)); + } + } + + vfunc_set_actor(actor) { + if (this._actor_connection_size_id) { + let old_actor = this.get_actor(); + old_actor?.disconnect(this._actor_connection_size_id); + } + if (actor) { + this.width = actor.width; + this.height = actor.height; + this._actor_connection_size_id = actor.connect('notify::size', _ => { + this.width = actor.width; + this.height = actor.height; + }); + } + else + this._actor_connection_size_id = null; + + super.vfunc_set_actor(actor); + } + + vfunc_paint_target(paint_node, paint_context) { + // force setting nearest-neighbour texture filtering + this.get_pipeline().set_layer_filters(0, 9728, 9728); + + super.vfunc_paint_target(paint_node, paint_context); + } + });
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/extension.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/extension.js new file mode 100644 index 0000000..fbfb54c --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/extension.js @@ -0,0 +1,614 @@ +import Meta from 'gi://Meta'; +import Clutter from 'gi://Clutter'; +import * as Main from 'resource:///org/gnome/shell/ui/main.js'; +import * as Config from 'resource:///org/gnome/shell/misc/config.js'; + +import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js'; + +import { update_from_old_settings } from './conveniences/settings_updater.js'; +import { PipelinesManager } from './conveniences/pipelines_manager.js'; +import { EffectsManager } from './conveniences/effects_manager.js'; +import { Connections } from './conveniences/connections.js'; +import { Settings } from './conveniences/settings.js'; +import { KEYS } from './conveniences/keys.js'; + +import { PanelBlur } from './components/panel.js'; +import { OverviewBlur } from './components/overview.js'; +import { DashBlur } from './components/dash_to_dock.js'; +import { LockscreenBlur } from './components/lockscreen.js'; +import { AppFoldersBlur } from './components/appfolders.js'; +import { WindowListBlur } from './components/window_list.js'; +import { CoverflowAltTabBlur } from './components/coverflow_alt_tab.js'; +import { ApplicationsBlur } from './components/applications.js'; +import { ScreenshotBlur } from './components/screenshot.js'; + + +/// The main extension class, created when the GNOME Shell is loaded. +export default class BlurMyShell extends Extension { + /// Enables the extension. + enable() { + // add the extension to global to make it accessible to other extensions + // create it first as it is very useful when debugging crashes + global.blur_my_shell = this; + + // update from old settings, very important for hacks level specifically + update_from_old_settings(this.getSettings()); + + // create a Settings instance, to manage extension's preferences + // it needs to be loaded before logging, as it checks for DEBUG + this._settings = new Settings(KEYS, this.getSettings()); + + this._log("enabling extension..."); + + // create main extension Connections instance + this._connection = new Connections; + + // store it in a global array + this._connections = [this._connection]; + + // create a global effects manager (to prevent RAM bleeding) + this._effects_manager = new EffectsManager(this._connection); + + // create a global pipelines manager, that helps talking with preferences + this._pipelines_manager = new PipelinesManager(this._settings); + + // create an instance of each component, with its associated Connections + let init = () => { + // create a Connections instance, to manage signals + let connection = new Connections; + + // store it to keeps track of them globally + this._connections.push(connection); + + return [connection, this._settings, this._effects_manager]; + }; + + this._panel_blur = new PanelBlur(...init()); + this._dash_to_dock_blur = new DashBlur(...init()); + this._overview_blur = new OverviewBlur(...init()); + this._lockscreen_blur = new LockscreenBlur(...init()); + this._appfolder_blur = new AppFoldersBlur(...init()); + this._window_list_blur = new WindowListBlur(...init()); + this._coverflow_alt_tab_blur = new CoverflowAltTabBlur(...init()); + this._applications_blur = new ApplicationsBlur(...init()); + this._screenshot_blur = new ScreenshotBlur(...init()); + + // connect each component to preferences change + this._connect_to_settings(); + + // enable the lockscreen blur, only one important in both `user` session and `unlock-dialog` + if (this._settings.lockscreen.BLUR && !this._lockscreen_blur.enabled) + this._lockscreen_blur.enable(); + + // ensure we take the correct action for the current session mode + this._user_session_mode_enabled = false; + this._on_session_mode_changed(Main.sessionMode); + + // watch for changes to the session mode + this._connection.connect(Main.sessionMode, 'updated', + () => this._on_session_mode_changed(Main.sessionMode) + ); + } + + /// Enables the components related to the user session (everything except lockscreen blur). + _enable_user_session() { + this._log("changing mode to user session..."); + + // maybe disable clipped redraw + this._update_clipped_redraws(); + + // enable every component + // if the shell is still starting up, wait for it to be entirely loaded; + // this should prevent bugs like #136 and #137 + if (Main.layoutManager._startingUp) { + this._connection.connect( + Main.layoutManager, + 'startup-complete', + () => this._enable_components() + ); + } else + this._enable_components(); + + // try to enable the components as soon as possible anyway, this way the + // overview may load before the user sees it + try { + if (this._settings.overview.BLUR && !this._overview_blur.enabled) + this._overview_blur.enable(); + } catch (e) { + this._log("Could not enable overview blur directly"); + this._log(e); + } + try { + if (this._settings.dash_to_dock.BLUR + && !this._dash_to_dock_blur.enabled) + this._dash_to_dock_blur.enable(); + } catch (e) { + this._log("Could not enable dash-to-dock blur directly"); + this._log(e); + } + try { + if (this._settings.panel.BLUR && !this._panel_blur.enabled) + this._panel_blur.enable(); + } catch (e) { + this._log("Could not enable panel blur directly"); + this._log(e); + } + + // tells the extension we have enabled the user session components, so that we do not + // disable them later if they were not even enabled to begin with + this._user_session_mode_enabled = true; + } + + /// Disables the extension. + /// + /// This extension needs to use the 'unlock-dialog' session mode in order to change the blur on + /// the lockscreen. We have kind of two states of enablement for this extension: + /// - the 'enabled' state, which means that we have created the necessary components (which only + /// are js objects) and enabled the lockscreen blur (which means swapping two functions from + /// the `UnlockDialog` constructor with our ones; + /// - the 'user session enabled` mode, which means that we are in the 'enabled' mode AND we are + /// in the user mode, and so we enable all the other components that we created before. + /// We switch from one state to the other thanks to `this._on_session_mode_changed`, and we + /// track wether or not we are in the user mode with `this._user_session_mode_enabled` (because + /// `this._on_session_mode_changed` might be called multiple times while in the user session + /// mode, typically when going back from simple lockscreen and not sleep mode). + disable() { + this._log("disabling extension..."); + + // disable every component from user session mode + if (this._user_session_mode_enabled) + this._disable_user_session(); + this._overview_blur.restore_patched_proto(); + + // disable lockscreen blur too + this._lockscreen_blur.disable(); + + // untrack them + this._panel_blur = null; + this._dash_to_dock_blur = null; + this._overview_blur = null; + this._appfolder_blur = null; + this._lockscreen_blur = null; + this._window_list_blur = null; + this._coverflow_alt_tab_blur = null; + this._applications_blur = null; + this._screenshot_blur = null; + + // make sure no settings change can re-enable them + this._settings.disconnect_all_settings(); + + // force disconnecting every signal, even if component crashed + this._connections.forEach((connections) => { + connections.disconnect_all(); + }); + this._connections = []; + + // remove the clipped redraws flag + this._reenable_clipped_redraws(); + + // remove the extension from GJS's global + delete global.blur_my_shell; + + this._log("extension disabled."); + + this._settings = null; + } + + /// Disables the components related to the user session (everything except lockscreen blur). + _disable_user_session() { + this._log("disabling user session mode..."); + + // disable every component except lockscreen blur + this._panel_blur.disable(); + this._dash_to_dock_blur.disable(); + this._overview_blur.disable(); + this._appfolder_blur.disable(); + this._window_list_blur.disable(); + this._coverflow_alt_tab_blur.disable(); + this._applications_blur.disable(); + this._screenshot_blur.disable(); + + // remove the clipped redraws flag + this._reenable_clipped_redraws(); + + // tells the extension we have disabled the user session components, so that we do not + // disable them later again if they were already disabled + this._user_session_mode_enabled = false; + } + + /// Restarts the components related to the user session. + _restart() { + this._log("restarting..."); + + this._disable_user_session(); + this._enable_user_session(); + + this._log("restarted."); + } + + /// Changes the extension to operate either on 'user' mode or 'unlock-dialog' mode, switching + /// from one to the other means enabling/disabling every component except lockscreen blur. + _on_session_mode_changed(session) { + if (session.currentMode === 'user' || session.parentMode === 'user') { + if (!this._user_session_mode_enabled) + // we need to activate everything + this._enable_user_session(); + } + else if (session.currentMode === 'unlock-dialog') { + if (this._user_session_mode_enabled) + // we need to disable the components related to the user session mode + this._disable_user_session(); + } + } + + /// Add or remove the clutter debug flag to disable clipped redraws. + /// This will entirely fix the blur effect, but should not be used except if + /// the user really needs it, as clipped redraws are a huge performance + /// boost for the compositor. + _update_clipped_redraws() { + if (this._settings.HACKS_LEVEL === 2) + this._disable_clipped_redraws(); + else + this._reenable_clipped_redraws(); + } + + /// Add the Clutter debug flag. + _disable_clipped_redraws() { + let gnome_shell_major_version = parseInt(Config.PACKAGE_VERSION.split('.')[0]); + if (gnome_shell_major_version >= 48) + Clutter.add_debug_flags( + null, Clutter.DrawDebugFlag.DISABLE_CLIPPED_REDRAWS, null + ); + else + Meta.add_clutter_debug_flags( + null, Clutter.DrawDebugFlag.DISABLE_CLIPPED_REDRAWS, null + ); + } + + /// Remove the Clutter debug flag. + _reenable_clipped_redraws() { + let gnome_shell_major_version = parseInt(Config.PACKAGE_VERSION.split('.')[0]); + if (gnome_shell_major_version >= 48) + Clutter.remove_debug_flags( + null, Clutter.DrawDebugFlag.DISABLE_CLIPPED_REDRAWS, null + ); + else + Meta.remove_clutter_debug_flags( + null, Clutter.DrawDebugFlag.DISABLE_CLIPPED_REDRAWS, null + ); + } + + /// Enables every component from the user session needed, should be called when the shell is + /// entirely loaded as the `enable` methods interact with it. + _enable_components() { + // enable each component if needed, and if it is not already enabled + + if (this._settings.panel.BLUR && !this._panel_blur.enabled) + this._panel_blur.enable(); + + if (this._settings.dash_to_dock.BLUR && !this._dash_to_dock_blur.enabled) + this._dash_to_dock_blur.enable(); + + if (this._settings.overview.BLUR && !this._overview_blur.enabled) + this._overview_blur.enable(); + + if (this._settings.appfolder.BLUR) + this._appfolder_blur.enable(); + + if (this._settings.applications.BLUR) + this._applications_blur.enable(); + + if (this._settings.window_list.BLUR) + this._window_list_blur.enable(); + + if (this._settings.coverflow_alt_tab.BLUR) + this._coverflow_alt_tab_blur.enable(); + + if (this._settings.screenshot.BLUR) + this._screenshot_blur.enable(); + + this._log("all components enabled."); + } + + /// Updates needed things in each component when a preference changed + _connect_to_settings() { + // restart the extension when hacks level is changed, easier than + // restarting individual components and should not happen often either + this._settings.HACKS_LEVEL_changed(() => this._restart()); + + + // ---------- OVERVIEW ---------- + + // toggled on/off + this._settings.overview.BLUR_changed(() => { + if (this._settings.overview.BLUR) + this._overview_blur.enable(); + else + this._overview_blur.disable(); + }); + + // overview pipeline changed + this._settings.overview.PIPELINE_changed(() => { + if (this._settings.overview.BLUR) + this._overview_blur.update_backgrounds(); + }); + + // overview components style changed + this._settings.overview.STYLE_COMPONENTS_changed(() => { + if (this._settings.overview.BLUR) + this._overview_blur.update_components_classname(); + }); + + + // ---------- APPFOLDER ---------- + + // toggled on/off + this._settings.appfolder.BLUR_changed(() => { + if (this._settings.appfolder.BLUR) + this._appfolder_blur.enable(); + else + this._appfolder_blur.disable(); + }); + + // appfolder sigma changed + this._settings.appfolder.SIGMA_changed(() => { + if (this._settings.appfolder.BLUR) + this._appfolder_blur.set_sigma( + this._settings.appfolder.SIGMA + ); + }); + + // appfolder brightness changed + this._settings.appfolder.BRIGHTNESS_changed(() => { + if (this._settings.appfolder.BLUR) + this._appfolder_blur.set_brightness( + this._settings.appfolder.BRIGHTNESS + ); + }); + + // appfolder dialogs style changed + this._settings.appfolder.STYLE_DIALOGS_changed(() => { + if (this._settings.appfolder.BLUR) + this._appfolder_blur.blur_appfolders(); + }); + + + // ---------- PANEL ---------- + + // toggled on/off + this._settings.panel.BLUR_changed(() => { + if (this._settings.panel.BLUR) + this._panel_blur.enable(); + else + this._panel_blur.disable(); + }); + + // static blur toggled on/off, really we can just reload the blur at this point + this._settings.panel.STATIC_BLUR_changed(() => { + if (this._settings.panel.BLUR) + this._panel_blur.reset(); + }); + + // panel pipeline changed + this._settings.panel.PIPELINE_changed(() => { + if (this._settings.panel.BLUR) + this._panel_blur.update_pipeline(); + }); + + // panel blur's overview connection toggled on/off + this._settings.panel.UNBLUR_IN_OVERVIEW_changed(() => { + this._panel_blur.connect_to_windows_and_overview(); + }); + + // force light text toggled on/off + this._settings.panel.FORCE_LIGHT_TEXT_changed(() => { + if (this._settings.panel.BLUR) + this._panel_blur.update_light_text_classname(); + }); + + // panel override background toggled on/off + this._settings.panel.OVERRIDE_BACKGROUND_changed(() => { + if (this._settings.panel.BLUR) + this._panel_blur.connect_to_windows_and_overview(); + }); + + // panel style changed + this._settings.panel.STYLE_PANEL_changed(() => { + if (this._settings.panel.BLUR) + this._panel_blur.connect_to_windows_and_overview(); + }); + + // panel background's dynamic overriding toggled on/off + this._settings.panel.OVERRIDE_BACKGROUND_DYNAMICALLY_changed(() => { + if (this._settings.panel.BLUR) + this._panel_blur.connect_to_windows_and_overview(); + }); + + + // ---------- DASH TO DOCK ---------- + + // toggled on/off + this._settings.dash_to_dock.BLUR_changed(() => { + if (this._settings.dash_to_dock.BLUR) + this._dash_to_dock_blur.enable(); + else + this._dash_to_dock_blur.disable(); + }); + + // static blur toggled on/off + this._settings.dash_to_dock.STATIC_BLUR_changed(() => { + if (this._settings.dash_to_dock.BLUR) + this._dash_to_dock_blur.change_blur_type(); + }); + + // overview pipeline changed + this._settings.dash_to_dock.PIPELINE_changed(() => { + if (this._settings.dash_to_dock.BLUR) + this._dash_to_dock_blur.update_pipeline(); + }); + + // dash-to-dock override background toggled on/off + this._settings.dash_to_dock.OVERRIDE_BACKGROUND_changed(() => { + if (this._settings.dash_to_dock.BLUR) + this._dash_to_dock_blur.update_background(); + }); + + // dash-to-dock style changed + this._settings.dash_to_dock.STYLE_DASH_TO_DOCK_changed(() => { + if (this._settings.dash_to_dock.BLUR) + this._dash_to_dock_blur.update_background(); + }); + + // dash-to-dock blur's overview connection toggled on/off + this._settings.dash_to_dock.UNBLUR_IN_OVERVIEW_changed(() => { + if (this._settings.dash_to_dock.BLUR) + this._dash_to_dock_blur.connect_to_overview(); + }); + + + // ---------- APPLICATIONS ---------- + + // toggled on/off + this._settings.applications.BLUR_changed(() => { + if (this._settings.applications.BLUR) + this._applications_blur.enable(); + else + this._applications_blur.disable(); + }); + + // static blur toggled on/off + this._settings.applications.STATIC_BLUR_changed(() => { + if (this._settings.applications.BLUR) + this._applications_blur.change_blur_type(); + }); + + // pipeline changed + this._settings.applications.PIPELINE_changed(() => { + if (this._settings.applications.BLUR) + this._applications_blur.change_pipeline(); + }); + + // application opacity changed + this._settings.applications.OPACITY_changed(() => { + if (this._settings.applications.BLUR) + this._applications_blur.set_opacity( + this._settings.applications.OPACITY + ); + }); + + // application dynamic-opacity changed + this._settings.applications.DYNAMIC_OPACITY_changed(() => { + if (this._settings.applications.BLUR) + this._applications_blur.init_dynamic_opacity(); + }); + + // application blur-on-overview changed + this._settings.applications.BLUR_ON_OVERVIEW_changed(() => { + if (this._settings.applications.BLUR) + this._applications_blur.connect_to_overview(); + }); + + // application enable-all changed + this._settings.applications.ENABLE_ALL_changed(() => { + if (this._settings.applications.BLUR) + this._applications_blur.update_all_windows(); + }); + + // application whitelist changed + this._settings.applications.WHITELIST_changed(() => { + if ( + this._settings.applications.BLUR + && !this._settings.applications.ENABLE_ALL + ) + this._applications_blur.update_all_windows(); + }); + + // application blacklist changed + this._settings.applications.BLACKLIST_changed(() => { + if ( + this._settings.applications.BLUR + && this._settings.applications.ENABLE_ALL + ) + this._applications_blur.update_all_windows(); + }); + + + // ---------- LOCKSCREEN ---------- + + // toggled on/off + this._settings.lockscreen.BLUR_changed(() => { + if (this._settings.lockscreen.BLUR) + this._lockscreen_blur.enable(); + else + this._lockscreen_blur.disable(); + }); + + // lockscreen pipeline changed + this._settings.lockscreen.PIPELINE_changed(() => { + if (this._settings.lockscreen.BLUR) + this._lockscreen_blur.update_lockscreen(); + }); + + + // ---------- WINDOW LIST ---------- + + // toggled on/off + this._settings.window_list.BLUR_changed(() => { + if (this._settings.window_list.BLUR) + this._window_list_blur.enable(); + else + this._window_list_blur.disable(); + }); + + + // ---------- COVERFLOW ALT-TAB ---------- + + // toggled on/off + this._settings.coverflow_alt_tab.BLUR_changed(() => { + if (this._settings.coverflow_alt_tab.BLUR) + this._coverflow_alt_tab_blur.enable(); + else + this._coverflow_alt_tab_blur.disable(); + }); + + + // ---------- HIDETOPBAR ---------- + + // toggled on/off + this._settings.hidetopbar.COMPATIBILITY_changed(() => { + // no need to verify if it is enabled or not, it is done anyway + this._panel_blur.connect_to_windows_and_overview(); + }); + + + // ---------- DASH TO PANEL ---------- + + // toggled on/off + this._settings.dash_to_panel.BLUR_ORIGINAL_PANEL_changed(() => { + if (this._settings.panel.BLUR) + this._panel_blur.reset(); + }); + + + // ---------- SCREENSHOT ---------- + + // toggled on/off + this._settings.screenshot.BLUR_changed(() => { + if (this._settings.screenshot.BLUR) + this._screenshot_blur.enable(); + else + this._screenshot_blur.disable(); + }); + + // screenshot pipeline changed + this._settings.screenshot.PIPELINE_changed(() => { + if (this._settings.screenshot.BLUR) + this._screenshot_blur.update_pipeline(); + }); + } + + _log(str) { + if (this._settings.DEBUG) + console.log(`[Blur my Shell > extension] ${str}`); + } +} diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/add-row-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/add-row-symbolic.svg new file mode 100644 index 0000000..bdab309 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/add-row-symbolic.svg @@ -0,0 +1,4 @@ +<svg width="16" height="16" enable-background="new" version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="2" y="7" width="11" height="1" fill="#363636"/> + <rect transform="rotate(90)" x="2" y="-8" width="11" height="1" fill="#363636"/> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/applications-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/applications-symbolic.svg new file mode 100644 index 0000000..87f307f --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/applications-symbolic.svg @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg7" + sodipodi:docname="applications.svg" + inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview9" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="44.6875" + inkscape:cx="5.5944056" + inkscape:cy="8" + inkscape:window-width="1500" + inkscape:window-height="963" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg7" /> + <defs + id="defs3"> + <style + id="current-color-scheme" + type="text/css">.ColorScheme-Text { color:#363636; }</style> + </defs> + <path + d="M 2,1 C 0.892,1 0,1.892 0,3 v 9 c 0,1.108 0.892,2 2,2 h 12 c 1.108,0 2,-0.892 2,-2 V 3 C 16,1.892 15.108,1 14,1 Z m 0,1 h 12 c 0.554,0 1,0.446 1,1 H 1 C 1,2.446 1.446,2 2,2 Z M 1,3 h 14 v 9 c 0,0.554 -0.446,1 -1,1 H 2 C 1.446,13 1,12.554 1,12 Z" + style="fill:currentColor" + class="ColorScheme-Text" + id="path5" + sodipodi:nodetypes="sssssssssssccsccssssc" /> + <g + id="g68" + transform="translate(0.3993007,0.15314685)"> + <path + d="M 9.5,4 C 9.223,4 9,4.223 9,4.5 v 2 A 0.499,0.499 0 0 0 9.5,7 h 2 C 11.777,7 12,6.777 12,6.5 v -2 C 12,4.223 11.777,4 11.5,4 Z M 10,5 h 1 v 1 h -1 z" + fill="#363636" + id="path2" /> + <path + d="M 4,6 C 3.446,6 3,6.446 3,7 v 3 c 0,0.554 0.446,1 1,1 h 3 c 0.554,0 1,-0.446 1,-1 V 7 C 8,6.446 7.554,6 7,6 Z m 0,1 h 3 v 3 H 4 Z" + fill="#363636" + id="path8" /> + </g> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/bottom-panel-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/bottom-panel-symbolic.svg new file mode 100644 index 0000000..2eda98b --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/bottom-panel-symbolic.svg @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg7" + sodipodi:docname="panel.svg" + inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview9" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="44.6875" + inkscape:cx="5.5944056" + inkscape:cy="8" + inkscape:window-width="1500" + inkscape:window-height="963" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg7" /> + <defs + id="defs3"> + <style + id="current-color-scheme" + type="text/css">.ColorScheme-Text { color:#363636; }</style> + </defs> + <path + d="M 2,1 C 0.892,1 0,1.892 0,3 v 9 c 0,1.108 0.892,2 2,2 h 12 c 1.108,0 2,-0.892 2,-2 V 3 C 16,1.892 15.108,1 14,1 Z m 0,1 h 12 c 0.554,0 1,0.446 1,1 H 1 C 1,2.446 1.446,2 2,2 Z M 1,4 h 14 v 8 c 0,0.554 -0.446,1 -1,1 H 2 C 1.446,13 1,12.554 1,12 Z" + style="fill:currentColor" + class="ColorScheme-Text" + id="path5" + sodipodi:nodetypes="sssssssssssccsccssssc" /> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dash-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dash-symbolic.svg new file mode 100644 index 0000000..5a78b46 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dash-symbolic.svg @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg7" + sodipodi:docname="top-panel.svg" + inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview9" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="44.6875" + inkscape:cx="5.5944056" + inkscape:cy="8" + inkscape:window-width="1500" + inkscape:window-height="963" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg7" /> + <defs + id="defs3"> + <style + id="current-color-scheme" + type="text/css">.ColorScheme-Text { color:#363636; }</style> + </defs> + <path + d="M 2,1 C 0.892,1 0,1.892 0,3 v 9 c 0,1.108 0.892,2 2,2 h 12 c 1.108,0 2,-0.892 2,-2 V 3 C 16,1.892 15.108,1 14,1 Z m 0,1 h 12 c 0.554,0 1,0.446 1,1 H 1 C 1,2.446 1.446,2 2,2 Z M 1,3 h 14 v 9 c 0,0.554 -0.446,1 -1,1 H 2 C 1.446,13 1,12.554 1,12 Z m 3,7 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 h 8 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z" + style="fill:currentColor" + class="ColorScheme-Text" + id="path5" + sodipodi:nodetypes="sssssssssssccsccsssscsssssss" /> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/down-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/down-symbolic.svg new file mode 100644 index 0000000..652f8c0 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/down-symbolic.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 2.292969 6.707031 l 5 5 c 0.390625 0.390625 1.023437 0.390625 1.414062 0 l 5 -5 c 0.390625 -0.390625 0.390625 -1.023437 0 -1.414062 s -1.023437 -0.390625 -1.414062 0 l -4.292969 4.292969 l -4.292969 -4.292969 c -0.390625 -0.390625 -1.023437 -0.390625 -1.414062 0 s -0.390625 1.023437 0 1.414062 z m 0 0" fill="#222222" fill-rule="evenodd"/></svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/duplicate-row-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/duplicate-row-symbolic.svg new file mode 100644 index 0000000..925e900 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/duplicate-row-symbolic.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M7 5c-1.108 0-2 .892-2 2v7c0 1.108.892 2 2 2h7c1.108 0 2-.892 2-2V7c0-1.108-.892-2-2-2Zm0 1h7c.554 0 1 .446 1 1v7c0 .554-.446 1-1 1H7c-.554 0-1-.446-1-1V7c0-.554.446-1 1-1Z" style="fill:#dedede;stroke:none;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers;stop-color:#000"/><path d="M2 0C.892 0 0 .892 0 2v7c0 1.108.892 2 2 2h2v-1H2c-.554 0-1-.446-1-1V2c0-.554.446-1 1-1h7c.554 0 1 .446 1 1v2h1V2c0-1.108-.892-2-2-2Z" style="fill:#dedede;stroke:none;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers;stop-color:#000"/></svg>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dynamic-mode-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dynamic-mode-symbolic.svg new file mode 100644 index 0000000..c37b9aa --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/dynamic-mode-symbolic.svg @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16px" + height="16px" + viewBox="0 0 16 16" + version="1.1" + id="svg5" + sodipodi:docname="dynamic-mode-symbolic.svg" + inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs5" /> + <sodipodi:namedview + id="namedview5" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + inkscape:zoom="44.75" + inkscape:cx="7.9888268" + inkscape:cy="8" + inkscape:window-width="1500" + inkscape:window-height="963" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg5" + showguides="true" /> + <path + d="m 11.5,11.34375 a 5.75,5.75 0 0 1 -1,0.134766 v 2.234375 C 10.5,14.425813 9.9258135,15 9.2128906,15 H 2.2871094 C 1.5741865,15 1,14.425813 1,13.712891 V 6.7871094 C 1,6.0741865 1.5741865,5.5 2.2871094,5.5 h 2.234375 A 5.75,5.75 0 0 1 4.65625,4.5 H 1.5585937 C 0.69558189,4.5 0,5.1955819 0,6.0585937 V 14.441406 C 0,15.304418 0.69558189,16 1.5585937,16 H 9.9414063 C 10.804418,16 11.5,15.304418 11.5,14.441406 Z" + style="opacity:1;fill:#dedede;stroke-linejoin:round" + id="path14" /> + <path + d="M 10.5,11.478516 A 5.75,5.75 0 0 1 10.25,11.5 5.75,5.75 0 0 1 4.5,5.75 5.75,5.75 0 0 1 4.5214844,5.5 H 2.2871094 C 1.5741865,5.5 1,6.0741865 1,6.7871094 V 13.712891 C 1,14.425813 1.5741865,15 2.2871094,15 H 9.2128906 C 9.9258135,15 10.5,14.425813 10.5,13.712891 Z" + style="opacity:0.25;fill:#dedede;stroke-width:0.826087;stroke-linejoin:round" + id="path15" /> + <path + d="m 11.5,11.34375 v -1.029297 a 4.75,4.75 0 0 1 -1,0.164063 v 1 a 5.75,5.75 0 0 0 1,-0.134766 z" + style="opacity:1;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.25351;stroke-linejoin:round;-inkscape-stroke:hairline" + id="path22" /> + <path + d="M 10.25,0 A 5.75,5.75 0 0 0 4.65625,4.5 H 5.6855469 A 4.75,4.75 0 0 1 10.25,1 4.75,4.75 0 0 1 15,5.75 4.75,4.75 0 0 1 11.5,10.314453 V 11.34375 A 5.75,5.75 0 0 0 16,5.75 5.75,5.75 0 0 0 10.25,0 Z" + style="opacity:1;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.25351;stroke-linejoin:round;-inkscape-stroke:hairline" + id="path18" /> + <path + d="m 4.5214844,5.5 h 1 a 4.75,4.75 0 0 1 0.1640625,-1 H 4.65625 a 5.75,5.75 0 0 0 -0.1347656,1 z" + style="opacity:1;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.25351;stroke-linejoin:round;-inkscape-stroke:hairline" + id="path17" /> + <path + d="m 10.5,11.478516 v -1 A 4.75,4.75 0 0 1 10.25,10.5 4.75,4.75 0 0 1 5.5,5.75 4.75,4.75 0 0 1 5.5214844,5.5 h -1 A 5.75,5.75 0 0 0 4.5,5.75 a 5.75,5.75 0 0 0 5.75,5.75 5.75,5.75 0 0 0 0.25,-0.02148 z" + style="opacity:1;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.25351;stroke-linejoin:round;-inkscape-stroke:hairline" + id="path16" /> + <path + d="M 10.5,10.478516 V 6.7871094 C 10.5,6.0741865 9.9258135,5.5 9.2128906,5.5 H 5.5214844 A 4.75,4.75 0 0 0 5.5,5.75 a 4.75,4.75 0 0 0 4.75,4.75 4.75,4.75 0 0 0 0.25,-0.02148 z" + style="opacity:0.125;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.03551;stroke-linejoin:round;-inkscape-stroke:hairline;fill-opacity:1" + id="path21" /> + <path + d="m 5.6855469,4.5 a 4.75,4.75 0 0 0 -0.1640625,1 H 9.2128906 C 9.9258135,5.5 10.5,6.0741865 10.5,6.7871094 v 3.6914066 a 4.75,4.75 0 0 0 1,-0.164063 V 6.0585937 C 11.5,5.1955819 10.804418,4.5 9.9414063,4.5 Z" + style="opacity:0.5;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.03551;stroke-linejoin:round;-inkscape-stroke:hairline;fill-opacity:1" + id="path20" /> + <path + d="M 5.6855469,4.5 H 9.9414063 C 10.804418,4.5 11.5,5.1955819 11.5,6.0585937 V 10.314453 A 4.75,4.75 0 0 0 15,5.75 4.75,4.75 0 0 0 10.25,1 4.75,4.75 0 0 0 5.6855469,4.5 Z" + style="opacity:0;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.03551;stroke-linejoin:round;-inkscape-stroke:hairline;fill-opacity:1" + id="path19" /> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/edit-row-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/edit-row-symbolic.svg new file mode 100644 index 0000000..f4115ad --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/edit-row-symbolic.svg @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <metadata> + <rdf:RDF> + <cc:Work rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> + <dc:title/> + </cc:Work> + </rdf:RDF> + </metadata> + <path d="m4 1c-1.108 0-2 0.892-2 2v10c0 1.108 0.892 2 2 2h8c1.108 0 2-0.892 2-2v-5.0488l-1 1v4.0488c0 0.554-0.446 1-1 1h-8c-0.554 0-1-0.446-1-1v-10c0-0.554 0.446-1 1-1h6.0488l1-1z" fill="#dedede"/> + <path class="ColorScheme-Text" d="m14.607 1.6863c-0.78347-0.78347-2.045-0.78347-2.8284 0l3.5355 3.5355c0.78347-0.78347 0.78348-2.045 0-2.8284zm-3.5355 0.70711-7.0711 7.0711-6e-7 3.5355h3.5355l7.0711-7.0711zm0 1.4142 2.1213 2.1213-5.6569 5.6569-2.1213-2.1213z" fill="#dedede"/> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/heart-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/heart-symbolic.svg new file mode 100644 index 0000000..fa045a8 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/heart-symbolic.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 5.074219 1.9375 c -3.136719 -0.3125 -5.875 3.914062 -2.816407 6.613281 l 5.742188 5.117188 l 5.746094 -5.117188 c 2.585937 -2.238281 1.070312 -6.492187 -2.351563 -6.585937 c -0.972656 -0.027344 -1.921875 0.324218 -2.636719 0.984375 l -0.757812 0.675781 l -0.753906 -0.675781 c -0.703125 -0.628907 -1.449219 -0.941407 -2.171875 -1.011719 z m -0.097657 0.988281 c 0.507813 0.046875 1.039063 0.265625 1.597657 0.769531 h 0.003906 l 1.421875 1.269532 l 1.425781 -1.273438 l 0.007813 -0.007812 c 0.523437 -0.480469 1.21875 -0.738282 1.933594 -0.71875 c 1.300781 0.035156 2.15625 0.816406 2.515624 1.824218 c 0.355469 1.007813 0.191407 2.15625 -0.792968 3.003907 l -0.003906 0.007812 l -5.085938 4.527344 l -5.078125 -4.527344 h -0.003906 c -0.753907 -0.664062 -0.992188 -1.332031 -0.996094 -2 c 0 -0.667969 0.285156 -1.351562 0.761719 -1.890625 c 0.480468 -0.535156 1.128906 -0.898437 1.789062 -0.976562 c 0.167969 -0.015625 0.335938 -0.019532 0.503906 -0.007813 z m 0 0" fill="#222222"/></svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/other-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/other-symbolic.svg new file mode 100644 index 0000000..45e703e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/other-symbolic.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" enable-background="new"><defs><filter id="a" color-interpolation-filters="sRGB"><feBlend mode="darken" in2="BackgroundImage"/></filter></defs><g transform="matrix(0 -1 -1 0 -413 -83.997)" color="#000" fill="#dedede"><rect y="-418" x="-92.997" width="2" style="marker:none" ry="1" rx="1" height="2" overflow="visible" enable-background="new"/><rect y="-422" x="-92.997" width="2" style="marker:none" ry="1" rx="1" height="2" overflow="visible" enable-background="new"/><rect y="-426" x="-92.997" width="2" style="marker:none" ry="1" rx="1" height="2" overflow="visible" enable-background="new"/></g></svg>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/overview-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/overview-symbolic.svg new file mode 100644 index 0000000..445f662 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/overview-symbolic.svg @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + version="1.1" + viewBox="0 0 16 16" + id="svg7" + sodipodi:docname="overview.svg" + inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview9" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + showgrid="false" + inkscape:zoom="44.6875" + inkscape:cx="5.5944056" + inkscape:cy="8" + inkscape:window-width="1500" + inkscape:window-height="963" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="g68" + inkscape:snap-bbox="true" + inkscape:snap-bbox-edge-midpoints="true" + inkscape:snap-bbox-midpoints="true" /> + <defs + id="defs3"> + <style + id="current-color-scheme" + type="text/css">.ColorScheme-Text { color:#363636; }</style> + </defs> + <path + d="M 2,1 C 0.892,1 0,1.892 0,3 v 9 c 0,1.108 0.892,2 2,2 h 12 c 1.108,0 2,-0.892 2,-2 V 3 C 16,1.892 15.108,1 14,1 Z m 0,1 h 12 c 0.554,0 1,0.446 1,1 H 1 C 1,2.446 1.446,2 2,2 Z M 1,3 h 14 v 9 c 0,0.554 -0.446,1 -1,1 H 2 C 1.446,13 1,12.554 1,12 Z" + style="fill:currentColor" + class="ColorScheme-Text" + id="path5" + sodipodi:nodetypes="sssssssssssccsccssssc" /> + <g + id="g68" + transform="translate(0.3993007,0.15314685)"> + <path + d="m 3.1756095,3.5602457 c -0.8440582,0 -1,0.446 -1,1 v 5.5732153 c 0,0.677136 0.446,1 1,1 H 12.02579 c 0.554,0 0.999999,-0.446 0.999999,-1 V 4.5602457 c 0,-0.554 -0.445999,-1 -0.999999,-1 z m 0,1 H 12.02579 V 10.133461 H 3.1756095 Z" + fill="#363636" + id="path8" + sodipodi:nodetypes="sssssssssccccc" /> + </g> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/pipelines-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/pipelines-symbolic.svg new file mode 100644 index 0000000..d451b23 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/pipelines-symbolic.svg @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16" + height="16" + enable-background="new" + version="1.1" + id="svg16" + sodipodi:docname="pipelines-symbolic.svg" + inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs20" /> + <sodipodi:namedview + id="namedview18" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + showgrid="false" + inkscape:zoom="24.174578" + inkscape:cx="13.98163" + inkscape:cy="8.3765683" + inkscape:window-width="1500" + inkscape:window-height="963" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="g14" /> + <g + fill="#363636" + id="g14" + transform="rotate(90,7.75,8.25)"> + <path + d="m 2.9500144,1 c -0.277,0 -0.5,0.223 -0.5,0.5 v 6.5547 a 2.5,2.5 0 0 1 0.5,-0.054688 2.5,2.5 0 0 1 0.5,0.050781 v -6.5508 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 0.5,11.945 a 2.5,2.5 0 0 1 -0.5,0.05469 2.5,2.5 0 0 1 -0.5,-0.05078 v 1.5508 c 0,0.277 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.223 0.5,-0.5 v -1.5547 z" + id="path2" /> + <path + d="M 7.5,1 C 7.223,1 7,1.223 7,1.5 V 3.0547 A 2.5,2.5 0 0 1 7.5,3.000012 2.5,2.5 0 0 1 8,3.050793 v -1.5508 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z M 8,7.9453 A 2.5,2.5 0 0 1 7.5,7.999988 2.5,2.5 0 0 1 7,7.949207 v 6.5508 c 0,0.277 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.223 0.5,-0.5 v -6.5547 z" + id="path4" /> + <path + d="m 12.049986,1.0001482 c -0.277,0 -0.5,0.223 -0.5,0.5 v 6.5547 a 2.5,2.5 0 0 1 0.5,-0.054688 2.5,2.5 0 0 1 0.5,0.050781 v -6.5508 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 0.5,11.9450008 a 2.5,2.5 0 0 1 -0.5,0.05469 2.5,2.5 0 0 1 -0.5,-0.05078 v 1.5508 c 0,0.276999 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.223001 0.5,-0.5 v -1.5547 z" + id="path6" /> + <circle + cx="2.9500144" + cy="10.5" + id="circle8" + r="1.5" /> + <circle + cx="7.5" + cy="5.5" + r="1.5" + id="circle10" /> + <circle + cx="12.049986" + cy="10.500149" + id="circle12" + r="1.5" /> + </g> +</svg>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/remove-row-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/remove-row-symbolic.svg new file mode 100644 index 0000000..a8da14f --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/remove-row-symbolic.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path d="m4.4647 3.9648c-0.12775 0-0.2555 0.048567-0.35339 0.14649-0.19578 0.19586-0.19578 0.51116 0 0.70703l3.1816 3.1816-3.1816 3.1816c-0.19578 0.19586-0.19578 0.51116 0 0.70703 0.19578 0.19586 0.51118 0.19586 0.70704 0l3.1816-3.1816 3.1816 3.1816c0.19578 0.19586 0.51114 0.19586 0.70704 0 0.19578-0.19586 0.19578-0.51116 0-0.70703l-3.1816-3.1816 3.1816-3.1816c0.19578-0.19586 0.19578-0.51116 0-0.70703-0.19578-0.19586-0.51118-0.19586-0.70704 0l-3.1816 3.1816-3.1816-3.1816c-0.09789-0.097928-0.22564-0.14649-0.35339-0.14649z" fill="#363636" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.9149" style="paint-order:stroke fill markers"/> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/reset-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/reset-symbolic.svg new file mode 100644 index 0000000..e443de4 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/reset-symbolic.svg @@ -0,0 +1,7 @@ +<svg width="16" height="16" enable-background="new" version="1.1" xmlns="http://www.w3.org/2000/svg"> + <g fill="#363636"> + <path d="m8 3a6 6 0 0 0-6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6h-1a5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5z"/> + <path d="m8.1719 0.67188-0.70703 0.70703 2.1211 2.1211-2.1211 2.1211 0.70703 0.70703 2.8281-2.8281-0.70703-0.70703z"/> + <rect x="8" y="3" width="2" height="1"/> + </g> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-row-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-row-symbolic.svg new file mode 100644 index 0000000..e6d2d9e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-row-symbolic.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="16px" viewBox="0 0 16 16" width="16px"><filter id="a" height="100%" width="100%" x="0%" y="0%"><feColorMatrix color-interpolation-filters="sRGB" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/></filter><mask id="b"><g filter="url(#a)"><path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.5"/></g></mask><clipPath id="c"><path d="m 0 0 h 1600 v 1200 h -1600 z"/></clipPath><mask id="d"><g filter="url(#a)"><path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.7"/></g></mask><clipPath id="e"><path d="m 0 0 h 1600 v 1200 h -1600 z"/></clipPath><mask id="f"><g filter="url(#a)"><path d="m -1.6 -1.6 h 19.2 v 19.2 h -19.2 z" fill-opacity="0.35"/></g></mask><clipPath id="g"><path d="m 0 0 h 1600 v 1200 h -1600 z"/></clipPath><g mask="url(#b)"><g clip-path="url(#c)" transform="matrix(1 0 0 1 -860 -60)"><path d="m 550 182 c -0.351562 0.003906 -0.695312 0.101562 -1 0.28125 v 3.4375 c 0.304688 0.179688 0.648438 0.277344 1 0.28125 c 1.105469 0 2 -0.894531 2 -2 s -0.894531 -2 -2 -2 z m 0 5 c -0.339844 0 -0.679688 0.058594 -1 0.175781 v 6.824219 h 4 v -4 c 0 -1.65625 -1.34375 -3 -3 -3 z m 0 0"/></g></g><g mask="url(#d)"><g clip-path="url(#e)" transform="matrix(1 0 0 1 -860 -60)"><path d="m 569 182 v 4 c 1.105469 0 2 -0.894531 2 -2 s -0.894531 -2 -2 -2 z m 0 5 v 7 h 3 v -4 c 0 -1.65625 -1.34375 -3 -3 -3 z m 0 0"/></g></g><g mask="url(#f)"><g clip-path="url(#g)" transform="matrix(1 0 0 1 -860 -60)"><path d="m 573 182.269531 v 3.449219 c 0.613281 -0.355469 0.996094 -1.007812 1 -1.71875 c 0 -0.714844 -0.382812 -1.375 -1 -1.730469 z m 0 4.90625 v 6.824219 h 2 v -4 c 0 -1.269531 -0.800781 -2.402344 -2 -2.824219 z m 0 0"/></g></g><path d="m 7.292969 1.707031 l 7 7 v -1.414062 l -7 7 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 s 1.023437 0.390625 1.414062 0 l 7 -7 c 0.390625 -0.390625 0.390625 -1.023437 0 -1.414062 l -7 -7 c -0.390625 -0.3906252 -1.023437 -0.3906252 -1.414062 0 c -0.390625 0.390625 -0.390625 1.023437 0 1.414062 z m 0 0"/><path d="m 15 7 h -14 c -0.550781 0 -1 0.449219 -1 1 s 0.449219 1 1 1 h 14 c 0.550781 0 1 -0.449219 1 -1 s -0.449219 -1 -1 -1 z m 0 0"/></svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-window-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-window-symbolic.svg new file mode 100644 index 0000000..cad2da8 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/select-window-symbolic.svg @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 0 16 16" width="16px"><path d="m 2.953125 1.074219 l 2.417969 13.210937 l 3.238281 -2.398437 l 2.054687 2.648437 c 1.03125 1.433594 3.148438 -0.210937 2.011719 -1.5625 l -2.015625 -2.59375 l 2.984375 -2.175781 z m 0 0" fill="#222222"/></svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/static-mode-symbolic.svg b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/static-mode-symbolic.svg new file mode 100644 index 0000000..5b0eb20 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/icons/hicolor/scalable/actions/static-mode-symbolic.svg @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + width="16px" + height="16px" + viewBox="0 0 16 16" + version="1.1" + id="svg5" + sodipodi:docname="static-mode-symbolic.svg" + inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg"> + <defs + id="defs5" /> + <sodipodi:namedview + id="namedview5" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:showpageshadow="2" + inkscape:pageopacity="0.0" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" + inkscape:zoom="44.75" + inkscape:cx="8" + inkscape:cy="8" + inkscape:window-width="1500" + inkscape:window-height="963" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="svg5" + showguides="true" /> + <path + d="m 11.5,11.34375 a 5.75,5.75 0 0 1 -1,0.134766 v 2.234375 C 10.5,14.425813 9.9258135,15 9.2128906,15 H 2.2871094 C 1.5741865,15 1,14.425813 1,13.712891 V 6.7871094 C 1,6.0741865 1.5741865,5.5 2.2871094,5.5 h 2.234375 A 5.75,5.75 0 0 1 4.65625,4.5 H 1.5585937 C 0.69558189,4.5 0,5.1955819 0,6.0585937 V 14.441406 C 0,15.304418 0.69558189,16 1.5585937,16 H 9.9414063 C 10.804418,16 11.5,15.304418 11.5,14.441406 Z" + style="opacity:1;fill:#dedede;stroke-linejoin:round" + id="path14" /> + <path + d="M 10.5,11.478516 A 5.75,5.75 0 0 1 10.25,11.5 5.75,5.75 0 0 1 4.5,5.75 5.75,5.75 0 0 1 4.5214844,5.5 H 2.2871094 C 1.5741865,5.5 1,6.0741865 1,6.7871094 V 13.712891 C 1,14.425813 1.5741865,15 2.2871094,15 H 9.2128906 C 9.9258135,15 10.5,14.425813 10.5,13.712891 Z" + style="opacity:0.25;fill:#dedede;stroke-width:0.826087;stroke-linejoin:round" + id="path15" /> + <path + d="m 11.5,11.34375 v -1.029297 a 4.75,4.75 0 0 1 -1,0.164063 v 1 a 5.75,5.75 0 0 0 1,-0.134766 z" + style="opacity:1;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.25351;stroke-linejoin:round;-inkscape-stroke:hairline" + id="path22" /> + <path + d="M 10.25,0 A 5.75,5.75 0 0 0 4.65625,4.5 H 5.6855469 A 4.75,4.75 0 0 1 10.25,1 4.75,4.75 0 0 1 15,5.75 4.75,4.75 0 0 1 11.5,10.314453 V 11.34375 A 5.75,5.75 0 0 0 16,5.75 5.75,5.75 0 0 0 10.25,0 Z" + style="opacity:1;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.25351;stroke-linejoin:round;-inkscape-stroke:hairline" + id="path18" /> + <path + d="m 4.5214844,5.5 h 1 a 4.75,4.75 0 0 1 0.1640625,-1 H 4.65625 a 5.75,5.75 0 0 0 -0.1347656,1 z" + style="opacity:1;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.25351;stroke-linejoin:round;-inkscape-stroke:hairline" + id="path17" /> + <path + d="m 10.5,11.478516 v -1 A 4.75,4.75 0 0 1 10.25,10.5 4.75,4.75 0 0 1 5.5,5.75 4.75,4.75 0 0 1 5.5214844,5.5 h -1 A 5.75,5.75 0 0 0 4.5,5.75 a 5.75,5.75 0 0 0 5.75,5.75 5.75,5.75 0 0 0 0.25,-0.02148 z" + style="opacity:1;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.25351;stroke-linejoin:round;-inkscape-stroke:hairline" + id="path16" /> + <path + d="M 10.5,10.478516 V 6.7871094 C 10.5,6.0741865 9.9258135,5.5 9.2128906,5.5 H 5.5214844 A 4.75,4.75 0 0 0 5.5,5.75 a 4.75,4.75 0 0 0 4.75,4.75 4.75,4.75 0 0 0 0.25,-0.02148 z" + style="opacity:0;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.03551;stroke-linejoin:round;-inkscape-stroke:hairline;fill-opacity:1" + id="path21" /> + <path + d="m 5.6855469,4.5 a 4.75,4.75 0 0 0 -0.1640625,1 H 9.2128906 C 9.9258135,5.5 10.5,6.0741865 10.5,6.7871094 v 3.6914066 a 4.75,4.75 0 0 0 1,-0.164063 V 6.0585937 C 11.5,5.1955819 10.804418,4.5 9.9414063,4.5 Z" + style="opacity:0;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.03551;stroke-linejoin:round;-inkscape-stroke:hairline;fill-opacity:1" + id="path20" /> + <path + d="M 5.6855469,4.5 H 9.9414063 C 10.804418,4.5 11.5,5.1955819 11.5,6.0585937 V 10.314453 A 4.75,4.75 0 0 0 15,5.75 4.75,4.75 0 0 0 10.25,1 4.75,4.75 0 0 0 5.6855469,4.5 Z" + style="opacity:0;vector-effect:non-scaling-stroke;fill:#dedede;stroke-width:1.03551;stroke-linejoin:round;-inkscape-stroke:hairline;fill-opacity:1" + id="path19" /> +</svg> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/af/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/af/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..7fd4c31 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/af/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..aac168e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ar/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/az/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/az/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..2d37384 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/az/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/be/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/be/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..6229b38 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/be/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/bg/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/bg/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..9d8da30 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/bg/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ca/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ca/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..f804035 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ca/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/cs/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/cs/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..8f46756 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/cs/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/da/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/da/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..b44f3c8 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/da/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..923e3e6 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/de/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/el/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/el/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..c671ffa --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/el/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..352d3bc --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/es/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/et/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/et/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..a92f357 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/et/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fi/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fi/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..4e50603 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fi/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..a3a72a3 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/fr/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/he/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/he/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..c00a0b0 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/he/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hi/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hi/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..d3801bb --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hi/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hr/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hr/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..45ed92c --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hr/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hu/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hu/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..40e34c4 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/hu/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/id/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/id/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..034f55a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/id/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/it/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/it/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..a6fc86a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/it/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ja/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ja/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..12d1d52 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ja/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ka/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ka/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..f38aa09 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ka/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ko/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ko/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..9088bf3 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ko/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ml/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ml/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..a03d776 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ml/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/mrh/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/mrh/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..52a61c4 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/mrh/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/my/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/my/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..0d81fb0 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/my/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nb_NO/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nb_NO/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..50cdf68 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nb_NO/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..a1a3517 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nl/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nn/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nn/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..28f7c42 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/nn/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pl/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pl/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..47fc350 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pl/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..10d3aa1 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt_BR/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt_BR/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..3dcad8d --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/pt_BR/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ro/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ro/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..dd7822e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ro/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..f7ba1de --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ru/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sk/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sk/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..be8e9a4 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sk/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sl/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sl/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..34b6505 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sl/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sv/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sv/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..c7bc46f --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/sv/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..8fc6e3d --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/ta/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/th/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/th/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..e04e4a5 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/th/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/tr/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/tr/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..04fce82 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/tr/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/uk/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/uk/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..9957d99 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/uk/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/vi/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/vi/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..385f8fa --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/vi/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_CN/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_CN/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..7b84952 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_CN/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_TW/LC_MESSAGES/blur-my-shell@aunetx.mo b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_TW/LC_MESSAGES/blur-my-shell@aunetx.mo Binary files differnew file mode 100644 index 0000000..20e60f5 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/locale/zh_TW/LC_MESSAGES/blur-my-shell@aunetx.mo diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/metadata.json b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/metadata.json new file mode 100644 index 0000000..cce8059 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/metadata.json @@ -0,0 +1,28 @@ +{ + "_generated": "Generated by SweetTooth, do not edit", + "description": "Adds a blur look to different parts of the GNOME Shell, including the top panel, dash and overview.\n\nYou can support my work by sponsoring me on:\n- github: https://github.com/sponsors/aunetx\n- ko-fi: https://ko-fi.com/aunetx\n\nIf you use Ubuntu, you may want to change the radius of the corner effect for Dash-to-Dock in preferences, else you may see unpleasantly mixed radii in your dock.\n\nNote: if the extension shows an error after updating, please make sure to restart your session to see if it persists. This is due to a bug in gnome shell, which I can't fix by myself.", + "donations": { + "github": "aunetx", + "kofi": "aunetx" + }, + "gettext-domain": "blur-my-shell@aunetx", + "name": "Blur my Shell", + "original-authors": [ + "me@aunetx.dev" + ], + "session-modes": [ + "unlock-dialog", + "user" + ], + "settings-schema": "org.gnome.shell.extensions.blur-my-shell", + "shell-version": [ + "46", + "47", + "48", + "49", + "50" + ], + "url": "https://github.com/aunetx/blur-my-shell", + "uuid": "blur-my-shell@aunetx", + "version": 71 +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js new file mode 100644 index 0000000..a4dd5be --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications.js @@ -0,0 +1,217 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + +import { ApplicationRow } from './applications_management/application_row.js'; + + +const make_array = prefs_group => { + let list_box = prefs_group + .get_first_child() + .get_last_child() + .get_first_child(); + + let elements = []; + let i = 0; + let element = list_box.get_row_at_index(i); + while (element) { + elements.push(element); + i++; + element = list_box.get_row_at_index(i); + } + + return elements; +}; + + +export const Applications = GObject.registerClass({ + GTypeName: 'Applications', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/applications.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'blur', + 'pipeline_choose_row', + 'mode_static', + 'mode_dynamic', + 'sigma_row', + 'sigma', + 'brightness_row', + 'brightness', + 'opacity', + 'dynamic_opacity', + 'blur_on_overview', + 'enable_all', + 'whitelist', + 'add_window_whitelist', + 'blacklist', + 'add_window_blacklist' + ], +}, class Applications extends Adw.PreferencesPage { + constructor(preferences, preferences_window, pipelines_manager, pipelines_page) { + super({}); + this._preferences_window = preferences_window; + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.applications.settings.bind( + 'blur', this._blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._pipeline_choose_row.initialize( + this.preferences.applications, this.pipelines_manager, this.pipelines_page + ); + + this.change_blur_mode(this.preferences.applications.STATIC_BLUR, true); + + this._mode_static.connect('toggled', + () => this.preferences.applications.STATIC_BLUR = this._mode_static.active + ); + this.preferences.applications.STATIC_BLUR_changed( + () => this.change_blur_mode(this.preferences.applications.STATIC_BLUR, false) + ); + + this.preferences.applications.settings.bind( + 'opacity', this._opacity, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'dynamic-opacity', this._dynamic_opacity, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'blur-on-overview', this._blur_on_overview, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'enable-all', this._enable_all, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'sigma', this._sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.applications.settings.bind( + 'brightness', this._brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + + // connect 'enable all' button to whitelist/blacklist visibility + this._enable_all.bind_property( + 'active', this._whitelist, 'visible', + GObject.BindingFlags.INVERT_BOOLEAN + ); + this._enable_all.bind_property( + 'active', this._blacklist, 'visible', + GObject.BindingFlags.DEFAULT + ); + + // make sure that blacklist / whitelist is correctly hidden + if (this._enable_all.active) + this._whitelist.visible = false; + this._blacklist.visible = !this._whitelist.visible; + + // listen to app row addition + this._add_window_whitelist.connect('clicked', + () => this.add_to_whitelist() + ); + this._add_window_blacklist.connect('clicked', + () => this.add_to_blacklist() + ); + + // add initial applications + this.add_widgets_from_lists(); + + this.preferences.connect('reset', () => { + this.remove_all_widgets(); + this.add_widgets_from_lists(); + }); + } + + // A way to retriew the whitelist widgets. + get _whitelist_elements() { + return make_array(this._whitelist); + } + + // A way to retriew the blacklist widgets. + get _blacklist_elements() { + return make_array(this._blacklist); + } + + add_widgets_from_lists() { + this.preferences.applications.WHITELIST.forEach( + app_name => this.add_to_whitelist(app_name) + ); + + this.preferences.applications.BLACKLIST.forEach( + app_name => this.add_to_blacklist(app_name) + ); + + } + + close_all_expanded_rows() { + this._whitelist_elements.forEach( + element => element.set_expanded(false) + ); + this._blacklist_elements.forEach( + element => element.set_expanded(false) + ); + } + + remove_all_widgets() { + this._whitelist_elements.forEach( + element => this._whitelist.remove(element) + ); + this._blacklist_elements.forEach( + element => this._blacklist.remove(element) + ); + } + + add_to_whitelist(app_name = null) { + let window_row = new ApplicationRow('whitelist', this, app_name); + this._whitelist.add(window_row); + } + + add_to_blacklist(app_name = null) { + let window_row = new ApplicationRow('blacklist', this, app_name); + this._blacklist.add(window_row); + } + + update_whitelist_titles() { + let titles = this._whitelist_elements + .map(element => element._window_class.buffer.text) + .filter(title => title != ""); + + this.preferences.applications.WHITELIST = titles; + } + + update_blacklist_titles() { + let titles = this._blacklist_elements + .map(element => element._window_class.buffer.text) + .filter(title => title != ""); + + this.preferences.applications.BLACKLIST = titles; + } + + remove_from_whitelist(widget) { + this._whitelist.remove(widget); + this.update_whitelist_titles(); + } + + remove_from_blacklist(widget) { + this._blacklist.remove(widget); + this.update_blacklist_titles(); + } + + change_blur_mode(is_static_blur, first_run) { + this._mode_static.set_active(is_static_blur); + if (first_run) + this._mode_dynamic.set_active(!is_static_blur); + + this._pipeline_choose_row.set_visible(is_static_blur); + this._sigma_row.set_visible(!is_static_blur); + this._brightness_row.set_visible(!is_static_blur); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications_management/application_row.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications_management/application_row.js new file mode 100644 index 0000000..4af3bf8 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/applications_management/application_row.js @@ -0,0 +1,112 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; +import Gtk from 'gi://Gtk'; + +import { pick, on_picking, on_picked } from '../../dbus/client.js'; + + +export const ApplicationRow = GObject.registerClass({ + GTypeName: 'ApplicationRow', + Template: GLib.uri_resolve_relative(import.meta.url, '../../ui/application-row.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'window_picker', + 'window_class', + 'picking_failure_toast', + 'window_not_found_toast' + ], +}, class ApplicationRow extends Adw.ExpanderRow { + constructor(list, app_page, app_name) { + super({}); + this._list = list; + this._app_page = app_page; + + // add a 'remove' button before the text + let action_row = this.child.get_first_child().get_first_child(); + let remove_button = new Gtk.Button({ + 'icon-name': 'remove-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6, + }); + remove_button.add_css_class('circular'); + remove_button.add_css_class('flat'); + action_row.add_prefix(remove_button); + + // connect the button to the whitelist / blacklist removal + remove_button.connect('clicked', () => this._remove_row()); + + // bind row title to text buffer + this._window_class.buffer.bind_property( + 'text', this, 'title', + Gio.SettingsBindFlags.BIDIRECTIONNAL + ); + + // set application name if it exists, or open the revealer and pick one + if (app_name) + this._window_class.buffer.text = app_name; + else { + app_page.close_all_expanded_rows(); + this.set_expanded(true); + this._do_pick_window(true); + } + + // pick a window when the picker button is clicked + this._window_picker.connect('clicked', () => this._do_pick_window()); + + // update list on text buffer change + this._window_class.connect('changed', + () => this._update_rows_titles() + ); + } + + _remove_row() { + this._app_page["remove_from_" + this._list](this); + } + + _update_rows_titles() { + this._app_page["update_" + this._list + "_titles"](this); + } + + _do_pick_window(remove_if_failed = false) { + // a mechanism to know if the extension is listening correcly + let has_responded = false; + let should_take_answer = true; + setTimeout(() => { + if (!has_responded) { + // show toast about failure + this._app_page._preferences_window.add_toast( + this._picking_failure_toast + ); + + // prevent title from changing with later picks + should_take_answer = false; + + // remove row if asked + if (remove_if_failed) + this._remove_row(); + } + }, 250); + + on_picking(() => + has_responded = true + ); + + on_picked(wm_class => { + if (should_take_answer) { + if (wm_class == 'window-not-found') { + console.warn("Can't pick window from here"); + this._app_page._preferences_window.add_toast( + this._window_not_found_toast + ); + return; + } + this._window_class.buffer.text = wm_class; + } + }); + + pick(); + } +}); diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/dash.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/dash.js new file mode 100644 index 0000000..aae3768 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/dash.js @@ -0,0 +1,81 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + + +export const Dash = GObject.registerClass({ + GTypeName: 'Dash', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/dash.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'blur', + 'pipeline_choose_row', + 'mode_static', + 'mode_dynamic', + 'sigma_row', + 'sigma', + 'brightness_row', + 'brightness', + 'override_background', + 'style_dash_to_dock', + 'unblur_in_overview' + ], +}, class Dash extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, pipelines_page) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.dash_to_dock.settings.bind( + 'blur', this._blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._pipeline_choose_row.initialize( + this.preferences.dash_to_dock, this.pipelines_manager, this.pipelines_page + ); + + this.change_blur_mode(this.preferences.dash_to_dock.STATIC_BLUR, true); + + this._mode_static.connect('toggled', + () => this.preferences.dash_to_dock.STATIC_BLUR = this._mode_static.active + ); + this.preferences.dash_to_dock.STATIC_BLUR_changed( + () => this.change_blur_mode(this.preferences.dash_to_dock.STATIC_BLUR, false) + ); + + this.preferences.dash_to_dock.settings.bind( + 'sigma', this._sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'brightness', this._brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'override-background', + this._override_background, 'enable-expansion', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'style-dash-to-dock', this._style_dash_to_dock, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_dock.settings.bind( + 'unblur-in-overview', this._unblur_in_overview, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + } + + change_blur_mode(is_static_blur, first_run) { + this._mode_static.set_active(is_static_blur); + if (first_run) + this._mode_dynamic.set_active(!is_static_blur); + + this._pipeline_choose_row.set_visible(is_static_blur); + this._sigma_row.set_visible(!is_static_blur); + this._brightness_row.set_visible(!is_static_blur); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/menu.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/menu.js new file mode 100644 index 0000000..899fdcf --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/menu.js @@ -0,0 +1,68 @@ +import Gdk from 'gi://Gdk'; +import Gtk from 'gi://Gtk'; +import Gio from 'gi://Gio'; +import GLib from 'gi://GLib'; + + +export function addMenu(window) { + const builder = new Gtk.Builder(); + + // add a dummy page and remove it immediately, to access headerbar + builder.add_from_file(GLib.filename_from_uri(GLib.uri_resolve_relative(import.meta.url, '../ui/menu.ui', GLib.UriFlags.NONE))[0]); + let menu_util = builder.get_object('menu_util'); + window.add(menu_util); + try { + addMenuToHeader(window, builder); + } catch (error) { + // could not add menu... not so bad + } + window.remove(menu_util); +} + +function addMenuToHeader(window, builder) { + // a little hack to get to the headerbar + const page = builder.get_object('menu_util'); + const pages_stack = page.get_parent(); // AdwViewStack + const content_stack = pages_stack.get_parent().get_parent(); // GtkStack + const preferences = content_stack.get_parent(); // GtkBox + const headerbar = preferences.get_first_child().get_next_sibling() + .get_first_child().get_first_child().get_first_child(); // AdwHeaderBar + headerbar.pack_start(builder.get_object('info_menu')); + + // setup menu actions + const actionGroup = new Gio.SimpleActionGroup(); + window.insert_action_group('prefs', actionGroup); + + // a list of actions with their associated link + const actions = [ + { + name: 'open-bug-report', + link: 'https://github.com/aunetx/blur-my-shell/issues' + }, + { + name: 'open-readme', + link: 'https://github.com/aunetx/blur-my-shell' + }, + { + name: 'open-license', + link: 'https://github.com/aunetx/blur-my-shell/blob/master/LICENSE' + }, + { + name: 'donate-github', + link: 'https://github.com/sponsors/aunetx' + }, + { + name: 'donate-kofi', + link: 'https://ko-fi.com/aunetx' + }, + ]; + + actions.forEach(action => { + let act = new Gio.SimpleAction({ name: action.name }); + act.connect( + 'activate', + () => Gtk.show_uri(window, action.link, Gdk.CURRENT_TIME) + ); + actionGroup.add_action(act); + }); +} diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js new file mode 100644 index 0000000..0fac364 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/other.js @@ -0,0 +1,86 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + + +export const Other = GObject.registerClass({ + GTypeName: 'Other', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/other.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'lockscreen_blur', + 'lockscreen_pipeline_choose_row', + + 'screenshot_blur', + 'screenshot_pipeline_choose_row', + + 'window_list_blur', + 'window_list_sigma', + 'window_list_brightness', + + 'coverflow_alt_tab_blur', + 'coverflow_alt_tab_pipeline_choose_row', + + 'hack_level', + 'debug', + 'reset' + ], +}, class Overview extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, pipelines_page) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.lockscreen.settings.bind( + 'blur', this._lockscreen_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._lockscreen_pipeline_choose_row.initialize( + this.preferences.lockscreen, this.pipelines_manager, this.pipelines_page + ); + + this.preferences.screenshot.settings.bind( + 'blur', this._screenshot_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._screenshot_pipeline_choose_row.initialize( + this.preferences.screenshot, this.pipelines_manager, this.pipelines_page + ); + + this.preferences.window_list.settings.bind( + 'blur', this._window_list_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.window_list.settings.bind( + 'sigma', this._window_list_sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.window_list.settings.bind( + 'brightness', this._window_list_brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + + this.preferences.coverflow_alt_tab.settings.bind( + 'blur', this._coverflow_alt_tab_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this._coverflow_alt_tab_pipeline_choose_row.initialize( + this.preferences.coverflow_alt_tab, this.pipelines_manager, this.pipelines_page + ); + + this.preferences.settings.bind( + 'hacks-level', this._hack_level, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.settings.bind( + 'debug', this._debug, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._reset.connect('clicked', () => this.preferences.reset()); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/overview.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/overview.js new file mode 100644 index 0000000..f6fe592 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/overview.js @@ -0,0 +1,59 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + + +export const Overview = GObject.registerClass({ + GTypeName: 'Overview', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/overview.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'overview_blur', + 'pipeline_choose_row', + 'overview_style_components', + + 'appfolder_blur', + 'appfolder_sigma', + 'appfolder_brightness', + 'appfolder_style_dialogs' + ], +}, class Overview extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, pipelines_page) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.overview.settings.bind( + 'blur', this._overview_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._pipeline_choose_row.initialize( + this.preferences.overview, this.pipelines_manager, this.pipelines_page + ); + + this.preferences.overview.settings.bind( + 'style-components', this._overview_style_components, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + + this.preferences.appfolder.settings.bind( + 'blur', this._appfolder_blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.appfolder.settings.bind( + 'sigma', this._appfolder_sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.appfolder.settings.bind( + 'brightness', this._appfolder_brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.appfolder.settings.bind( + 'style-dialogs', this._appfolder_style_dialogs, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js new file mode 100644 index 0000000..c49f323 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/panel.js @@ -0,0 +1,102 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gio from 'gi://Gio'; + + +export const Panel = GObject.registerClass({ + GTypeName: 'Panel', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/panel.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'blur', + 'pipeline_choose_row', + 'mode_static', + 'mode_dynamic', + 'sigma_row', + 'sigma', + 'brightness_row', + 'brightness', + 'unblur_in_overview', + 'force_light_text', + 'override_background', + 'style_panel', + 'override_background_dynamically', + 'hidetopbar_compatibility', + 'dtp_blur_original_panel' + ], +}, class Panel extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, pipelines_page) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.preferences.panel.settings.bind( + 'blur', this._blur, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + + this._pipeline_choose_row.initialize( + this.preferences.panel, this.pipelines_manager, this.pipelines_page + ); + + this.change_blur_mode(this.preferences.panel.STATIC_BLUR, true); + + this._mode_static.connect('toggled', + () => this.preferences.panel.STATIC_BLUR = this._mode_static.active + ); + this.preferences.panel.STATIC_BLUR_changed( + () => this.change_blur_mode(this.preferences.panel.STATIC_BLUR, false) + ); + + this.preferences.panel.settings.bind( + 'sigma', this._sigma, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'brightness', this._brightness, 'value', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'unblur-in-overview', this._unblur_in_overview, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'force-light-text', this._force_light_text, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'override-background', + this._override_background, 'enable-expansion', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'style-panel', this._style_panel, 'selected', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.panel.settings.bind( + 'override-background-dynamically', + this._override_background_dynamically, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.hidetopbar.settings.bind( + 'compatibility', this._hidetopbar_compatibility, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + this.preferences.dash_to_panel.settings.bind( + 'blur-original-panel', this._dtp_blur_original_panel, 'active', + Gio.SettingsBindFlags.DEFAULT + ); + } + + change_blur_mode(is_static_blur, first_run) { + this._mode_static.set_active(is_static_blur); + if (first_run) + this._mode_dynamic.set_active(!is_static_blur); + + this._pipeline_choose_row.set_visible(is_static_blur); + this._sigma_row.set_visible(!is_static_blur); + this._brightness_row.set_visible(!is_static_blur); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines.js new file mode 100644 index 0000000..158ea9a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines.js @@ -0,0 +1,98 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { PipelineGroup } from './pipelines_management/pipeline_group.js'; +import { EffectsDialog } from './pipelines_management/effects_dialog.js'; + + +export const Pipelines = GObject.registerClass({ + GTypeName: 'Pipelines', + Template: GLib.uri_resolve_relative(import.meta.url, '../ui/pipelines.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'add_pipeline' + ], +}, class Pipelines extends Adw.PreferencesPage { + constructor(preferences, pipelines_manager, window) { + super({}); + + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.window = window; + + this.pipelines_map = new Map; + + for (let pipeline_id in this.pipelines_manager.pipelines) + this.add_pipeline(pipeline_id, false); + + this.preferences.connect('reset', _ => { + this.pipelines_map.forEach((_infos, pid) => this.remove_pipeline(pid)); + for (let pipeline_id in this.pipelines_manager.pipelines) + this.add_pipeline(pipeline_id, false); + }); + + this._add_pipeline.connect( + "clicked", + () => this.pipelines_manager.create_pipeline(_("New pipeline")) + ); + + this.pipelines_manager.connect( + "pipeline-created", + (_obj, id, _pipeline) => this.add_pipeline(id, true) + ); + } + + add_pipeline(pipeline_id, scroll_to_bottom) { + let pipeline = this.pipelines_manager.pipelines[pipeline_id]; + let pipeline_group = new PipelineGroup( + this.pipelines_manager, pipeline_id, pipeline, this + ); + + let pipeline_destroyed_id = this.pipelines_manager.connect( + pipeline_id + "::pipeline-destroyed", + () => this.remove_pipeline(pipeline_id) + ); + + let pipeline_renamed_id = this.pipelines_manager.connect( + pipeline_id + "::pipeline-renamed", + (_obj, name) => this.rename_pipeline(pipeline_id, name) + ); + + this.pipelines_map.set(pipeline_id, { + pipeline_group, pipeline_destroyed_id, pipeline_renamed_id + }); + + this.add(pipeline_group); + + // scroll to the bottom of the page + if (scroll_to_bottom) { + this.window.set_visible_page(this); + setTimeout(() => { + const scroll_adjustment = this.get_first_child().get_vadjustment(); + scroll_adjustment.value = scroll_adjustment.get_upper(); + }, 10); + pipeline_group._title.grab_focus(); + } + } + + remove_pipeline(pipeline_id) { + let pipeline_infos = this.pipelines_map.get(pipeline_id); + if (pipeline_infos) { + this.pipelines_manager.disconnect(pipeline_infos.pipeline_destroyed_id); + this.remove(pipeline_infos.pipeline_group); + this.pipelines_map.delete(pipeline_id); + } + } + + rename_pipeline(pipeline_id, name) { + let pipeline_infos = this.pipelines_map.get(pipeline_id); + if (pipeline_infos) + pipeline_infos.pipeline_group.set_title(name.length > 0 ? name : " "); + } + + open_effects_dialog(pipeline_id) { + let dialog = new EffectsDialog(this.pipelines_manager, pipeline_id); + dialog.present(this.window); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effect_row.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effect_row.js new file mode 100644 index 0000000..130edfd --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effect_row.js @@ -0,0 +1,222 @@ +import Adw from 'gi://Adw'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { get_supported_effects } from '../../effects/effects.js'; + + +export const EffectRow = GObject.registerClass({ + GTypeName: 'EffectRow', + InternalChildren: [], +}, class EffectRow extends Adw.ExpanderRow { + constructor(effect, effects_dialog) { + super({}); + + this.SUPPORTED_EFFECTS = get_supported_effects(_); + + this.effect = effect; + this.effects_dialog = effects_dialog; + this.pipeline_id = effects_dialog.pipeline_id; + this.pipelines_manager = effects_dialog.pipelines_manager; + + if (effect.type in this.SUPPORTED_EFFECTS) { + this.set_title(this.SUPPORTED_EFFECTS[effect.type].name); + this.set_subtitle(this.SUPPORTED_EFFECTS[effect.type].description); + this.populate_options(); + } + else { + this._warn(`could not assign effect ${effect.type} to its correct name`); + this.set_title(effect.type); + } + + let prefix_bin = new Gtk.Box({ + spacing: 6 + }); + this.add_prefix(prefix_bin); + + let move_bin = new Gtk.Box({ + orientation: Gtk.Orientation.VERTICAL, + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6 + }); + prefix_bin.append(move_bin); + move_bin.add_css_class('linked'); + + this._move_up_button = new Gtk.Button({ + 'icon-name': 'go-up-symbolic', + 'width-request': 38, + 'height-request': 19 + }); + this._move_down_button = new Gtk.Button({ + 'icon-name': 'go-down-symbolic', + 'width-request': 38, + 'height-request': 19 + }); + this._move_up_button.add_css_class('flat'); + this._move_down_button.add_css_class('flat'); + move_bin.append(this._move_up_button); + move_bin.append(this._move_down_button); + + this._move_up_button.connect('clicked', () => effects_dialog.move_row_by(this, -1)); + this._move_down_button.connect('clicked', () => effects_dialog.move_row_by(this, +1)); + + let remove_button = new Gtk.Button({ + 'icon-name': 'remove-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6, + 'valign': Gtk.Align.CENTER + }); + prefix_bin.append(remove_button); + remove_button.add_css_class('destructive-action'); + + remove_button.connect('clicked', () => effects_dialog.remove_row(this)); + } + + populate_options() { + const editable_params = this.SUPPORTED_EFFECTS[this.effect.type].editable_params; + + if (Object.keys(editable_params).length == 0) + this.enable_expansion = false; + + for (const param_key in editable_params) { + let param = editable_params[param_key]; + let row; + switch (param.type) { + case "integer": + row = new Adw.SpinRow({ + adjustment: new Gtk.Adjustment({ + lower: param.min, + upper: param.max, + step_increment: param.increment + }) + }); + row.adjustment.set_value(this.get_effect_param(param_key)); + row.adjustment.connect( + 'value-changed', () => this.set_effect_param(param_key, row.adjustment.value) + ); + break; + + case "float": + row = new Adw.ActionRow; + let scale = new Gtk.Scale({ + valign: Gtk.Align.CENTER, + hexpand: true, + width_request: 200, + draw_value: true, + value_pos: Gtk.PositionType.RIGHT, + digits: param.digits, + adjustment: new Gtk.Adjustment({ + lower: param.min, + upper: param.max, + step_increment: param.increment, + page_increment: param.big_increment + }) + }); + // TODO check if it's a good idea to set the default parameter, as the "good" + // value really change depending on the user wallpaper... if so, do for dynamic + // blur too + scale.add_mark( + this.get_default_effect_param(param_key), Gtk.PositionType.BOTTOM, null + ); + row.add_suffix(scale); + scale.adjustment.set_value(this.get_effect_param(param_key)); + scale.adjustment.connect( + 'value-changed', () => this.set_effect_param(param_key, scale.adjustment.value) + ); + break; + + case "boolean": + row = new Adw.SwitchRow; + row.set_active(this.get_effect_param(param_key)); + row.connect( + 'notify::active', () => this.set_effect_param(param_key, row.active) + ); + break; + + case "dropdown": + row = new Adw.ComboRow({ model: new Gtk.StringList }); + param.options.forEach(option => row.model.append(option)); + row.selected = this.get_effect_param(param_key); + row.connect( + 'notify::selected', () => this.set_effect_param(param_key, row.selected) + ); + break; + + case "rgba": + row = new Adw.ActionRow; + let color_button = new Gtk.ColorButton({ + valign: Gtk.Align.CENTER, + width_request: 75, + height_request: 45, + show_editor: true, + use_alpha: true + }); + row.add_suffix(color_button); + // set original color + let c = color_button.get_rgba().copy(); + [c.red, c.green, c.blue, c.alpha] = this.get_effect_param(param_key); + color_button.set_rgba(c); + // update on on 'color-set' + color_button.connect( + 'color-set', () => { + let c = color_button.get_rgba(); + this.set_effect_param(param_key, [c.red, c.green, c.blue, c.alpha]); + } + ); + break; + + default: + row = new Adw.ActionRow; + break; + } + row.set_title(param.name); + row.set_subtitle(param.description); + this.add_row(row); + } + } + + get_effect_param(key) { + let effects = this.pipelines_manager.pipelines[this.pipeline_id].effects; + const gsettings_effect = effects.find(e => e.id == this.effect.id); + + if ('params' in gsettings_effect && key in gsettings_effect.params) + return gsettings_effect.params[key]; + else + return this.get_default_effect_param(key); + } + + get_default_effect_param(key) { + return this.SUPPORTED_EFFECTS[this.effect.type].class.default_params[key]; + } + + set_effect_param(key, value) { + // we must pay attention not to change the effects in the pipelines manager before updating + // it in gsettings, else it won't be updated (or every effect will be) + let effects = this.pipelines_manager.pipelines[this.pipeline_id].effects; + const effect_index = effects.findIndex(e => e.id == this.effect.id); + + if (effect_index >= 0) { + effects[effect_index] = { + ...this.effect, params: { ...this.effect.params } + }; + effects[effect_index].params[key] = value; + this.effect = effects[effect_index]; + } + else + this._warn(`effect not found when setting key ${key}`); + + this.pipelines_manager.update_pipeline_effects(this.pipeline_id, effects, false); + } + + _warn(str) { + console.warn( + `[Blur my Shell > effect row] pipeline '${this.pipeline_id}',` + + ` effect '${this.effect.id}': ${str}` + ); + } +}); diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effects_dialog.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effects_dialog.js new file mode 100644 index 0000000..222a92e --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/effects_dialog.js @@ -0,0 +1,174 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import Gio from 'gi://Gio'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { EffectRow } from './effect_row.js'; +import { get_effects_groups, get_supported_effects } from '../../effects/effects.js'; + +export const EffectsDialog = GObject.registerClass({ + GTypeName: 'EffectsDialog', + Template: GLib.uri_resolve_relative(import.meta.url, '../../ui/effects-dialog.ui', GLib.UriFlags.NONE), + InternalChildren: [ + "add_effect", + "add_effect_alt_menu", + "effects_list" + ], +}, class EffectsDialog extends Adw.PreferencesDialog { + constructor(pipelines_manager, pipeline_id) { + super({}); + + this.EFFECTS_GROUPS = get_effects_groups(_); + this.SUPPORTED_EFFECTS = get_supported_effects(_); + + this.pipelines_manager = pipelines_manager; + this.pipeline_id = pipeline_id; + + let pipeline = pipelines_manager.pipelines[pipeline_id]; + + this.set_title(pipeline.name.length > 0 ? _(`Effects for "${pipeline.name}"`) : _("Effects")); + + pipeline.effects.forEach(effect => { + const effect_row = new EffectRow(effect, this); + this._effects_list.add(effect_row); + this.update_rows_insensitive_mover(effect_row); + }); + + // setup advanced effects chooser action + this.show_advanced_effects = false; + let action_group = new Gio.SimpleActionGroup(); + this.insert_action_group('effects-dialog', action_group); + let advanced_effects_action = Gio.SimpleAction.new_stateful( + 'advanced-effects-bool', + null, + GLib.Variant.new_boolean(this.show_advanced_effects) + ); + advanced_effects_action.connect( + 'change-state', + (_, state) => { + this.show_advanced_effects = state.get_boolean(); + this.build_effects_chooser(); + advanced_effects_action.set_state(state); + } + ); + action_group.add_action(advanced_effects_action); + + this.build_effects_chooser(); + this._add_effect.connect('clicked', () => this.effects_chooser_dialog.present(this)); + } + + build_effects_chooser() { + this.effects_chooser_dialog = new Adw.Dialog({ + presentation_mode: Adw.DialogPresentationMode.BOTTOM_SHEET, + content_width: 450 + }); + + let page = new Adw.PreferencesPage; + this.effects_chooser_dialog.set_child(page); + + for (const effects_group in this.EFFECTS_GROUPS) { + const group_infos = this.EFFECTS_GROUPS[effects_group]; + + let group = new Adw.PreferencesGroup({ + title: group_infos.name + }); + page.add(group); + + for (const effect_type of group_infos.contains) { + if (!(effect_type in this.SUPPORTED_EFFECTS)) + continue; + + if (!this.show_advanced_effects && this.SUPPORTED_EFFECTS[effect_type].is_advanced) + continue; + + let action_row = new Adw.ActionRow({ + title: this.SUPPORTED_EFFECTS[effect_type].name, + subtitle: this.SUPPORTED_EFFECTS[effect_type].description + }); + let select_button = new Gtk.Button({ + 'icon-name': 'select-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6 + }); + group.add(action_row); + + select_button.add_css_class('flat'); + action_row.add_suffix(select_button); + action_row.set_activatable_widget(select_button); + select_button.connect('clicked', () => { + this.append_effect(effect_type); + this.effects_chooser_dialog.close(); + }); + } + } + } + + append_effect(effect_type) { + const effect = { + type: effect_type, id: "effect_" + ("" + Math.random()).slice(2, 16) + }; + this.pipelines_manager.update_pipeline_effects( + this.pipeline_id, + [...this.pipelines_manager.pipelines[this.pipeline_id].effects, effect] + ); + + const effect_row = new EffectRow(effect, this); + this._effects_list.add(effect_row); + this.move_row_by(effect_row, 0); + this.update_rows_insensitive_mover(effect_row); + } + + move_row_by(row, number) { + const effects = this.pipelines_manager.pipelines[this.pipeline_id].effects; + const effect_index = effects.findIndex(e => e.id == row.effect.id); + + if (effect_index >= 0) { + effects.splice(effect_index, 1); + effects.splice(effect_index + number, 0, row.effect); + + const listbox = row.get_parent(); + listbox.set_sort_func((row_a, row_b) => { + const id_a = effects.findIndex(e => e.id == row_a.effect.id); + const id_b = effects.findIndex(e => e.id == row_b.effect.id); + return id_a > id_b; + }); + + this.update_rows_insensitive_mover(row); + + this.pipelines_manager.update_pipeline_effects( + this.pipeline_id, effects + ); + } + } + + update_rows_insensitive_mover(any_row) { + if (this._insensitive_top) + this._insensitive_top.set_sensitive(true); + if (this._insensitive_bottom) + this._insensitive_bottom.set_sensitive(true); + + const listbox = any_row.get_parent(); + this._insensitive_top = listbox.get_first_child()._move_up_button; + this._insensitive_top?.set_sensitive(false); + this._insensitive_bottom = listbox.get_last_child()._move_down_button; + this._insensitive_bottom?.set_sensitive(false); + } + + remove_row(row) { + const effects = this.pipelines_manager.pipelines[this.pipeline_id].effects; + const effect_index = effects.findIndex(e => e.id == row.effect.id); + + if (effect_index >= 0) { + effects.splice(effect_index, 1); + this.pipelines_manager.update_pipeline_effects( + this.pipeline_id, effects + ); + } + + this._effects_list.remove(row); + } +}); diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js new file mode 100644 index 0000000..e0c5165 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_choose_row.js @@ -0,0 +1,106 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + + +export const PipelineChooseRow = GObject.registerClass({ + GTypeName: 'PipelineChooseRow', + Template: GLib.uri_resolve_relative(import.meta.url, '../../ui/pipeline-choose-row.ui', GLib.UriFlags.NONE), + InternalChildren: [ + 'pipeline_choose', + 'pipeline_model', + 'pipeline_edit' + ], +}, class PipelineChooseRow extends Adw.ActionRow { + initialize(preferences, pipelines_manager, pipelines_page) { + this.preferences = preferences; + this.pipelines_manager = pipelines_manager; + this.pipelines_page = pipelines_page; + + this.create_pipelines_list(); + + // display the correct pipeline name in the drop-down instead of their ids + const closure_func = string_object => { + const pipeline_id = string_object.get_string(); + if (pipeline_id == 'create_new') + return _("Create new pipeline"); + if (pipeline_id in this.pipelines_manager.pipelines) + return this.pipelines_manager.pipelines[pipeline_id].name; + else + return ""; + }; + + const expression = new Gtk.ClosureExpression(GObject.TYPE_STRING, closure_func, []); + this._pipeline_choose.expression = expression; + + // TODO fix the expression not being re-evaluated other than by setting it again + this.pipelines_manager.connect( + 'pipeline-names-changed', + () => this._pipeline_choose.expression = new Gtk.ClosureExpression( + GObject.TYPE_STRING, closure_func, [] + ) + ); + + this.preferences.PIPELINE_changed(() => this.on_settings_pipeline_changed()); + + this.pipelines_manager.connect('pipeline-list-changed', () => this.create_pipelines_list()); + + this._pipeline_choose.connect('notify::selected', () => this.on_selected_pipeline_changed()); + + this._pipeline_edit.connect( + 'clicked', + () => this.pipelines_page.open_effects_dialog(this.preferences.PIPELINE) + ); + } + + on_selected_pipeline_changed() { + if (!this._pipeline_choose.selected_item || this._is_creating_pipelines_list) + return; + + const pipeline_id = this._pipeline_choose.selected_item.get_string(); + if (pipeline_id == 'create_new') { + const id = this.pipelines_manager.create_pipeline(_("New pipeline")); + this.preferences.PIPELINE = id; + } + else + this.preferences.PIPELINE = pipeline_id; + } + + on_settings_pipeline_changed() { + for (let i = 0; i < this._pipeline_model.n_items; i++) { + const pipeline_id = this._pipeline_model.get_string(i); + // if we have more pipelines than we should have: rebuild... + // that is the case when resetting the preferences for example + if (!(pipeline_id in this.pipelines_manager)) { + this.create_pipelines_list(); + return; + } + if (pipeline_id == this.preferences.PIPELINE) + this._pipeline_choose.set_selected(i); + } + } + + create_pipelines_list() { + // prevent the pipeline selector from being updated while re-creating the list + this._is_creating_pipelines_list = true; + + // remove ancient items + this._pipeline_model.splice(0, this._pipeline_model.n_items, null); + + // add new ones + let i = 0; + for (let pipeline_id in this.pipelines_manager.pipelines) { + this._pipeline_model.append(pipeline_id); + if (pipeline_id == this.preferences.PIPELINE) + this._pipeline_choose.set_selected(i); + i++; + } + this._pipeline_model.append('create_new'); + + // now update the drop-down selector + this._is_creating_pipelines_list = false; + this.on_selected_pipeline_changed(); + } +});
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_group.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_group.js new file mode 100644 index 0000000..627b576 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/preferences/pipelines_management/pipeline_group.js @@ -0,0 +1,99 @@ +import Adw from 'gi://Adw'; +import GLib from 'gi://GLib'; +import GObject from 'gi://GObject'; +import Gtk from 'gi://Gtk'; +import { gettext as _ } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { get_supported_effects } from '../../effects/effects.js'; + + +export const PipelineGroup = GObject.registerClass({ + GTypeName: 'PipelineGroup', + Template: GLib.uri_resolve_relative(import.meta.url, '../../ui/pipeline-group.ui', GLib.UriFlags.NONE), + InternalChildren: [ + "title", + "effects_description_row", + "manage_effects" + ], +}, class PipelineGroup extends Adw.PreferencesGroup { + constructor(pipelines_manager, pipeline_id, pipeline, pipelines_page) { + super({}); + + this.SUPPORTED_EFFECTS = get_supported_effects(_); + + this._pipelines_manager = pipelines_manager; + this._pipelines_page = pipelines_page; + this._pipeline_id = pipeline_id; + + // set the description + this.set_description(_(`Pipeline id: "${pipeline_id}"`)); + + // set the title and connect it to the text entry + this.set_title(pipeline.name.length > 0 ? pipeline.name : " "); + this._title.set_text(pipeline.name); + this._title.connect( + 'changed', + () => pipelines_manager.rename_pipeline(pipeline_id, this._title.get_text()) + ); + + // the bin containing the actions + let prefix_bin = new Gtk.Box; + prefix_bin.add_css_class('linked'); + this._title.add_prefix(prefix_bin); + + // add a 'remove' button if we are not the default pipeline + if (pipeline_id != "pipeline_default") { + let remove_button = new Gtk.Button({ + 'icon-name': 'remove-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6 + }); + remove_button.add_css_class('destructive-action'); + prefix_bin.append(remove_button); + remove_button.connect('clicked', () => pipelines_manager.delete_pipeline(pipeline_id)); + } + // add a 'duplicate' button + let duplicate_button = new Gtk.Button({ + 'icon-name': 'duplicate-row-symbolic', + 'width-request': 38, + 'height-request': 38, + 'margin-top': 6, + 'margin-bottom': 6 + }); + prefix_bin.append(duplicate_button); + duplicate_button.connect('clicked', () => pipelines_manager.duplicate_pipeline(pipeline_id)); + + this.update_effects_description_row(); + this._pipelines_manager.connect( + pipeline_id + '::pipeline-updated', + () => this.update_effects_description_row() + ); + + this._manage_effects.connect( + 'clicked', + () => pipelines_page.open_effects_dialog(pipeline_id) + ); + } + + update_effects_description_row() { + const effects = this._pipelines_manager.pipelines[this._pipeline_id].effects; + + if (effects.length == 0) + this._effects_description_row.set_title(_("No effect")); + else if (effects.length == 1) + this._effects_description_row.set_title(_("1 effect")); + else + this._effects_description_row.set_title(_(`${effects.length} effects`)); + + let subtitle = ""; + effects.forEach(effect => { + if (effect.type in this.SUPPORTED_EFFECTS) + subtitle += _(`${this.SUPPORTED_EFFECTS[effect.type].name}, `); + else + subtitle += _("Unknown effect, "); + }); + this._effects_description_row.set_subtitle(subtitle.slice(0, -2)); + } +}); diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/prefs.js b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/prefs.js new file mode 100644 index 0000000..43c4889 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/prefs.js @@ -0,0 +1,51 @@ +import Gdk from 'gi://Gdk'; +import Gtk from 'gi://Gtk'; +import { ExtensionPreferences } from 'resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js'; + +import { update_from_old_settings } from './conveniences/settings_updater.js'; +import { PipelinesManager } from './conveniences/pipelines_manager.js'; +import { Settings } from './conveniences/settings.js'; +import { KEYS } from './conveniences/keys.js'; + +import { addMenu } from './preferences/menu.js'; +import { Pipelines } from './preferences/pipelines.js'; +import { Panel } from './preferences/panel.js'; +import { Overview } from './preferences/overview.js'; +import { Dash } from './preferences/dash.js'; +import { Applications } from './preferences/applications.js'; +import { Other } from './preferences/other.js'; + +import './preferences/pipelines_management/pipeline_choose_row.js'; + + +export default class BlurMyShellPreferences extends ExtensionPreferences { + constructor(metadata) { + super(metadata); + + // load the icon theme + let iconPath = this.dir.get_child("icons").get_path(); + let iconTheme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default()); + iconTheme.add_search_path(iconPath); + } + + fillPreferencesWindow(window) { + addMenu(window); + + // update from old settings, very important for hacks level specifically + update_from_old_settings(this.getSettings()); + + const preferences = new Settings(KEYS, this.getSettings()); + const pipelines_manager = new PipelinesManager(preferences); + + const pipelines_page = new Pipelines(preferences, pipelines_manager, window); + + window.add(pipelines_page); + window.add(new Panel(preferences, pipelines_manager, pipelines_page)); + window.add(new Overview(preferences, pipelines_manager, pipelines_page)); + window.add(new Dash(preferences, pipelines_manager, pipelines_page)); + window.add(new Applications(preferences, window, pipelines_manager, pipelines_page)); + window.add(new Other(preferences, pipelines_manager, pipelines_page)); + + window.search_enabled = true; + } +} diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/gschemas.compiled b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/gschemas.compiled Binary files differnew file mode 100644 index 0000000..c2b6708 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/gschemas.compiled diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml new file mode 100644 index 0000000..7526e30 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/schemas/org.gnome.shell.extensions.blur-my-shell.gschema.xml @@ -0,0 +1,595 @@ +<?xml version="1.0" encoding="UTF-8"?> +<schemalist> + <!-- GENERAL --> + <schema id="org.gnome.shell.extensions.blur-my-shell" + path="/org/gnome/shell/extensions/blur-my-shell/"> + <!-- SETTINGS VERSION --> + <key type="i" name="settings-version"> + <default>1</default> + <summary>The version of the settings to update from.</summary> + </key> + <!-- PIPELINES --> + <key type="a{sa{sv}}" name="pipelines"> + <default> <![CDATA[ + { + 'pipeline_default': { + 'name': <'Default'>, + 'effects': <[ + <{ + 'type': <'native_static_gaussian_blur'>, + 'id': <'effect_000000000000'>, + 'params': <{ + 'radius': <30>, + 'brightness': <0.6> + }> + }> + ]> + }, + 'pipeline_default_rounded': { + 'name': <'Default rounded'>, + 'effects': <[ + <{ + 'type': <'native_static_gaussian_blur'>, + 'id': <'effect_000000000001'>, + 'params': <{ + 'radius': <30>, + 'brightness': <0.6> + }> + }>, + <{ + 'type': <'corner'>, + 'id': <'effect_000000000002'>, + 'params': <{ + 'radius': <24> + }> + }> + ]> + } + } + ]]></default> + <summary>A dictionnary describing the different pipelines and their effects.</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Global gaussian sigma to use</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>0.6</default> + <summary>Global brightness to use</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + <!-- COLOR AND NOISE --> + <key type="b" name="color-and-noise"> + <default>true</default> + <summary>Boolean, controls wether or not the color and noise effects are in use globally</summary> + </key> + <!-- HACKS LEVEL --> + <key type="i" name="hacks-level"> + <default>1</default> + <summary>Level of hacks to use (from 0 to 2, 2 disabling clipped redraws entirely)</summary> + </key> + <!-- DEBUG --> + <key type="b" name="debug"> + <default>false</default> + <summary>Boolean, set to true to activate debug mode (more verbose journalctl logs)</summary> + </key> + + <child name='overview' schema='org.gnome.shell.extensions.blur-my-shell.overview'></child> + <child name='appfolder' schema='org.gnome.shell.extensions.blur-my-shell.appfolder'></child> + <child name='panel' schema='org.gnome.shell.extensions.blur-my-shell.panel'></child> + <child name='dash-to-dock' schema='org.gnome.shell.extensions.blur-my-shell.dash-to-dock'></child> + <child name='applications' schema='org.gnome.shell.extensions.blur-my-shell.applications'></child> + <child name='screenshot' schema='org.gnome.shell.extensions.blur-my-shell.screenshot'></child> + <child name='lockscreen' schema='org.gnome.shell.extensions.blur-my-shell.lockscreen'></child> + <child name='window-list' schema='org.gnome.shell.extensions.blur-my-shell.window-list'></child> + <child name='coverflow-alt-tab' schema='org.gnome.shell.extensions.blur-my-shell.coverflow-alt-tab'></child> + <child name='hidetopbar' schema='org.gnome.shell.extensions.blur-my-shell.hidetopbar'></child> + <child name='dash-to-panel' schema='org.gnome.shell.extensions.blur-my-shell.dash-to-panel'></child> + </schema> + + <!-- OVERVIEW --> + <schema id="org.gnome.shell.extensions.blur-my-shell.overview" + path="/org/gnome/shell/extensions/blur-my-shell/overview/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>true</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- PIPELINE --> + <key type="s" name="pipeline"> + <default>"pipeline_default"</default> + <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary> + </key> + <!-- CUSTOMIZE --> + <key type="b" name="customize"> + <default>false</default> + <summary>Boolean, whether to customize the blur effect sigma/brightness or use general values</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Gaussian sigma to use for the blur effect</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>0.6</default> + <summary>Brightness to use for the blur effect</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + <!-- STYLE COMPONENTS --> + <key type="i" name="style-components"> + <default>1</default> + <summary>Enum to select the style of the components in overview (0 not styled, 1 light, 2 dark, 3 transparent)</summary> + </key> + </schema> + + <!-- APPFOLDER --> + <schema id="org.gnome.shell.extensions.blur-my-shell.appfolder" + path="/org/gnome/shell/extensions/blur-my-shell/appfolder/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>true</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- CUSTOMIZE --> + <key type="b" name="customize"> + <default>false</default> + <summary>Boolean, whether to customize the blur effect sigma/brightness or use general values</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Gaussian sigma to use for the blur effect</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>0.6</default> + <summary>Brightness to use for the blur effect</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + <!-- STYLE DIALOGS --> + <key type="i" name="style-dialogs"> + <default>1</default> + <summary>Enum to select the style of the appfolder dialogs (0 not styled, 1 transparent, 2 light, 3 dark)</summary> + </key> + </schema> + + <!-- PANEL --> + <schema id="org.gnome.shell.extensions.blur-my-shell.panel" + path="/org/gnome/shell/extensions/blur-my-shell/panel/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>true</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- PIPELINE --> + <key type="s" name="pipeline"> + <default>"pipeline_default"</default> + <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary> + </key> + <!-- CUSTOMIZE --> + <key type="b" name="customize"> + <default>false</default> + <summary>Boolean, whether to customize the blur effect sigma/brightness or use general values</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Gaussian sigma to use for the blur effect</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>0.6</default> + <summary>Brightness to use for the blur effect</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + <!-- STATIC BLUR --> + <key type="b" name="static-blur"> + <default>true</default> + <summary>Boolean, whether to use a static or dynamic blur for this component</summary> + </key> + <!-- UNBLUR IN OVERVIEW --> + <key type="b" name="unblur-in-overview"> + <default>true</default> + <summary>Boolean, whether to disable blur from this component when opening the overview or not</summary> + </key> + <!-- FORCE LIGHT TEXT --> + <key type="b" name="force-light-text"> + <default>false</default> + <summary>Boolean, whether or not to force the panel to have light text, useful when using light theme</summary> + </key> + <!-- OVERRIDE BACKGROUND --> + <key type="b" name="override-background"> + <default>true</default> + <summary>Boolean, whether to override the background or not</summary> + </key> + <!-- STYLE PANEL --> + <key type="i" name="style-panel"> + <default>0</default> + <summary>Enum to select the style of the panel (0 transparent, 1 light, 2 dark, 3 contrasted)</summary> + </key> + <!-- UNBLUR DYNAMICALLY --> + <key type="b" name="override-background-dynamically"> + <default>false</default> + <summary>Boolean, whether to disable blur from this component when a window is close to the panel</summary> + </key> + </schema> + + <!-- DASH TO DOCK --> + <schema id="org.gnome.shell.extensions.blur-my-shell.dash-to-dock" + path="/org/gnome/shell/extensions/blur-my-shell/dash-to-dock/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>true</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- PIPELINE --> + <key type="s" name="pipeline"> + <default>"pipeline_default_rounded"</default> + <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary> + </key> + <!-- CUSTOMIZE --> + <key type="b" name="customize"> + <default>false</default> + <summary>Boolean, whether to customize the blur effect sigma/brightness or use general values</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Gaussian sigma to use for the blur effect</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>0.6</default> + <summary>Brightness to use for the blur effect</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + <!-- STATIC BLUR --> + <key type="b" name="static-blur"> + <default>true</default> + <summary>Boolean, whether to use static or dynamic blur for this component</summary> + </key> + <!-- OVERRIDE BACKGROUND --> + <key type="b" name="override-background"> + <default>true</default> + <summary>Boolean, whether to override the background or not</summary> + </key> + <!-- STYLE DASH TO DOCK --> + <key type="i" name="style-dash-to-dock"> + <default>0</default> + <summary>Enum to select the style of dash to dock (0 transparent, 1 light, 2 dark)</summary> + </key> + <!-- UNBLUR IN OVERVIEW --> + <key type="b" name="unblur-in-overview"> + <default>false</default> + <summary>Boolean, whether to disable blur from this component when opening the overview or not</summary> + </key> + <!-- CORNER RADIUS --> + <key type="i" name="corner-radius"> + <default>12</default> + <summary>Radius for the corner rounding effect</summary> + </key> + </schema> + + <!-- APPLICATIONS --> + <schema id="org.gnome.shell.extensions.blur-my-shell.applications" + path="/org/gnome/shell/extensions/blur-my-shell/applications/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>false</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- PIPELINE --> + <key type="s" name="pipeline"> + <default>"pipeline_default"</default> + <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary> + </key> + <!-- STATIC BLUR --> + <key type="b" name="static-blur"> + <default>false</default> + <summary>Boolean, whether to use static or dynamic blur for this component</summary> + </key> + <!-- CUSTOMIZE --> + <key type="b" name="customize"> + <default>true</default> + <summary>Boolean, whether to customize the blur effect sigma/brightness or use general values</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Gaussian sigma to use for the blur effect</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>1.</default> + <summary>Brightness to use for the blur effect</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + <!-- OPACITY --> + <key type="i" name="opacity"> + <default>215</default> + <summary>Opacity of the window actor on top of the blur effect</summary> + </key> + <!-- DYNAMIC OPACITY --> + <key type="b" name="dynamic-opacity"> + <default>true</default> + <summary>Wether or not to make the focused window opaque</summary> + </key> + <!-- BLUR ON OVERVIEW --> + <key type="b" name="blur-on-overview"> + <default>false</default> + <summary>Wether or not to blur applications on the overview</summary> + </key> + <!-- ENABLE ALL --> + <key type="b" name="enable-all"> + <default>false</default> + <summary>Wether or not to blur all applications by default</summary> + </key> + <!-- WHITELIST --> + <key type="as" name="whitelist"> + <default>[]</default> + <summary>List of applications to blur</summary> + </key> + <!-- BLACKLIST --> + <key type="as" name="blacklist"> + <default>["Plank","com.desktop.ding", "Conky"]</default> + <summary>List of applications not to blur</summary> + </key> + </schema> + + <!-- SCREENSHOT --> + <schema id="org.gnome.shell.extensions.blur-my-shell.screenshot" + path="/org/gnome/shell/extensions/blur-my-shell/screenshot/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>true</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- PIPELINE --> + <key type="s" name="pipeline"> + <default>"pipeline_default"</default> + <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary> + </key> + <!-- CUSTOMIZE --> + <key type="b" name="customize"> + <default>false</default> + <summary>Boolean, whether to customize the blur effect sigma/brightness or use general values</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Gaussian sigma to use for the blur effect</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>0.6</default> + <summary>Brightness to use for the blur effect</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + </schema> + + <!-- LOCKSCREEN --> + <schema id="org.gnome.shell.extensions.blur-my-shell.lockscreen" + path="/org/gnome/shell/extensions/blur-my-shell/lockscreen/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>true</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- PIPELINE --> + <key type="s" name="pipeline"> + <default>"pipeline_default"</default> + <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary> + </key> + <!-- CUSTOMIZE --> + <key type="b" name="customize"> + <default>false</default> + <summary>Boolean, whether to customize the blur effect sigma/brightness or use general values</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Gaussian sigma to use for the blur effect</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>0.6</default> + <summary>Brightness to use for the blur effect</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + </schema> + + <!-- WINDOW LIST --> + <schema id="org.gnome.shell.extensions.blur-my-shell.window-list" + path="/org/gnome/shell/extensions/blur-my-shell/window-list/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>true</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- PIPELINE --> + <key type="s" name="pipeline"> + <default>"pipeline_default"</default> + <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary> + </key> + <!-- CUSTOMIZE --> + <key type="b" name="customize"> + <default>false</default> + <summary>Boolean, whether to customize the blur effect sigma/brightness or use general values</summary> + </key> + <!-- SIGMA --> + <key type="i" name="sigma"> + <default>30</default> + <summary>Gaussian sigma to use for the blur effect</summary> + </key> + <!-- BRIGHTNESS --> + <key type="d" name="brightness"> + <default>0.6</default> + <summary>Brightness to use for the blur effect</summary> + </key> + <!-- COLOR --> + <key type="(dddd)" name="color"> + <default>(0.,0.,0.,0.)</default> + <summary>Color to mix with the blur effect</summary> + </key> + <!-- NOISE AMOUNT --> + <key type="d" name="noise-amount"> + <default>0.</default> + <summary>Amount of noise to add to the blur effect</summary> + </key> + <!-- NOISE LIGHTNESS --> + <key type="d" name="noise-lightness"> + <default>0.</default> + <summary>Lightness of the noise added to the blur effect</summary> + </key> + </schema> + + <!-- COVERFLOW ALT-TAB --> + <schema id="org.gnome.shell.extensions.blur-my-shell.coverflow-alt-tab" + path="/org/gnome/shell/extensions/blur-my-shell/coverflow-alt-tab/"> + <!-- BLUR --> + <key type="b" name="blur"> + <default>true</default> + <summary>Boolean, whether to blur activate the blur for this component or not</summary> + </key> + <!-- PIPELINE --> + <key type="s" name="pipeline"> + <default>"pipeline_default"</default> + <summary>String, the name of the pipeline to use. It must exist, else "pipeline_default" will be used</summary> + </key> + </schema> + + <!-- HIDETOPBAR --> + <schema id="org.gnome.shell.extensions.blur-my-shell.hidetopbar" + path="/org/gnome/shell/extensions/blur-my-shell/hidetopbar/"> + <!-- COMPATIBILITY --> + <key type="b" name="compatibility"> + <default>false</default> + <summary>Boolean, whether to try compatibility with hidetopbar@mathieu.bidon.ca or not</summary> + </key> + </schema> + + <!-- DASH TO PANEL --> + <schema id="org.gnome.shell.extensions.blur-my-shell.dash-to-panel" + path="/org/gnome/shell/extensions/blur-my-shell/dash-to-panel/"> + <!-- COMPATIBILITY --> + <key type="b" name="blur-original-panel"> + <default>true</default> + <summary>Boolean, whether to blur the original panel (if option selected) with Dash to Panel</summary> + </key> + </schema> +</schemalist>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/stylesheet.css b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/stylesheet.css new file mode 100644 index 0000000..b61e530 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/stylesheet.css @@ -0,0 +1,573 @@ +/*** PANEL ***/ + +/* +* `.transparent-panel` +*/ +#panel.transparent-panel { + background: transparent; + transition-duration: 500ms; +} + +/* +* `.dark-panel` +*/ +#panel.dark-panel { + background-color: rgba(100, 100, 100, 0.35); + box-shadow: none; + transition-duration: 500ms; +} + +/* +* `.light-panel` +*/ +#panel.light-panel { + background-color: rgba(200, 200, 200, 0.2); + box-shadow: none; + transition-duration: 500ms; +} + +/* +* `.contrasted-panel` +*/ +#panel.contrasted-panel { + background-color: transparent; + box-shadow: none; + transition-duration: 500ms; +} + +.contrasted-panel .panel-button, +.contrasted-panel .clock, +.contrasted-panel .clock-display StIcon { + color: #ffffff; + border-radius: 14px; + border: 3px solid transparent; + background-color: rgba(0, 0, 0, 0.8); + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.03); +} + + +.contrasted-panel .clock-display StIcon { + padding: 8px; + margin: 0; +} + +.contrasted-panel .panel-button:hover, +.contrasted-panel .panel-button:hover .clock { + color: #ffffff; + background-color: rgba(0, 0, 0, 0.8); +} + +.contrasted-panel .clock-display { + background-color: transparent !important; + box-shadow: none !important; + border: none !important; +} + +.contrasted-panel .clock { + margin: 0 !important; +} + + +/*** DASH-TO-DOCK ***/ + +/* +* `.transparent-dash` +*/ +.transparent-dash .dash-background { + background-color: transparent !important; +} + +/* +* `.light-dash` +*/ +.light-dash .dash-background { + background-color: rgba(200, 200, 200, 0.2) !important; +} + +/* +* `.dark-dash` +*/ +.dark-dash .dash-background { + background-color: rgba(100, 100, 100, 0.35) !important; +} + + +/*** OVERVIEW ***/ + +/* +* Add transparency to the workspace animation (between workspaces) +*/ +.blurred-overview .workspace-animation { + background-color: transparent !important; +} + + +/* +* `.overview-components-transparent` +*/ + +.overview-components-transparent .workspace-thumbnail { + border: 1px solid rgba(100, 100, 100, 0.35); +} + +.overview-components-transparent .search-entry { + color: white; + background-color: rgba(0, 0, 0, 0); + border-color: transparent; + box-shadow: none; +} + +.overview-components-transparent .search-entry .search-entry-icon { + color: rgba(255, 255, 255, 0.65); +} + +.overview-components-transparent .overview-tile, +.overview-components-transparent .overview-icon, +.overview-components-transparent .grid-search-result, +.overview-components-transparent .list-search-result, +.overview-components-transparent .search-provider-icon, +/* prevents the extension from interfering with Just Perfection */ +.overview-components-transparent.just-perfection .search-section-content, +/* remove the rectangular background from the dash */ +.overview-components-transparent #dash .overview-tile, +.overview-components-transparent #dashtopanelScrollview .overview-tile { + background-color: transparent; +} + +.overview-components-transparent .workspace-thumbnail, +.overview-components-transparent .search-section-content, +.overview-components-transparent .overview-tile.app-folder, +.overview-components-transparent .page-navigation-arrow, +.overview-components-transparent .app-folder-dialog .icon-button, +/* this shouldn't apply to Dash to Dock */ +.overview-components-transparent StBoxLayout>StWidget>#dash>.dash-background { + background-color: rgba(0, 0, 0, 0); +} + +.overview-components-transparent .overview-tile:hover, +.overview-components-transparent .overview-tile:focus, +.overview-components-transparent .overview-tile:selected, +.overview-components-transparent .overview-tile:highlighted, +.overview-components-transparent .grid-search-result:hover, +.overview-components-transparent .grid-search-result:focus, +.overview-components-transparent .grid-search-result:selected, +.overview-components-transparent .grid-search-result:highlighted, +.overview-components-transparent .list-search-result:hover, +.overview-components-transparent .list-search-result:focus, +.overview-components-transparent .list-search-result:selected, +.overview-components-transparent .list-search-result:highlighted, +.overview-components-transparent .search-provider-icon:hover, +.overview-components-transparent .search-provider-icon:focus, +.overview-components-transparent .page-navigation-arrow:hover, +.overview-components-transparent .page-navigation-arrow:focus, +.overview-components-transparent .app-folder-dialog .icon-button:hover, +.overview-components-transparent .app-folder-dialog .icon-button:focus, +.overview-components-transparent #dash .overview-tile:hover .overview-icon, +.overview-components-transparent #dash .overview-tile:focus .overview-icon, +.overview-components-transparent #dash .show-apps:hover .overview-icon, +.overview-components-transparent #dash .show-apps:focus .overview-icon { + background-color: rgba(230, 230, 230, 0.08); +} + +.overview-components-transparent .overview-tile:active, +.overview-components-transparent .overview-tile:focus:hover, +.overview-components-transparent .overview-tile:drop, +.overview-components-transparent .overview-tile:selected:hover, +.overview-components-transparent .overview-tile:highlighted:hover, +.overview-components-transparent .grid-search-result:active, +.overview-components-transparent .grid-search-result:focus:hover, +.overview-components-transparent .grid-search-result:selected:hover, +.overview-components-transparent .grid-search-result:highlighted:hover, +.overview-components-transparent .list-search-result:active, +.overview-components-transparent .list-search-result:focus:hover, +.overview-components-transparent .list-search-result:selected:hover, +.overview-components-transparent .list-search-result:highlighted:hover, +.overview-components-transparent .search-provider-icon:active, +.overview-components-transparent .search-provider-icon:focus:hover, +.overview-components-transparent .page-navigation-arrow:active, +.overview-components-transparent .page-navigation-arrow:focus:hover, +.overview-components-transparent .app-folder-dialog .icon-button:active, +.overview-components-transparent .app-folder-dialog .icon-button:focus:hover, +.overview-components-transparent #dash .overview-tile:active .overview-icon, +.overview-components-transparent #dash .overview-tile:focus:hover .overview-icon, +.overview-components-transparent #dash .overview-tile:drop .overview-icon, +.overview-components-transparent #dash .show-apps:checked .overview-icon { + background-color: rgba(230, 230, 230, 0.12); +} + +.overview-components-transparent .overview-tile:focus:active, +.overview-components-transparent .overview-tile:selected:active, +.overview-components-transparent .overview-tile:highlighted:active, +.overview-components-transparent .grid-search-result:focus:active, +.overview-components-transparent .grid-search-result:selected:active, +.overview-components-transparent .grid-search-result:highlighted:active, +.overview-components-transparent .list-search-result:focus:active, +.overview-components-transparent .list-search-result:selected:active, +.overview-components-transparent .list-search-result:highlighted:active, +.overview-components-transparent .search-provider-icon:focus:active, +.overview-components-transparent .page-navigation-arrow:focus:active, +.overview-components-transparent .app-folder-dialog .icon-button:focus:active, +.overview-components-transparent #dash .show-apps:checked .overview-icon:hover { + background-color: rgba(230, 230, 230, 0.15); +} + + +/* +* `.overview-components-light` +*/ + +.overview-components-light .search-entry { + color: white; + background-color: rgba(200, 200, 200, 0.2); + border-color: transparent; + box-shadow: none; +} + +.overview-components-light .search-entry .search-entry-icon { + color: rgba(255, 255, 255, 0.65); +} + +.overview-components-light .overview-tile, +.overview-components-light .overview-icon, +.overview-components-light .grid-search-result, +.overview-components-light .list-search-result, +.overview-components-light .search-provider-icon, +/* prevents the extension from interfering with Just Perfection */ +.overview-components-light.just-perfection .search-section-content, +/* remove the rectangular background from the dash */ +.overview-components-light #dash .overview-tile, +.overview-components-light #dashtopanelScrollview .overview-tile { + background-color: transparent; +} + +.overview-components-light .workspace-thumbnail, +.overview-components-light .search-section-content, +.overview-components-light .overview-tile.app-folder, +.overview-components-light .page-navigation-arrow, +.overview-components-light .app-folder-dialog .icon-button, +/* this shouldn't apply to Dash to Dock */ +.overview-components-light StBoxLayout>StWidget>#dash>.dash-background { + background-color: rgba(200, 200, 200, 0.2); +} + +.overview-components-light .overview-tile:hover, +.overview-components-light .overview-tile:focus, +.overview-components-light .overview-tile:selected, +.overview-components-light .overview-tile:highlighted, +.overview-components-light .grid-search-result:hover, +.overview-components-light .grid-search-result:focus, +.overview-components-light .grid-search-result:selected, +.overview-components-light .grid-search-result:highlighted, +.overview-components-light .list-search-result:hover, +.overview-components-light .list-search-result:focus, +.overview-components-light .list-search-result:selected, +.overview-components-light .list-search-result:highlighted, +.overview-components-light .search-provider-icon:hover, +.overview-components-light .search-provider-icon:focus, +.overview-components-light .page-navigation-arrow:hover, +.overview-components-light .page-navigation-arrow:focus, +.overview-components-light .app-folder-dialog .icon-button:hover, +.overview-components-light .app-folder-dialog .icon-button:focus, +.overview-components-light #dash .overview-tile:hover .overview-icon, +.overview-components-light #dash .overview-tile:focus .overview-icon, +.overview-components-light #dash .show-apps:hover .overview-icon, +.overview-components-light #dash .show-apps:focus .overview-icon { + background-color: rgba(230, 230, 230, 0.2); +} + +.overview-components-light .overview-tile:active, +.overview-components-light .overview-tile:focus:hover, +.overview-components-light .overview-tile:drop, +.overview-components-light .overview-tile:selected:hover, +.overview-components-light .overview-tile:highlighted:hover, +.overview-components-light .grid-search-result:active, +.overview-components-light .grid-search-result:focus:hover, +.overview-components-light .grid-search-result:selected:hover, +.overview-components-light .grid-search-result:highlighted:hover, +.overview-components-light .list-search-result:active, +.overview-components-light .list-search-result:focus:hover, +.overview-components-light .list-search-result:selected:hover, +.overview-components-light .list-search-result:highlighted:hover, +.overview-components-light .search-provider-icon:active, +.overview-components-light .search-provider-icon:focus:hover, +.overview-components-light .page-navigation-arrow:active, +.overview-components-light .page-navigation-arrow:focus:hover, +.overview-components-light .app-folder-dialog .icon-button:active, +.overview-components-light .app-folder-dialog .icon-button:focus:hover, +.overview-components-light #dash .overview-tile:active .overview-icon, +.overview-components-light #dash .overview-tile:focus:hover .overview-icon, +.overview-components-light #dash .overview-tile:drop .overview-icon, +.overview-components-light #dash .show-apps:checked .overview-icon { + background-color: rgba(230, 230, 230, 0.25); +} + +.overview-components-light .overview-tile:focus:active, +.overview-components-light .overview-tile:selected:active, +.overview-components-light .overview-tile:highlighted:active, +.overview-components-light .grid-search-result:focus:active, +.overview-components-light .grid-search-result:selected:active, +.overview-components-light .grid-search-result:highlighted:active, +.overview-components-light .list-search-result:focus:active, +.overview-components-light .list-search-result:selected:active, +.overview-components-light .list-search-result:highlighted:active, +.overview-components-light .search-provider-icon:focus:active, +.overview-components-light .page-navigation-arrow:focus:active, +.overview-components-light .app-folder-dialog .icon-button:focus:active, +.overview-components-light #dash .show-apps:checked .overview-icon:hover { + background-color: rgba(230, 230, 230, 0.3); +} + + +/* +* `.overview-components-dark` +*/ + +.overview-components-dark .search-entry { + color: white; + background-color: rgba(100, 100, 100, 0.35); + border-color: transparent; + box-shadow: none; +} + +.overview-components-dark .search-entry .search-entry-icon { + color: rgba(255, 255, 255, 0.65); +} + +.overview-components-dark .overview-tile, +.overview-components-dark .overview-icon, +.overview-components-dark .grid-search-result, +.overview-components-dark .list-search-result, +.overview-components-dark .search-provider-icon, +/* prevents the extension from interfering with Just Perfection */ +.overview-components-dark.just-perfection .search-section-content, +/* remove the rectangular background from the dash */ +.overview-components-dark #dash .overview-tile, +.overview-components-dark #dashtopanelScrollview .overview-tile { + background-color: transparent; +} + +.overview-components-dark .workspace-thumbnail, +.overview-components-dark .search-section-content, +.overview-components-dark .overview-tile.app-folder, +.overview-components-dark .page-navigation-arrow, +.overview-components-dark .app-folder-dialog .icon-button, +/* this shouldn't apply to Dash to Dock */ +.overview-components-dark StBoxLayout>StWidget>#dash>.dash-background { + background-color: rgba(100, 100, 100, 0.35); +} + +.overview-components-dark .overview-tile:hover, +.overview-components-dark .overview-tile:focus, +.overview-components-dark .overview-tile:selected, +.overview-components-dark .overview-tile:highlighted, +.overview-components-dark .grid-search-result:hover, +.overview-components-dark .grid-search-result:focus, +.overview-components-dark .grid-search-result:selected, +.overview-components-dark .grid-search-result:highlighted, +.overview-components-dark .list-search-result:hover, +.overview-components-dark .list-search-result:focus, +.overview-components-dark .list-search-result:selected, +.overview-components-dark .list-search-result:highlighted, +.overview-components-dark .search-provider-icon:hover, +.overview-components-dark .search-provider-icon:focus, +.overview-components-dark .page-navigation-arrow:hover, +.overview-components-dark .page-navigation-arrow:focus, +.overview-components-dark .app-folder-dialog .icon-button:hover, +.overview-components-dark .app-folder-dialog .icon-button:focus, +.overview-components-dark #dash .overview-tile:hover .overview-icon, +.overview-components-dark #dash .overview-tile:focus .overview-icon, +.overview-components-dark #dash .show-apps:hover .overview-icon, +.overview-components-dark #dash .show-apps:focus .overview-icon { + background-color: rgba(120, 120, 120, 0.35); +} + +.overview-components-dark .overview-tile:active, +.overview-components-dark .overview-tile:focus:hover, +.overview-components-dark .overview-tile:drop, +.overview-components-dark .overview-tile:selected:hover, +.overview-components-dark .overview-tile:highlighted:hover, +.overview-components-dark .grid-search-result:active, +.overview-components-dark .grid-search-result:focus:hover, +.overview-components-dark .grid-search-result:selected:hover, +.overview-components-dark .grid-search-result:highlighted:hover, +.overview-components-dark .list-search-result:active, +.overview-components-dark .list-search-result:focus:hover, +.overview-components-dark .list-search-result:selected:hover, +.overview-components-dark .list-search-result:highlighted:hover, +.overview-components-dark .search-provider-icon:active, +.overview-components-dark .search-provider-icon:focus:hover, +.overview-components-dark .page-navigation-arrow:active, +.overview-components-dark .page-navigation-arrow:focus:hover, +.overview-components-dark .app-folder-dialog .icon-button:active, +.overview-components-dark .app-folder-dialog .icon-button:focus:hover, +.overview-components-dark #dash .overview-tile:active .overview-icon, +.overview-components-dark #dash .overview-tile:focus:hover .overview-icon, +.overview-components-dark #dash .overview-tile:drop .overview-icon, +.overview-components-dark #dash .show-apps:checked .overview-icon { + background-color: rgba(120, 120, 120, 0.4); +} + +.overview-components-dark .overview-tile:focus:active, +.overview-components-dark .overview-tile:selected:active, +.overview-components-dark .overview-tile:highlighted:active, +.overview-components-dark .grid-search-result:focus:active, +.overview-components-dark .grid-search-result:selected:active, +.overview-components-dark .grid-search-result:highlighted:active, +.overview-components-dark .list-search-result:focus:active, +.overview-components-dark .list-search-result:selected:active, +.overview-components-dark .list-search-result:highlighted:active, +.overview-components-dark .search-provider-icon:focus:active, +.overview-components-dark .page-navigation-arrow:focus:active, +.overview-components-dark .app-folder-dialog .icon-button:focus:active, +.overview-components-dark #dash .show-apps:checked .overview-icon:hover { + background-color: rgba(120, 120, 120, 0.45); +} + + +/*** APPFOLDER DIALOG ***/ + +/* +* `.appfolder-dialogs-transparent` +*/ + +.appfolder-dialogs-transparent { + background-color: rgba(0, 0, 0, 0); + border: none; + box-shadow: none; +} + +.appfolder-dialogs-transparent .folder-name-entry { + color: white; + background-color: rgba(0, 0, 0, 0); + border: 0; + box-shadow: none; +} + +/* +* `.appfolder-dialogs-light` +*/ + +.appfolder-dialogs-light { + background-color: rgba(200, 200, 200, 0.2); + border: none; + box-shadow: none; +} + +.appfolder-dialogs-light .folder-name-entry { + color: white; + background-color: rgba(200, 200, 200, 0.2); + border: 0; + box-shadow: none; +} + + +/* +* `.appfolder-dialogs-dark` +*/ + +.appfolder-dialogs-dark { + background-color: rgba(100, 100, 100, 0.35); + border: none; + box-shadow: none; +} + +.appfolder-dialogs-dark .folder-name-entry { + color: white; + background-color: rgba(100, 100, 100, 0.35); + border: 0; + box-shadow: none; +} + + +/*** PANEL LIGHT TEXT ***/ + +/* +* `.panel-light-text`, adapted from gnome-shell-light.css +*/ + +#panel.panel-light-text .panel-button, +#panel.panel-light-text .panel-button.clock-display, +#panel.panel-light-text .netSpeedLabel { + color: #f6f5f4; + box-shadow: none; +} + +#panel.panel-light-text .panel-button:active, +#panel.panel-light-text .panel-button:focus, +#panel.panel-light-text .panel-button:checked, +#panel.panel-light-text .panel-button.clock-display:active .clock, +#panel.panel-light-text .panel-button.clock-display:focus .clock, +#panel.panel-light-text .panel-button.clock-display:checked .clock { + box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.25); +} + +#panel.panel-light-text .panel-button:active:hover, +#panel.panel-light-text .panel-button:focus:hover, +#panel.panel-light-text .panel-button:checked:hover, +#panel.panel-light-text .panel-button.clock-display:active:hover, +#panel.panel-light-text .panel-button.clock-display:focus:hover, +#panel.panel-light-text .panel-button.clock-display:checked:hover, +#panel.panel-light-text .panel-button.clock-display:active .clock:hover, +#panel.panel-light-text .panel-button.clock-display:focus .clock:hover, +#panel.panel-light-text .panel-button.clock-display:checked .clock:hover { + box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.35); +} + +#panel.panel-light-text .panel-button:hover, +#panel.panel-light-text .panel-button.clock-display:hover, +#panel.panel-light-text .panel-button.clock-display:hover .clock { + box-shadow: inset 0 0 0 100px rgba(246, 245, 244, 0.2); +} + +#panel.panel-light-text .panel-button#panelActivities .workspace-dot { + background-color: #f6f5f4; +} + +#panel.panel-light-text .panel-button.clock-display:active, +#panel.panel-light-text .panel-button.clock-display:focus, +#panel.panel-light-text .panel-button.clock-display:checked, +#panel.panel-light-text .panel-button.clock-display:hover { + box-shadow: none !important; +} + +#panel.panel-light-text .panel-button.screen-recording-indicator { + color: #f6f5f4; + box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.8); +} + +#panel.panel-light-text .panel-button.screen-recording-indicator:active, +#panel.panel-light-text .panel-button.screen-recording-indicator:focus, +#panel.panel-light-text .panel-button.screen-recording-indicator:checked { + box-shadow: inset 0 0 0 100px #c01c28; +} + +#panel.panel-light-text .panel-button.screen-recording-indicator:active:hover, +#panel.panel-light-text .panel-button.screen-recording-indicator:focus:hover, +#panel.panel-light-text .panel-button.screen-recording-indicator:checked:hover { + box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.95); +} + +#panel.panel-light-text .panel-button.screen-recording-indicator:hover { + box-shadow: inset 0 0 0 100px rgba(192, 28, 40, 0.9); +} + +#panel.panel-light-text .panel-button.screen-sharing-indicator { + color: #282828; + box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.8); +} + +#panel.panel-light-text .panel-button.screen-sharing-indicator:active, +#panel.panel-light-text .panel-button.screen-sharing-indicator:focus, +#panel.panel-light-text .panel-button.screen-sharing-indicator:checked { + box-shadow: inset 0 0 0 100px #ff7800; +} + +#panel.panel-light-text .panel-button.screen-sharing-indicator:active:hover, +#panel.panel-light-text .panel-button.screen-sharing-indicator:focus:hover, +#panel.panel-light-text .panel-button.screen-sharing-indicator:checked:hover { + box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.95); +} + +#panel.panel-light-text .panel-button.screen-sharing-indicator:hover { + box-shadow: inset 0 0 0 100px rgba(255, 120, 0, 0.9); +}
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/application-row.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/application-row.ui new file mode 100644 index 0000000..2a26d14 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/application-row.ui @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="ApplicationRow" parent="AdwExpanderRow"> + <property name="title" translatable="yes">Window Name</property> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Select window</property> + <property name="subtitle" translatable="yes">Pick a window or select it by its classname.</property> + + <child> + <object class="GtkBox" id="window_selector"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">175px</property> + <style> + <class name="linked" /> + </style> + + <child> + <object class="GtkButton" id="window_picker"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="icon-name">select-window-symbolic</property> + </object> + </child> + + <child> + <object class="GtkEntry" id="window_class"> + <property name="valign">center</property> + <property name="hexpand">true</property> + </object> + </child> + </object> + </child> + </object> + </child> + </template> + + <object class="AdwToast" id="picking_failure_toast"> + <property name="title">Could not pick window, make sure that the extension is enabled.</property> + </object> + + <object class="AdwToast" id="window_not_found_toast"> + <property name="title">Could not pick window from here, does not seem like a valid window.</property> + </object> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/applications.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/applications.ui new file mode 100644 index 0000000..14c9364 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/applications.ui @@ -0,0 +1,276 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="Applications" parent="AdwPreferencesPage"> + <property name="name">applications</property> + <property name="title" translatable="yes">Applications</property> + <property name="icon-name">applications-symbolic</property> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Applications blur</property> + <property name="description" translatable="yes">Adds blur to the applications. +To get the best results possible, although with reduced performances, you can choose the option “No artifact” in the “Other → Hack level” tab.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Blur type</property> + <property name="subtitle" translatable="yes">The dynamic blur is slower and only compatible with a gaussian blur effect, but shows content behind windows.</property> + <property name="activatable-widget">blur_mode_choose</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkBox" id="blur_mode_choose"> + <property name="valign">center</property> + <property name="hexpand">false</property> + <style> + <class name="linked" /> + </style> + + <child> + <object class="GtkToggleButton" id="mode_static"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="group">mode_dynamic</property> + <property name="child"> + <object class="AdwButtonContent"> + <property name="icon-name">static-mode-symbolic</property> + <property name="label" translatable="yes">Static</property> + </object> + </property> + </object> + </child> + <child> + <object class="GtkToggleButton" id="mode_dynamic"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="child"> + <object class="AdwButtonContent"> + <property name="icon-name">dynamic-mode-symbolic</property> + <property name="label" translatable="yes">Dynamic</property> + </object> + </property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="PipelineChooseRow" id="pipeline_choose_row"> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + </object> + </child> + + <child> + <object class="AdwActionRow" id="sigma_row"> + <property name="title" translatable="yes">Sigma</property> + <property name="subtitle" translatable="yes">The intensity of the blur.</property> + <property name="activatable-widget">sigma_scale</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="sigma_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">0</property> + <property name="adjustment">sigma</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow" id="brightness_row"> + <property name="title" translatable="yes">Brightness</property> + <property name="subtitle" translatable="yes">The brightness of the blur effect, a high value might make the text harder to read.</property> + <property name="activatable-widget">brightness_scale</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="brightness_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">2</property> + <property name="adjustment">brightness</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Opacity</property> + <property name="subtitle" translatable="yes">The opacity of the window on top of the blur effect, a higher value will be more legible.</property> + <property name="activatable-widget">opacity_scale</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="opacity_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="orientation">horizontal</property> + <property name="digits">0</property> + <property name="adjustment">opacity</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Opaque focused window</property> + <property name="subtitle" translatable="yes">Makes the focused window opaque and the other ones blurred, helping with legibility.</property> + <property name="activatable-widget">dynamic_opacity</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkSwitch" id="dynamic_opacity"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Blur on overview</property> + <property name="subtitle" translatable="yes">Forces the blur to be properly shown on all workspaces on overview. +This may cause some latency or performance issues.</property> + <property name="activatable-widget">blur_on_overview</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkSwitch" id="blur_on_overview"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Enable all by default</property> + <property name="subtitle" translatable="yes">Adds blur behind all windows by default.</property> + <property name="activatable-widget">enable_all</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkSwitch" id="enable_all"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwPreferencesGroup" id="whitelist"> + <property name="title" translatable="yes">Whitelist</property> + <property name="description" translatable="yes">A list of windows to blur. +Use * to match any sequence of characters (e.g., Firefox* or *Code*), and ? for a single one.</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + <property name="header-suffix"> + <object class="GtkButton" id="add_window_whitelist"> + <property name="halign">start</property> + <property name="valign">center</property> + <child> + <object class="GtkBox"> + <property name="margin-start">12</property> + <property name="margin-end">12</property> + <child> + <object class="GtkImage"> + <property name="margin-end">6</property> + <property name="icon-name">add-row-symbolic</property> + </object> + </child> + <child> + <object class="GtkLabel"> + <property name="label" translatable="yes">Add Window</property> + </object> + </child> + </object> + </child> + <style> + <class name="circular" /> + <class name="suggested-action" /> + </style> + </object> + </property> + + <!-- WINDOW ROW WIDGETS GO HERE --> + </object> + </child> + + <child> + <object class="AdwPreferencesGroup" id="blacklist"> + <property name="title" translatable="yes">Blacklist</property> + <property name="description" translatable="yes">A list of windows not to blur. +Use * to match any sequence of characters (e.g., Firefox* or *Code*), and ? for a single one.</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + <property name="header-suffix"> + <object class="GtkButton" id="add_window_blacklist"> + <property name="halign">start</property> + <property name="valign">center</property> + <child> + <object class="GtkBox"> + <property name="margin-start">12</property> + <property name="margin-end">12</property> + <child> + <object class="GtkImage"> + <property name="margin-end">6</property> + <property name="icon-name">add-row-symbolic</property> + </object> + </child> + <child> + <object class="GtkLabel"> + <property name="label" translatable="yes">Add Window</property> + </object> + </child> + </object> + </child> + <style> + <class name="circular" /> + <class name="suggested-action" /> + </style> + </object> + </property> + + <!-- WINDOW ROW WIDGETS GO HERE --> + </object> + </child> + </template> + + <object class="GtkAdjustment" id="sigma"> + <property name="lower">0</property> + <property name="upper">100</property> + <property name="step-increment">1</property> + </object> + + <object class="GtkAdjustment" id="brightness"> + <property name="lower">0.0</property> + <property name="upper">1.0</property> + <property name="step-increment">0.01</property> + </object> + + <object class="GtkAdjustment" id="opacity"> + <property name="lower">25</property> + <property name="upper">255</property> + <property name="step-increment">1</property> + </object> +</interface> diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/dash.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/dash.ui new file mode 100644 index 0000000..b08a4d1 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/dash.ui @@ -0,0 +1,172 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="Dash" parent="AdwPreferencesPage"> + <property name="name">dash</property> + <property name="title" translatable="yes">Dash</property> + <property name="icon-name">dash-symbolic</property> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Dash to Dock blur</property> + <property name="description" translatable="yes">Blur the background of the Dash to Dock extension, if it is used.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Blur type</property> + <property name="subtitle" translatable="yes">The dynamic blur is slower and only compatible with a gaussian blur effect.</property> + <property name="activatable-widget">blur_mode_choose</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkBox" id="blur_mode_choose"> + <property name="valign">center</property> + <property name="hexpand">false</property> + <style> + <class name="linked" /> + </style> + + <child> + <object class="GtkToggleButton" id="mode_static"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="group">mode_dynamic</property> + <property name="child"> + <object class="AdwButtonContent"> + <property name="icon-name">static-mode-symbolic</property> + <property name="label" translatable="yes">Static</property> + </object> + </property> + </object> + </child> + <child> + <object class="GtkToggleButton" id="mode_dynamic"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="child"> + <object class="AdwButtonContent"> + <property name="icon-name">dynamic-mode-symbolic</property> + <property name="label" translatable="yes">Dynamic</property> + </object> + </property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="PipelineChooseRow" id="pipeline_choose_row"> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + </object> + </child> + + <child> + <object class="AdwActionRow" id="sigma_row"> + <property name="title" translatable="yes">Sigma</property> + <property name="subtitle" translatable="yes">The intensity of the blur.</property> + <property name="activatable-widget">sigma_scale</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="sigma_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">0</property> + <property name="adjustment">sigma</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow" id="brightness_row"> + <property name="title" translatable="yes">Brightness</property> + <property name="subtitle" translatable="yes">The brightness of the blur effect, a high value might make the text harder to read.</property> + <property name="activatable-widget">brightness_scale</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="brightness_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">2</property> + <property name="adjustment">brightness</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwExpanderRow" id="override_background"> + <property name="title" translatable="yes">Override background</property> + <property name="subtitle" translatable="yes">Makes the background either transparent or semi-transparent, disable this to use Dash to Dock preferences instead.</property> + <property name="show-enable-switch">true</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Background style</property> + <property name="subtitle" translatable="yes">The transparent/semi-transparent style for the dock background.</property> + <property name="activatable-widget">style_dash_to_dock</property> + + <child> + <object class="GtkDropDown" id="style_dash_to_dock"> + <property name="valign">center</property> + <property name="model">style_dash_to_dock_model</property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Disable in overview</property> + <property name="subtitle" translatable="yes">Disables the blur from Dash to Dock when entering the overview.</property> + <property name="activatable-widget">unblur_in_overview</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkSwitch" id="unblur_in_overview"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + </object> + </child> + </template> + + <object class="GtkAdjustment" id="sigma"> + <property name="lower">0</property> + <property name="upper">100</property> + <property name="step-increment">1</property> + </object> + + <object class="GtkAdjustment" id="brightness"> + <property name="lower">0.0</property> + <property name="upper">1.0</property> + <property name="step-increment">0.01</property> + </object> + + <object class="GtkStringList" id="style_dash_to_dock_model"> + <items> + <item translatable="yes">Transparent</item> + <item translatable="yes">Light</item> + <item translatable="yes">Dark</item> + </items> + </object> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/effects-dialog.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/effects-dialog.ui new file mode 100644 index 0000000..c6baf62 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/effects-dialog.ui @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="EffectsDialog" parent="AdwPreferencesDialog"> + <property name="title" translatable="yes">Effects</property> + <property name="presentation-mode">ADW_DIALOG_BOTTOM_SHEET</property> + <property name="content-width">600</property> + <property name="content-height">480</property> + + <child> + <object class="AdwPreferencesPage"> + <child> + <object class="AdwPreferencesGroup" id="effects_list"> + <property name="title">Effects list</property> + <property name="description">Effect on the top will be applied first.</property> + + <property name="header-suffix"> + <object class="GtkBox"> + <property name="margin-start">12</property> + <property name="margin-end">12</property> + <style> + <class name="linked" /> + </style> + <child> + <object class="GtkButton" id="add_effect"> + <property name="halign">start</property> + <property name="valign">center</property> + <child> + <object class="GtkBox"> + <property name="margin-start">12</property> + <property name="margin-end">12</property> + <child> + <object class="GtkImage"> + <property name="margin-end">6</property> + <property name="icon-name">list-add-symbolic</property> + </object> + </child> + <child> + <object class="GtkLabel"> + <property name="label" translatable="yes">Add Effect</property> + </object> + </child> + </object> + </child> + <style> + <class name="circular" /> + <class name="suggested-action" /> + </style> + </object> + </child> + + <child> + <object class="GtkMenuButton" id="add_effect_alt_menu"> + <property name="valign">center</property> + <property name="icon-name">down-symbolic</property> + <property name="menu-model">add_effect_alt_menu_model</property> + <style> + <class name="circular" /> + </style> + </object> + </child> + </object> + </property> + </object> + </child> + </object> + </child> + </template> + + <menu id="add_effect_alt_menu_model"> + <section> + <item> + <attribute name="label" translatable="yes">Include advanced effects</attribute> + <attribute name="action">effects-dialog.advanced-effects-bool</attribute> + </item> + </section> + </menu> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/menu.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/menu.ui new file mode 100644 index 0000000..6d2a474 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/menu.ui @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <menu id="info_menu_model"> + <section> + <item> + <attribute name="label" translatable="yes">Project page</attribute> + <attribute name="action">prefs.open-readme</attribute> + </item> + <item> + <attribute name="label" translatable="yes">Report a Bug</attribute> + <attribute name="action">prefs.open-bug-report</attribute> + </item> + <item> + <attribute name="label" translatable="yes">License</attribute> + <attribute name="action">prefs.open-license</attribute> + </item> + <submenu> + <attribute name="label" translatable="yes">Donate</attribute> + <item> + <attribute name="label">GitHub</attribute> + <attribute name="action">prefs.donate-github</attribute> + </item> + <item> + <attribute name="label">Ko-fi</attribute> + <attribute name="action">prefs.donate-kofi</attribute> + </item> + </submenu> + </section> + </menu> + + <object class="GtkMenuButton" id="info_menu"> + <property name="menu-model">info_menu_model</property> + <property name="icon-name">heart-symbolic</property> + </object> + + <object class="AdwPreferencesPage" id="menu_util"></object> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/other.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/other.ui new file mode 100644 index 0000000..e136e38 --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/other.ui @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="Other" parent="AdwPreferencesPage"> + <property name="name">other</property> + <property name="title" translatable="yes">Other</property> + <property name="icon-name">other-symbolic</property> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Lockscreen blur</property> + <property name="description" translatable="yes">Change the blur of the lockscreen to use this extension's preferences.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="lockscreen_blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="PipelineChooseRow" id="lockscreen_pipeline_choose_row"> + <property name="sensitive" bind-source="lockscreen_blur" bind-property="state" bind-flags="sync-create" /> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Screenshot blur</property> + <property name="description" translatable="yes">Add blur to the background of the window selector in the screenshot UI.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="screenshot_blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="PipelineChooseRow" id="screenshot_pipeline_choose_row"> + <property name="sensitive" bind-source="screenshot_blur" bind-property="state" bind-flags="sync-create" /> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Window list extension blur</property> + <property name="description" translatable="yes">Make the window-list extension blurred, if it is used.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="window_list_blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Sigma</property> + <property name="subtitle" translatable="yes">The intensity of the blur.</property> + <property name="activatable-widget">window_list_sigma_scale</property> + <property name="sensitive" bind-source="window_list_blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="window_list_sigma_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">0</property> + <property name="adjustment">window_list_sigma</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Brightness</property> + <property name="subtitle" translatable="yes">The brightness of the blur effect, a high value might make the text harder to read.</property> + <property name="activatable-widget">window_list_brightness_scale</property> + <property name="sensitive" bind-source="window_list_blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="window_list_brightness_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">2</property> + <property name="adjustment">window_list_brightness</property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Coverflow Alt-Tab extension blur</property> + <property name="description" translatable="yes">Make the coverflow alt-tab extension blurred, if it is used.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="coverflow_alt_tab_blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="PipelineChooseRow" id="coverflow_alt_tab_pipeline_choose_row"> + <property name="sensitive" bind-source="coverflow_alt_tab_blur" bind-property="state" bind-flags="sync-create" /> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Performance</property> + <property name="description" translatable="yes">Various options to tweak the performance.</property> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Hack level</property> + <property name="subtitle" translatable="yes">Changes the behaviour of the dynamic blur effect. The default value is highly recommended. +The “No artifact” option will entirely disable clipped redraws in GNOME shell, and will impact your computer performances significantly.</property> + <property name="activatable-widget">hack_level</property> + <child> + <object class="GtkDropDown" id="hack_level"> + <property name="valign">center</property> + <property name="model">hack_level_model</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Debug</property> + <property name="subtitle" translatable="yes">Makes the extension verbose in logs, activate when you need to report an issue.</property> + <property name="activatable-widget">debug</property> + <child> + <object class="GtkSwitch" id="debug"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + </object> + </child> + + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Reset preferences</property> + <property name="description" translatable="yes">Resets preferences of Blur my Shell irreversibly.</property> + <property name="header-suffix"> + <object class="GtkButton" id="reset"> + <property name="halign">start</property> + <property name="valign">center</property> + <child> + <object class="GtkBox"> + <property name="margin-start">20</property> + <property name="margin-end">20</property> + <property name="margin-top">6</property> + <property name="margin-bottom">6</property> + <child> + <object class="GtkImage"> + <property name="margin-end">6</property> + <property name="icon-name">reset-symbolic</property> + </object> + </child> + <child> + <object class="GtkLabel"> + <property name="label" translatable="yes">Reset</property> + </object> + </child> + </object> + </child> + <style> + <class name="circular" /> + <class name="destructive-action" /> + </style> + </object> + </property> + </object> + </child> + </template> + + <object class="GtkAdjustment" id="window_list_sigma"> + <property name="lower">0</property> + <property name="upper">100</property> + <property name="step-increment">1</property> + </object> + + <object class="GtkAdjustment" id="window_list_brightness"> + <property name="lower">0.0</property> + <property name="upper">1.0</property> + <property name="step-increment">0.01</property> + </object> + + <object class="GtkStringList" id="hack_level_model"> + <items> + <item translatable="yes">High performances</item> + <item translatable="yes">Default</item> + <item translatable="yes">No artifact</item> + </items> + </object> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/overview.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/overview.ui new file mode 100644 index 0000000..36b91fc --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/overview.ui @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="Overview" parent="AdwPreferencesPage"> + <property name="name">overview</property> + <property name="title" translatable="yes">Overview</property> + <property name="icon-name">overview-symbolic</property> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Background blur</property> + <property name="description" translatable="yes">Add blur to the overview background, using the wallpaper picture.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="overview_blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="PipelineChooseRow" id="pipeline_choose_row"> + <property name="sensitive" bind-source="overview_blur" bind-property="state" bind-flags="sync-create" /> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Overview components style</property> + <property name="subtitle" translatable="yes">The semi-transparent style for the dash, search entry/results, and application folders.</property> + <property name="sensitive" bind-source="overview_blur" bind-property="state" bind-flags="sync-create" /> + <property name="activatable-widget">overview_style_components</property> + + <child> + <object class="GtkDropDown" id="overview_style_components"> + <property name="valign">center</property> + <property name="model">overview_style_components_model</property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Application folder blur</property> + <property name="description" translatable="yes">Makes the background of application folder dialogs blurred.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="appfolder_blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Sigma</property> + <property name="subtitle" translatable="yes">The intensity of the blur.</property> + <property name="activatable-widget">appfolder_sigma_scale</property> + <property name="sensitive" bind-source="appfolder_blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="appfolder_sigma_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">0</property> + <property name="adjustment">appfolder_sigma</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Brightness</property> + <property name="subtitle" translatable="yes">The brightness of the blur effect, a high value might make the text harder to read.</property> + <property name="activatable-widget">appfolder_brightness_scale</property> + <property name="sensitive" bind-source="appfolder_blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="appfolder_brightness_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">2</property> + <property name="adjustment">appfolder_brightness</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Application folder dialogs style</property> + <property name="subtitle" translatable="yes">The semi-transparent style for the application folder dialogs.</property> + <property name="sensitive" bind-source="appfolder_blur" bind-property="state" bind-flags="sync-create" /> + <property name="activatable-widget">appfolder_style_dialogs</property> + + <child> + <object class="GtkDropDown" id="appfolder_style_dialogs"> + <property name="valign">center</property> + <property name="model">appfolder_style_dialogs_model</property> + </object> + </child> + </object> + </child> + </object> + </child> + </template> + + <object class="GtkStringList" id="overview_style_components_model"> + <items> + <item translatable="yes">Do not style</item> + <item translatable="yes">Light</item> + <item translatable="yes">Dark</item> + <item translatable="yes">Transparent</item> + </items> + </object> + + <object class="GtkAdjustment" id="appfolder_sigma"> + <property name="lower">0</property> + <property name="upper">100</property> + <property name="step-increment">1</property> + </object> + + <object class="GtkAdjustment" id="appfolder_brightness"> + <property name="lower">0.0</property> + <property name="upper">1.0</property> + <property name="step-increment">0.01</property> + </object> + + + <object class="GtkStringList" id="appfolder_style_dialogs_model"> + <items> + <item translatable="yes">Do not style</item> + <item translatable="yes">Transparent</item> + <item translatable="yes">Light</item> + <item translatable="yes">Dark</item> + </items> + </object> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/panel.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/panel.ui new file mode 100644 index 0000000..306f4ef --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/panel.ui @@ -0,0 +1,240 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="Panel" parent="AdwPreferencesPage"> + <property name="name">panel</property> + <property name="title" translatable="yes">Panel</property> + <property name="icon-name">bottom-panel-symbolic</property> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Panel blur</property> + <property name="description" translatable="yes">Blur the top panel using the background image.</property> + <property name="header-suffix"> + <object class="GtkSwitch" id="blur"> + <property name="valign">center</property> + </object> + </property> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Blur type</property> + <property name="subtitle" translatable="yes">The dynamic blur is slower and only compatible with a gaussian blur effect.</property> + <property name="activatable-widget">blur_mode_choose</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkBox" id="blur_mode_choose"> + <property name="valign">center</property> + <property name="hexpand">false</property> + <style> + <class name="linked" /> + </style> + + <child> + <object class="GtkToggleButton" id="mode_static"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="group">mode_dynamic</property> + <property name="child"> + <object class="AdwButtonContent"> + <property name="icon-name">static-mode-symbolic</property> + <property name="label" translatable="yes">Static</property> + </object> + </property> + </object> + </child> + <child> + <object class="GtkToggleButton" id="mode_dynamic"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="child"> + <object class="AdwButtonContent"> + <property name="icon-name">dynamic-mode-symbolic</property> + <property name="label" translatable="yes">Dynamic</property> + </object> + </property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="PipelineChooseRow" id="pipeline_choose_row"> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + </object> + </child> + + <child> + <object class="AdwActionRow" id="sigma_row"> + <property name="title" translatable="yes">Sigma</property> + <property name="subtitle" translatable="yes">The intensity of the blur.</property> + <property name="activatable-widget">sigma_scale</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="sigma_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">0</property> + <property name="adjustment">sigma</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow" id="brightness_row"> + <property name="title" translatable="yes">Brightness</property> + <property name="subtitle" translatable="yes">The brightness of the blur effect, a high value might make the text harder to read.</property> + <property name="activatable-widget">brightness_scale</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkScale" id="brightness_scale"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="width-request">200px</property> + <property name="draw-value">true</property> + <property name="value-pos">right</property> + <property name="digits">2</property> + <property name="adjustment">brightness</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Force light text</property> + <property name="subtitle" translatable="yes">Use a light text for the panel, useful when using gnome-shell's light theme.</property> + <property name="activatable-widget">force_light_text</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkSwitch" id="force_light_text"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwExpanderRow" id="override_background"> + <property name="title" translatable="yes">Override background</property> + <property name="subtitle" translatable="yes">Override the background of the panel to use a transparent or semi-transparent one. +Recommended unless you want to customize your GNOME theme.</property> + <property name="show-enable-switch">true</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Background style</property> + <property name="subtitle" translatable="yes">The transparent/semi-transparent style for the panel background.</property> + <property name="activatable-widget">style_panel</property> + + <child> + <object class="GtkDropDown" id="style_panel"> + <property name="valign">center</property> + <property name="model">style_panel_model</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Disable when a window is near</property> + <property name="subtitle" translatable="yes">Disables the transparency of the panel when a window is near it.</property> + <property name="activatable-widget">override_background_dynamically</property> + + <child> + <object class="GtkSwitch" id="override_background_dynamically"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Disable in overview</property> + <property name="subtitle" translatable="yes">Disables the blur from the panel when entering the overview.</property> + <property name="activatable-widget">unblur_in_overview</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkSwitch" id="unblur_in_overview"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwPreferencesGroup"> + <property name="title" translatable="yes">Compatibility</property> + <property name="description" translatable="yes">Various options to provide compatibility with other extensions.</property> + <property name="sensitive" bind-source="blur" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Hidetopbar extension</property> + <property name="subtitle" translatable="yes">Does not disable the blur in overview, best used with static blur.</property> + <property name="activatable-widget">hidetopbar_compatibility</property> + <property name="sensitive" bind-source="unblur_in_overview" bind-property="state" bind-flags="sync-create" /> + + <child> + <object class="GtkSwitch" id="hidetopbar_compatibility"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + + <child> + <object class="AdwActionRow"> + <property name="title" translatable="yes">Blur original panel with Dash to Panel</property> + <property name="subtitle" translatable="yes">Enables the blurring of the original panel with Dash to Panel, if selected in the extension's options.</property> + <property name="activatable-widget">dtp_blur_original_panel</property> + + <child> + <object class="GtkSwitch" id="dtp_blur_original_panel"> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + </object> + </child> + </template> + + <object class="GtkStringList" id="style_panel_model"> + <items> + <item translatable="yes">Transparent</item> + <item translatable="yes">Light</item> + <item translatable="yes">Dark</item> + <item translatable="yes">Contrasted</item> + </items> + </object> + + <object class="GtkAdjustment" id="sigma"> + <property name="lower">0</property> + <property name="upper">100</property> + <property name="step-increment">1</property> + </object> + + <object class="GtkAdjustment" id="brightness"> + <property name="lower">0.0</property> + <property name="upper">1.0</property> + <property name="step-increment">0.01</property> + </object> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipeline-choose-row.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipeline-choose-row.ui new file mode 100644 index 0000000..72b854b --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipeline-choose-row.ui @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="PipelineChooseRow" parent="AdwActionRow"> + <property name="title" translatable="yes">Pipeline</property> + <property name="subtitle" translatable="yes">The pipeline to be used with this component.</property> + <property name="activatable-widget">pipeline_choose</property> + + <child> + <object class="GtkBox"> + <property name="valign">center</property> + <property name="hexpand">false</property> + <style> + <class name="linked" /> + </style> + + <child> + <object class="GtkDropDown" id="pipeline_choose"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="model"> + <object class="GtkStringList" id="pipeline_model"> + <items> + </items> + </object> + </property> + </object> + </child> + + <child> + <object class="GtkButton" id="pipeline_edit"> + <property name="valign">center</property> + <property name="hexpand">true</property> + <property name="icon-name">edit-row-symbolic</property> + </object> + </child> + </object> + </child> + </template> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipeline-group.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipeline-group.ui new file mode 100644 index 0000000..19a12bf --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipeline-group.ui @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="PipelineGroup" parent="AdwPreferencesGroup"> + <child> + <object class="AdwEntryRow" id="title"> + <property name="title" translatable="yes">Pipeline name</property> + </object> + </child> + + <child> + <object class="AdwActionRow" id="effects_description_row"> + <property name="activatable-widget">manage_effects</property> + + <child> + <object class="GtkButton" id="manage_effects"> + <property name="valign">center</property> + <property name="child"> + <object class="AdwButtonContent"> + <property name="icon-name">edit-row-symbolic</property> + <property name="label" translatable="yes">Manage effects</property> + <property name="use-underline">True</property> + </object> + </property> + </object> + </child> + </object> + </child> + </template> +</interface>
\ No newline at end of file diff --git a/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipelines.ui b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipelines.ui new file mode 100644 index 0000000..555ec0a --- /dev/null +++ b/raveos-theme/gnome/theme-data/extensions/installed/blur-my-shell@aunetx/ui/pipelines.ui @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface domain="blur-my-shell@aunetx"> + <template class="Pipelines" parent="AdwPreferencesPage"> + <property name="name">pipelines</property> + <property name="title" translatable="yes">Pipelines</property> + <property name="icon-name">pipelines-symbolic</property> + + <child> + <object class="AdwPreferencesGroup"> + <property name="description" translatable="yes">Each component uses a pipeline, which can be chosen in the corresponding tab. Here you can create, modify and delete the pipelines and their effects.</property> + + <property name="header-suffix"> + <object class="GtkButton" id="add_pipeline"> + <property name="halign">start</property> + <property name="valign">center</property> + <property name="margin-start">12</property> + <child> + <object class="GtkBox"> + <property name="margin-start">12</property> + <property name="margin-end">12</property> + <child> + <object class="GtkImage"> + <property name="margin-end">6</property> + <property name="icon-name">list-add-symbolic</property> + </object> + </child> + <child> + <object class="GtkLabel"> + <property name="label" translatable="yes">Add Pipeline</property> + </object> + </child> + </object> + </child> + <style> + <class name="circular" /> + <class name="suggested-action" /> + </style> + </object> + </property> + </object> + </child> + + </template> +</interface>
\ No newline at end of file |