diff --git a/lib-flatpak.sh b/lib-flatpak.sh index 4e49d69..b8c9725 100755 --- a/lib-flatpak.sh +++ b/lib-flatpak.sh @@ -27,17 +27,20 @@ pakitheme() { local repo_dir="$root_dir/repo" local build_dir="$root_dir/build" - prompt -i "Converting theme: $FLATPAK_THEME" - for location in "$data_home/themes" "$HOME/.themes" /usr/share/themes; do if [[ -d "$location/$FLATPAK_THEME" ]]; then - prompt -s "Found theme located at: $location/$FLATPAK_THEME" + prompt -s "Found theme located at: $location/$FLATPAK_THEME \n" theme_path="$location/$FLATPAK_THEME" break fi done - [[ -n "$theme_path" ]] || die 'Could not locate theme.' + if [[ -n "$theme_path" ]]; then + prompt -i "Converting theme: $FLATPAK_THEME... \n" + else + prompt -e "Could not locate theme... install theme first! \n" + exit 0 + fi rm -rf "$root_dir" "$repo_dir" mkdir -p "$repo_dir" diff --git a/lib-install.sh b/lib-install.sh index c5cda88..c4b2911 100755 --- a/lib-install.sh +++ b/lib-install.sh @@ -671,22 +671,24 @@ install_dash_to_dock_theme() { if [[ -d "${DASH_TO_DOCK_DIR_HOME}" ]]; then backup_file "${DASH_TO_DOCK_DIR_HOME}/stylesheet.css" "udo" - udoify_file "${DASH_TO_DOCK_DIR_HOME}/stylesheet.css" - udo sassc ${SASSC_OPT} "${DASH_TO_DOCK_SRC_DIR}/stylesheet$(destify ${colors[0]}).scss" "${DASH_TO_DOCK_DIR_HOME}/stylesheet.css" + udoify_file "${DASH_TO_DOCK_DIR_HOME}/stylesheet.css" + if [[ "${GNOME_VERSION}" == 'new' ]]; then + udo sassc ${SASSC_OPT} "${DASH_TO_DOCK_SRC_DIR}/stylesheet-40.scss" "${DASH_TO_DOCK_DIR_HOME}/stylesheet.css" + else + udo sassc ${SASSC_OPT} "${DASH_TO_DOCK_SRC_DIR}/stylesheet$(destify ${colors[0]}).scss" "${DASH_TO_DOCK_DIR_HOME}/stylesheet.css" + fi elif [[ -d "${DASH_TO_DOCK_DIR_ROOT}" ]]; then backup_file "${DASH_TO_DOCK_DIR_ROOT}/stylesheet.css" "sudo" - sudo sassc ${SASSC_OPT} "${DASH_TO_DOCK_SRC_DIR}/stylesheet$(destify ${colors[0]}).scss" "${DASH_TO_DOCK_DIR_ROOT}/stylesheet.css" + if [[ "${GNOME_VERSION}" == 'new' ]]; then + sudo sassc ${SASSC_OPT} "${DASH_TO_DOCK_SRC_DIR}/stylesheet-40.scss" "${DASH_TO_DOCK_DIR_ROOT}/stylesheet.css" + else + sudo sassc ${SASSC_OPT} "${DASH_TO_DOCK_SRC_DIR}/stylesheet$(destify ${colors[0]}).scss" "${DASH_TO_DOCK_DIR_ROOT}/stylesheet.css" + fi fi udo dbus-launch dconf write /org/gnome/shell/extensions/dash-to-dock/apply-custom-theme true } -revert_dash_to_dock() { - if [[ -d "${DASH_TO_DOCK_DIR_HOME}.bak" ]]; then - restore_file "${DASH_TO_DOCK_DIR_HOME}" "udo" - fi -} - revert_dash_to_dock_theme() { if [[ -d "${DASH_TO_DOCK_DIR_HOME}" ]]; then restore_file "${DASH_TO_DOCK_DIR_HOME}/stylesheet.css" "udo" diff --git a/src/other/dash-to-dock/_dash-to-dock.scss b/src/other/dash-to-dock/_dash-to-dock-3.scss similarity index 100% rename from src/other/dash-to-dock/_dash-to-dock.scss rename to src/other/dash-to-dock/_dash-to-dock-3.scss diff --git a/src/other/dash-to-dock/_dash-to-dock-4.scss b/src/other/dash-to-dock/_dash-to-dock-4.scss new file mode 100644 index 0000000..471fb5e --- /dev/null +++ b/src/other/dash-to-dock/_dash-to-dock-4.scss @@ -0,0 +1,334 @@ + +$dash_background_color: if($variant == 'light', rgba($panel_bg, $panel_opacity), rgba($panel_bg, $panel_opacity + 0.1)); +$dash_placeholder_size: 32px; +$dash_padding: $base_padding + 4px; // 10px +$dash_spacing: round($base_padding / 4); +$dash_bottom_margin: $base_margin * 4; +$dash_border_radius: $dash_radius; + +// Stock +$dock_side_margin: $dash_bottom_margin / 4; +$dock_fixed_inner_margin: $dock_side_margin; + +// Adapted to $dock_bottom_margin + +@function shrink($val) { + @return round($val / 4); +} + +@function opposite($val) { + @return map-get( + ( + left: right, + right: left, + top: bottom, + bottom: top, + ), + $val + ); +} + +$osd_fg_color: #eeeeec; + +@each $side in bottom, top, left, right { + #dashtodockContainer.#{$side} { + #dash { + margin: 0; + padding: 0; + padding-#{$side}: $dash_padding; + padding-#{opposite($side)}: $dash_padding; + + .dash-background { + margin: 0; + margin-#{$side}: $dock_side_margin; + padding: $dash_padding; + } + + .dash-separator { + @if $side == top or $side == bottom { + margin-bottom: 0; + } @else { + height: 1px; + margin: ($dash_spacing + ($dash_padding / 2)) 0; + background-color: transparentize($osd_fg_color, 0.7); + } + } + + .dash-item-container { + .app-well-app, + .show-apps { + padding: $dash_spacing; + padding-#{$side}: $dash_padding + $dock_side_margin; + padding-#{opposite($side)}: $dash_padding; + } + } + } + + &.shrink { + #dash { + .dash-background { + margin-#{$side}: shrink($dock_side_margin); + padding: shrink($dash_padding); + border-radius: $dash_border_radius - $dash_padding + shrink($dash_padding); + } + + #dashtodockDashContainer { + padding: shrink($dash_padding); + } + + .dash-item-container { + .app-well-app, + .show-apps { + padding: shrink($dash_spacing); + padding-#{$side}: shrink($dash_padding + $dock_side_margin); + padding-#{opposite($side)}: shrink($dash_padding); + } + } + } + + &.fixed { + #dash { + .dash-background { + margin-#{opposite($side)}: shrink($dock_fixed_inner_margin); + } + + .dash-item-container { + .app-well-app, + .show-apps { + padding-#{opposite($side)}: shrink($dash_padding + $dock_fixed_inner_margin); + } + } + } + } + } + + &.fixed { + #dash { + .dash-background { + margin-#{opposite($side)}: $dock_fixed_inner_margin; + } + + .dash-item-container { + .app-well-app, + .show-apps { + padding-#{opposite($side)}: $dash_padding + $dock_fixed_inner_margin; + } + } + } + } + } +} + +@each $side in bottom, top, left, right { + #dashtodockContainer.extended.#{$side} { + #dash { + margin: 0; + padding: 0; + + .dash-background { + margin: 0; + margin-#{$side}: 0 !important; + border-radius: 0; + padding: 0; + padding-#{$side}: $dash_padding; + padding-#{opposite($side)}: $dash_padding; + } + + #dashtodockDashContainer { + padding: $dash_padding; + padding-#{$side}: 0; + padding-#{opposite($side)}: 0; + } + + .dash-item-container { + .app-well-app, + .show-apps { + padding: $dash_spacing; + padding-#{$side}: $dash_padding; + padding-#{opposite($side)}: $dash_padding; + } + + .show-apps { + @if $side == top or $side == bottom { + margin-left: $dash_padding; + } @else { + margin-top: $dash_padding; + } + } + } + } + + &.shrink { + #dash { + .dash-background { + margin: 0; + margin-#{$side}: 0 !important; + border-radius: 0; + padding: 0; + padding-#{$side}: shrink($dash_padding - $dash_spacing); + padding-#{opposite($side)}: shrink($dash_padding - $dash_spacing); + } + + #dashtodockDashContainer { + padding: shrink($dash_padding - $dash_spacing); + padding-#{$side}: 0; + padding-#{opposite($side)}: 0; + } + + .dash-item-container { + .app-well-app, + .show-apps { + padding: shrink($dash_spacing); + padding-#{$side}: shrink($dash_padding); + padding-#{opposite($side)}: shrink($dash_padding); + } + + .show-apps { + @if $side == top or $side == bottom { + margin-left: shrink($dash_spacing); + } @else { + margin-top: shrink($dash_spacing); + } + } + } + } + } + + &.shrink.fixed { + #dash { + .dash-background { + margin-#{opposite($side)}: 0; + } + } + } + } +} + +#dashtodockContainer.top.shrink #dash .dash-background { + margin-top: 4px; + margin-bottom: 0; +} + +#dashtodockContainer.straight-corner #dash .dash-background, +#dashtodockContainer.shrink.straight-corner #dash .dash-background { + border-radius: 0px; +} + +/* Scrollview style */ +.bottom #dashtodockDashScrollview, +.top #dashtodockDashScrollview { + -st-hfade-offset: 24px; +} + +.left #dashtodockDashScrollview, +.right #dashtodockDashScrollview { + -st-vfade-offset: 24px; +} + +#dashtodockContainer.running-dots .dash-item-container > StButton, +#dashtodockContainer.dashtodock .dash-item-container > StButton { + transition-duration: 250; + background-size: contain; +} + +/* Running and focused application style */ + +#dashtodockContainer.running-dots .app-well-app.running > .overview-icon, +#dashtodockContainer.dashtodock .app-well-app.running > .overview-icon { + background-image: none; +} + +#dashtodockContainer.running-dots .app-well-app.focused .overview-icon, +#dashtodockContainer.dashtodock .app-well-app.focused .overview-icon { + background-color: rgba(238, 238, 236, 0.2); +} + +#dashtodockContainer.dashtodock #dash .dash-background { + background: #2e3436; +} + +#dashtodockContainer.dashtodock .progress-bar { + /* Customization of the progress bar style, e.g.: + -progress-bar-background: rgba(0.8, 0.8, 0.8, 1); + -progress-bar-border: rgba(0.9, 0.9, 0.9, 1); + */ +} + +#dashtodockContainer.top #dash .placeholder, +#dashtodockContainer.bottom #dash .placeholder { + width: 32px; + height: 1px; +} + +/* + * This is applied to a dummy actor. Only the alpha value for the background and border color + * and the transition-duration are used + */ +#dashtodockContainer.dummy-opaque { + background-color: rgba(0, 0, 0, 0.8); + border-color: rgba(0, 0, 0, 0.4); + transition-duration: 300ms; +} + +/* + * This is applied to a dummy actor. Only the alpha value for the background and border color + * and the transition-duration are used + */ +#dashtodockContainer.dummy-transparent { + background-color: rgba(0, 0, 0, 0.2); + border-color: rgba(0, 0, 0, 0.1); + transition-duration: 500ms; +} + +#dashtodockContainer .number-overlay { + color: rgba(255, 255, 255, 1); + background-color: rgba(0, 0, 0, 0.8); + text-align: center; +} + +#dashtodockContainer .notification-badge { + color: rgba(255, 255, 255, 1); + background-color: rgba(255, 0, 0, 1); + padding: 0.2em 0.5em; + border-radius: 1em; + font-weight: bold; + text-align: center; + margin: 2px; +} + +#dashtodockPreviewSeparator.popup-separator-menu-item-horizontal { + width: 1px; + height: auto; + border-right-width: 1px; + margin: 32px 0px; +} + +.dashtodock-app-well-preview-menu-item { + padding: 1em 1em 0.5em 1em; +} + +#dashtodockContainer .metro .overview-icon { + border-radius: 0px; +} + +#dashtodockContainer.bottom .metro.running2.focused, +#dashtodockContainer.bottom .metro.running3.focused, +#dashtodockContainer.bottom .metro.running4.focused, +#dashtodockContainer.top .metro.running2.focused, +#dashtodockContainer.top .metro.running3.focused, +#dashtodockContainer.top .metro.running4.focused { + background-image: url("./media/highlight_stacked_bg.svg"); + background-position: 0px 0px; + background-size: contain; +} + +#dashtodockContainer.left .metro.running2.focused, +#dashtodockContainer.left .metro.running3.focused, +#dashtodockContainer.left .metro.running4.focused, +#dashtodockContainer.right .metro.running2.focused, +#dashtodockContainer.right .metro.running3.focused, +#dashtodockContainer.right .metro.running4.focused { + background-image: url("./media/highlight_stacked_bg_h.svg"); + background-position: 0px 0px; + background-size: contain; +} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/COPYING b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/COPYING deleted file mode 100644 index d159169..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/README.md b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/README.md deleted file mode 100644 index 1c76c69..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Dash to Dock -![screenshot](https://github.com/micheleg/dash-to-dock/raw/master/media/screenshot.jpg) - -## A dock for the GNOME Shell -This extension enhances the dash moving it out of the overview and transforming it in a dock for an easier launching of applications and a faster switching between windows and desktops without having to leave the desktop view. - -[](https://extensions.gnome.org/extension/307/dash-to-dock) - -For additional installation instructions and more information visit [https://micheleg.github.io/dash-to-dock/](https://micheleg.github.io/dash-to-dock/). - -## Installation from source - -The extension can be installed directly from source, either for the convenience of using git or to test the latest development version. Clone the desired branch with git - -### Build Dependencies - -To compile the stylesheet you'll need an implementation of SASS. Dash to Dock supports `dart-sass` (`sass`), `sassc`, and `ruby-sass`. Every distro should have at least one of these implementations, we recommend using `dart-sass` (`sass`) or `sassc` over `ruby-sass` as `ruby-sass` is deprecated. - -By default, Dash to Dock will attempt to build with `dart-sass`. To change this behavior set the `SASS` environment variable to either `sassc` or `ruby`. - -```bash -export SASS=sassc -# or... -export SASS=ruby -``` - -### Building - -Clone the repository or download the branch from github. A simple Makefile is included. - -Next use `make` to install the extension into your home directory. A Shell reload is required `Alt+F2 r Enter` under Xorg or under Wayland you may have to logout and login. The extension has to be enabled with *gnome-extensions-app* (GNOME Extensions) or with *dconf*. - -```bash -git clone https://github.com/micheleg/dash-to-dock.git -make -make install -``` - -## Bug Reporting - -Bugs should be reported to the Github bug tracker [https://github.com/micheleg/dash-to-dock/issues](https://github.com/micheleg/dash-to-dock/issues). - -## License -Dash to Dock Gnome Shell extension is distributed under the terms of the GNU General Public License, -version 2 or later. See the COPYING file for details. diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/Settings.ui b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/Settings.ui deleted file mode 100644 index d2560de..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/Settings.ui +++ /dev/null @@ -1,2660 +0,0 @@ - - - - - 1 - 0.050000000000000003 - 0.25 - - - 0 - 12 - 12 - 12 - 12 - vertical - - - 0 - - - 0 - none - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - When set to minimize, double clicking minimizes all the windows of the application. - 1 - 40 - - - - 0 - 1 - - - - - - 0 - 1 - Shift+Click action - - - 0 - 0 - - - - - - 0 - center - - Raise window - Minimize window - Launch new instance - Cycle through windows - Minimize or overview - Show window previews - Minimize or show previews - Focus or show previews - Focus, minimize or show previews - Quit - - - 1 - 0 - 2 - - - - - - - - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - Behavior for Middle-Click. - 1 - 40 - - - - 0 - 1 - - - - - - 0 - 1 - Middle-Click action - - - 0 - 0 - - - - - - 0 - center - - Raise window - Minimize window - Launch new instance - Cycle through windows - Minimize or overview - Show window previews - Minimize or show previews - Focus or show previews - Focus, minimize or show previews - Quit - - - 1 - 0 - 2 - - - - - - - - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - Behavior for Shift+Middle-Click. - 1 - 40 - - - - 0 - 1 - - - - - - 0 - 1 - Shift+Middle-Click action - - - 0 - 0 - - - - - - 0 - center - - Raise window - Minimize window - Launch new instance - Cycle through windows - Minimize or overview - Show window previews - Minimize or show previews - Focus or show previews - Focus, minimize or show previews - Quit - - - 1 - 0 - 2 - - - - - - - - - - - - - - - - - 1 - 0.01 - 0.10 - - - 0.33 - 1 - 0.01 - 0.10 - - - 10 - 1 - 5 - - - 0 - 12 - 12 - 12 - 12 - vertical - - - 0 - - - - 0 - none - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - vertical - 12 - - - 0 - 32 - - - 1 - 0 - center - Enable Unity7 like glossy backlit items - - - - - - center - - - - - - - 0 - - - 1 - 0 - start - Use dominant color - - - - - - - - - - 0 - 32 - - - - 1 - 0 - - - - - - 0 - 1 - Customize indicator style - fill - - - 0 - 0 - - - - - - - - 0 - 1 - vertical - 12 - - - 0 - 32 - - - 1 - 0 - Color - - - - - - 1 - - - - - - - 0 - 32 - - - 1 - 0 - Border color - - - - - - 1 - - - - - - - 0 - 32 - - - 1 - 0 - Border width - - - - - - dot_border_width_adjustment - - - - - - - - - - - - - - - - - - - - 1 - 0.050000000000000003 - 0.25 - - - 16 - 128 - 1 - 10 - - - 6 - 6 - 6 - 6 - - - - - 0 - 24 - 24 - 24 - 24 - vertical - 24 - - - 0 - - - - 0 - none - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Show the dock on - - 0 - 0 - - - - - - 0 - center - - - 1 - 0 - - - - - - Show on all monitors. - 12 - - - 0 - 2 - 2 - - - - - - - - - - - - - - - - 100 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - Position on screen - - - - - - 0 - 32 - - - Left - end - center - - - - - - - Bottom - center - - position_left_button - - - - - - Top - center - - - position_left_button - - - - - - Right - center - - position_left_button - - - - - - - - - - - - - - - - - - - 0 - - - - 0 - none - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Hide the dock when it obstructs a window of the current application. More refined settings are available. - 1 - - - - 0 - 1 - - - - - - 0 - 1 - start - Intelligent autohide - - - 0 - 0 - - - - - - 0 - 6 - - - 1 - center - center - - - - 0 - emblem-system-symbolic - - - - - - - - end - center - - - - 1 - 0 - 2 - - - - - - - - - - - - - - - - - 0 - - - - 0 - none - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - Dock size limit - - - 0 - 0 - - - - - - 1 - baseline - 1 - dock_size_adjustment - 0 - 2 - right - - - 1 - 0 - - - - - - Panel mode: extend to the screen edge - 12 - - - 0 - 1 - 2 - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - Icon size limit - - - 0 - 0 - - - - - - 1 - baseline - 1 - icon_size_adjustment - 1 - 0 - right - - - 1 - 0 - - - - - - Fixed icon size: scroll to reveal other icons - 12 - - - 0 - 1 - 2 - - - - - - - - - - - - - - - - - - - 0 - Position and size - - - - - - - 1 - - - 0 - 24 - 24 - 24 - 24 - vertical - 24 - - - 0 - - - - 0 - none - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - end - center - - 1 - 0 - - - - - - 0 - 1 - start - Show favorite applications - - - 0 - 0 - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - end - center - - 1 - 0 - - - - - - 0 - 1 - start - Show running applications - - - 0 - 0 - - - - - - Isolate workspaces. - start - 12 - - - 0 - 2 - 2 - - - - - - Isolate monitors. - start - 12 - - - 0 - 3 - 2 - - - - - - 3 - - - - 0 - Show open windows previews. - 1 - - - - 0 - 1 - 2 - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - end - center - - 1 - 0 - 2 - - - - - - 0 - 1 - If disabled, these settings are accessible from gnome-tweak-tool or the extension website. - 1 - - - - 0 - 1 - - - - - - 0 - 1 - start - Show <i>Applications</i> icon - 1 - - - 0 - 0 - - - - - - Move the applications button at the beginning of the dock. - start - 12 - - - 0 - 2 - 2 - - - - - - 3 - - - - - 0 - start - Animate <i>Show Applications</i>. - 1 - - - - 0 - 3 - 2 - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - end - center - - 1 - 0 - - - - - - 0 - 1 - start - Show trash can - - - 0 - 0 - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - end - center - - 1 - 0 - - - - - - 0 - 1 - start - Show mounted volumes and devices - - - 0 - 0 - - - - - - - - - - - - - - - - - - - 0 - Launchers - - - - - - - 2 - - - 0 - 24 - 24 - 24 - 24 - vertical - 24 - - - 0 - - - - 0 - none - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - start - 1 - Enable Super+(0-9) as shortcuts to activate apps. It can also be used together with Shift and Ctrl. - 1 - 1 - - - - 0 - 1 - - - - - - 0 - 1 - start - Use keyboard shortcuts to activate apps - - - 0 - 0 - - - - - - 0 - 6 - - - 1 - center - center - - - - 0 - emblem-system-symbolic - - - - - - - - end - center - - - - 1 - 0 - 2 - - - - - - - - - - - - - - - - - 0 - - - - 0 - none - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Behaviour when clicking on the icon of a running application. - 1 - - - - 0 - 1 - - - - - - 0 - 1 - start - Click action - - - 0 - 0 - - - - - - 0 - 6 - - - 1 - center - - - 0 - emblem-system-symbolic - - - - - - - - 0 - center - - Raise window - Minimize - Launch new instance - Cycle through windows - Minimize or overview - Show window previews - Minimize or show previews - Focus or show previews - Focus, minimize or show previews - - - - - 1 - 0 - 2 - - - - - - - - - - - - - - - - - 0 - - - - 0 - none - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Behaviour when scrolling on the icon of an application. - 1 - - - - 0 - 1 - - - - - - 0 - 1 - start - Scroll action - - - 0 - 0 - - - - - - 0 - 6 - - - 0 - center - - Do nothing - Cycle through windows - Switch workspace - - - - - 1 - 0 - 2 - - - - - - - - - - - - - - - - - - - 0 - start - Behavior - - - - - - - 3 - - - 0 - 24 - 24 - 24 - 24 - vertical - 24 - - - 0 - - - - none - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Few customizations meant to integrate the dock with the default GNOME theme. Alternatively, specific options can be enabled below. - 1 - - - - 0 - 1 - - - - - - 0 - 1 - start - Use built-in theme - - - 0 - 0 - - - - - - end - center - - 1 - 0 - 2 - - - - - - - - - - - - - - - - - 0 - - - - 0 - none - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - end - center - - 1 - 0 - 2 - - - - - - 0 - 1 - start - Save space reducing padding and border radius. - - - - 0 - 1 - - - - - - 0 - 1 - start - Shrink the dash - - - 0 - 0 - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Customize windows counter indicators - - - 0 - 0 - - - - - - 0 - 6 - - - 1 - center - center - - - - 0 - emblem-system-symbolic - - - - - - - - 0 - - Default - Dots - Squares - Dashes - Segmented - Solid - Ciliora - Metro - - - - - 1 - 0 - 2 - - - - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Set the background color for the dash. - 1 - - - - 0 - 1 - - - - - - 0 - 1 - start - Customize the dash color - - - 0 - 0 - - - - - - 0 - 6 - - - 1 - center - center - - - - - - end - center - - - - 1 - 0 - 2 - - - - - - - - - - - - 0 - vertical - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Tune the dash background opacity. - - - - 0 - 1 - - - - - - 0 - 1 - start - Customize opacity - - - 0 - 0 - - - - - - 0 - 6 - - - 1 - center - center - - - 0 - emblem-system-symbolic - - - - - - - - 0 - center - - Default - Fixed - Dynamic - - - - - 1 - 0 - 2 - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - Opacity - - - - - 1 - 1 - custom_opacity_adjustement - - 0 - 0 - 0 - 2 - right - - - - - - - - - - - - 100 - 80 - - - 0 - 32 - - - 1 - 0 - center - start - Force straight corner - - - - - - center - 3 - - - - - - - - - - - - - - - - - - 0 - Appearance - - - - - - - 4 - - - 0 - 0 - 24 - 24 - 1 - 1 - vertical - 5 - - - - - - 0 - <b>Dash to Dock</b> - 1 - - - - - 0 - center - - - 0 - end - version: - - - - - 0 - start - ... - - - - - - - 0 - Moves the dash out of the overview transforming it in a dock - center - 1 - - - - - 0 - center - 5 - - - 0 - Created by - - - - - Michele (<a href="mailto:micxgx@gmail.com">micxgx@gmail.com</a>) - 1 - - - - - - - Webpage - 1 - center - - https://micheleg.github.io/dash-to-dock/ - - - - - 1 - end - <span size="small">This program comes with ABSOLUTELY NO WARRANTY. -See the <a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU General Public License, version 2 or later</a> for details.</span> - 1 - center - 1 - - - - - - - 0 - About - - - - - - - 1 - 0.01 - 0.10000000000000001 - - - 1 - 0.01 - 0.10000000000000001 - - - 0 - 12 - 12 - 12 - 12 - vertical - - - 0 - - - - 0 - none - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - vertical - 12 - - - 0 - 32 - - - - 1 - 0 - - - - - - 0 - 1 - Customize minimum and maximum opacity values - fill - - - 0 - 0 - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - Minimum opacity - - - - - 1 - 1 - min_opacity_adjustement - - 0 - 0 - 0 - 2 - right - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - Maximum opacity - - - - - 1 - 1 - max_opacity_adjustement - - 0 - 0 - 0 - 2 - right - - - - - - - - - - - - - - - - - - - 1000 - 50 - 250 - - - 10 - 0.25 - 1 - - - 0 - 12 - 12 - 12 - 12 - vertical - - - 0 - - - - 0 - none - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - end - center - - 1 - 0 - 2 - - - - - - 0 - 1 - Number overlay - - - 0 - 0 - - - - - - 0 - Temporarily show the application numbers over the icons, corresponding to the shortcut. - 1 - 40 - - - - 0 - 1 - - - - - - - - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - end - center - - 1 - 0 - 2 - - - - - - 0 - 1 - start - Show the dock if it is hidden - - - 0 - 0 - - - - - - 0 - If using autohide, the dock will appear for a short time when triggering the shortcut. - 1 - 40 - - - - 0 - 1 - - - - - - - - - - 100 - 80 - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - center - 12 - - 1 - 0 - - - - - - 0 - 1 - Shortcut for the options above - - - 0 - 0 - - - - - - 0 - Syntax: <Shift>, <Ctrl>, <Alt>, <Super> - 1 - 40 - - - - 0 - 1 - - - - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 1 - 6 - 32 - - - end - shortcut_time_adjustment - 3 - - 1 - 0 - - - - - - 0 - 1 - Hide timeout (s) - - - 0 - 0 - - - - - - - - - - - - - - - - - 1 - 0.050000000000000003 - 0.25 - - - 0 - 12 - 12 - 12 - 12 - vertical - - - 0 - - - - 0 - none - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Show the dock by mouse hover on the screen edge. - 1 - - - - 0 - 1 - - - - - - 0 - 1 - Autohide - - - 0 - 0 - - - - - - end - center - - 1 - 0 - 2 - - - - - - Push to show: require pressure to show the dock - - - 0 - 3 - 2 - - - - - - Enable in fullscreen mode - 12 - - - 0 - 2 - 2 - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 32 - - - 0 - 1 - start - Show the dock when it doesn't obstruct application windows. - 1 - - - - 0 - 1 - - - - - - 0 - 1 - Dodge windows - - - 0 - 0 - - - - - - end - center - - 1 - 0 - 2 - - - - - - 0 - vertical - - - All windows - 12 - - 1 - - - - - - Only focused application's windows - - 1 - all_windows_radio_button - - - - - - Only maximized windows - - 1 - all_windows_radio_button - - - - - 0 - 2 - 2 - - - - - - - - - - - - 0 - 12 - 12 - 12 - 12 - 1 - 6 - 32 - - - end - animation_time_adjustment - 3 - - 1 - 0 - - - - - - 0 - 1 - Animation duration (s) - - - 0 - 0 - - - - - - end - hide_timeout_adjustment - 3 - - 1 - 1 - - - - - - end - show_timeout_adjustment - 3 - - 1 - 2 - - - - - - 0.000 - pressure_threshold_adjustment - - 1 - 3 - - - - - - 0 - 1 - Hide timeout (s) - - - 0 - 1 - - - - - - 0 - 1 - Show timeout (s) - - - 0 - 2 - - - - - - 0 - 1 - Pressure threshold - - - 0 - 3 - - - - - - - - - - - - - - - - diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/appIconIndicators.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/appIconIndicators.js deleted file mode 100644 index f015a80..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/appIconIndicators.js +++ /dev/null @@ -1,1078 +0,0 @@ -const Cairo = imports.cairo; -const Clutter = imports.gi.Clutter; -const GdkPixbuf = imports.gi.GdkPixbuf -const Gio = imports.gi.Gio; -const Graphene = imports.gi.Graphene; -const Gtk = imports.gi.Gtk; -const Main = imports.ui.main; -const Pango = imports.gi.Pango; -const Shell = imports.gi.Shell; -const St = imports.gi.St; - -const Util = imports.misc.util; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Docking = Me.imports.docking; -const Utils = Me.imports.utils; - -let tracker = Shell.WindowTracker.get_default(); - -const RunningIndicatorStyle = { - DEFAULT: 0, - DOTS: 1, - SQUARES: 2, - DASHES: 3, - SEGMENTED: 4, - SOLID: 5, - CILIORA: 6, - METRO: 7 -}; - -const MAX_WINDOWS_CLASSES = 4; - - -/* - * This is the main indicator class to be used. The desired bahviour is - * obtained by composing the desired classes below based on the settings. - * - */ -var AppIconIndicator = class DashToDock_AppIconIndicator { - - constructor(source) { - this._indicators = []; - - // Unity indicators always enabled for now - let unityIndicator = new UnityIndicator(source); - this._indicators.push(unityIndicator); - - // Choose the style for the running indicators - let runningIndicator = null; - let runningIndicatorStyle; - - let settings = Docking.DockManager.settings; - if (settings.get_boolean('apply-custom-theme' )) { - runningIndicatorStyle = RunningIndicatorStyle.DOTS; - } else { - runningIndicatorStyle = settings.get_enum('running-indicator-style'); - } - - switch (runningIndicatorStyle) { - case RunningIndicatorStyle.DEFAULT: - runningIndicator = new RunningIndicatorDefault(source); - break; - - case RunningIndicatorStyle.DOTS: - runningIndicator = new RunningIndicatorDots(source); - break; - - case RunningIndicatorStyle.SQUARES: - runningIndicator = new RunningIndicatorSquares(source); - break; - - case RunningIndicatorStyle.DASHES: - runningIndicator = new RunningIndicatorDashes(source); - break; - - case RunningIndicatorStyle.SEGMENTED: - runningIndicator = new RunningIndicatorSegmented(source); - break; - - case RunningIndicatorStyle.SOLID: - runningIndicator = new RunningIndicatorSolid(source); - break; - - case RunningIndicatorStyle.CILIORA: - runningIndicator = new RunningIndicatorCiliora(source); - break; - - case RunningIndicatorStyle.METRO: - runningIndicator = new RunningIndicatorMetro(source); - break; - - default: - runningIndicator = new RunningIndicatorBase(source); - } - - this._indicators.push(runningIndicator); - } - - update() { - for (let i=0; i { - this._signalsHandler.destroy(); - }); - } - - update() { - } - - destroy() { - this._source.disconnect(this._sourceDestroyId); - this._signalsHandler.destroy(); - } -}; - -/* - * A base indicator class for running style, from which all other EunningIndicators should derive, - * providing some basic methods, variables definitions and their update, css style classes handling. - * - */ -var RunningIndicatorBase = class DashToDock_RunningIndicatorBase extends IndicatorBase { - - constructor(source) { - super(source) - - this._side = Utils.getPosition(); - this._nWindows = 0; - - this._dominantColorExtractor = new DominantColorExtractor(this._source.app); - - // These statuses take into account the workspace/monitor isolation - this._isFocused = false; - this._isRunning = false; - } - - update() { - // Limit to 1 to MAX_WINDOWS_CLASSES windows classes - this._nWindows = Math.min(this._source.getInterestingWindows().length, MAX_WINDOWS_CLASSES); - - // We need to check the number of windows, as the focus might be - // happening on another monitor if using isolation - if (tracker.focus_app == this._source.app && this._nWindows > 0) - this._isFocused = true; - else - this._isFocused = false; - - // In the case of workspace isolation, we need to hide the dots of apps with - // no windows in the current workspace - if ((this._source.app.state != Shell.AppState.STOPPED || this._source.isLocation()) && this._nWindows > 0) - this._isRunning = true; - else - this._isRunning = false; - - this._updateCounterClass(); - this._updateFocusClass(); - this._updateDefaultDot(); - } - - _updateCounterClass() { - for (let i = 1; i <= MAX_WINDOWS_CLASSES; i++) { - let className = 'running' + i; - if (i != this._nWindows) - this._source.remove_style_class_name(className); - else - this._source.add_style_class_name(className); - } - } - - _updateFocusClass() { - if (this._isFocused) - this._source.add_style_class_name('focused'); - else - this._source.remove_style_class_name('focused'); - } - - _updateDefaultDot() { - if (this._isRunning) - this._source._dot.show(); - else - this._source._dot.hide(); - } - - _hideDefaultDot() { - // I use opacity to hide the default dot because the show/hide function - // are used by the parent class. - this._source._dot.opacity = 0; - } - - _restoreDefaultDot() { - this._source._dot.opacity = 255; - } - - _enableBacklight() { - - let colorPalette = this._dominantColorExtractor._getColorPalette(); - - // Fallback - if (colorPalette === null) { - this._source._iconContainer.set_style( - 'border-radius: 5px;' + - 'background-gradient-direction: vertical;' + - 'background-gradient-start: #e0e0e0;' + - 'background-gradient-end: darkgray;' - ); - - return; - } - - this._source._iconContainer.set_style( - 'border-radius: 5px;' + - 'background-gradient-direction: vertical;' + - 'background-gradient-start: ' + colorPalette.original + ';' + - 'background-gradient-end: ' + colorPalette.darker + ';' - ); - - } - - _disableBacklight() { - this._source._iconContainer.set_style(null); - } - - destroy() { - this._disableBacklight(); - // Remove glossy background if the children still exists - if (this._source._iconContainer.get_children().length > 1) - this._source._iconContainer.get_children()[1].set_style(null); - this._restoreDefaultDot(); - - super.destroy(); - } -}; - -// We add a css class so third parties themes can limit their indicaor customization -// to the case we do nothing -var RunningIndicatorDefault = class DashToDock_RunningIndicatorDefault extends RunningIndicatorBase { - - constructor(source) { - super(source); - this._source.add_style_class_name('default'); - } - - destroy() { - this._source.remove_style_class_name('default'); - super.destroy(); - } -}; - -var RunningIndicatorDots = class DashToDock_RunningIndicatorDots extends RunningIndicatorBase { - - constructor(source) { - super(source) - - this._hideDefaultDot(); - - this._area = new St.DrawingArea({x_expand: true, y_expand: true}); - - // We draw for the bottom case and rotate the canvas for other placements - //set center of rotatoins to the center - this._area.set_pivot_point(0.5, 0.5); - // prepare transformation matrix - let m = new Graphene.Matrix(); - m.init_identity(); - let v = new Graphene.Vec3(); - v.init(0, 0, 1); - - switch (this._side) { - case St.Side.TOP: - m.xx = -1; - m.rotate(180, v); - break - - case St.Side.BOTTOM: - // nothing - break; - - case St.Side.LEFT: - m.yy = -1; - m.rotate(90, v); - break; - - case St.Side.RIGHT: - m.rotate(-90, v); - break - } - - this._area.set_transform(m); - - this._area.connect('repaint', this._updateIndicator.bind(this)); - this._source._iconContainer.add_child(this._area); - - let keys = ['custom-theme-running-dots-color', - 'custom-theme-running-dots-border-color', - 'custom-theme-running-dots-border-width', - 'custom-theme-customize-running-dots', - 'unity-backlit-items', - 'running-indicator-dominant-color']; - - keys.forEach(function(key) { - this._signalsHandler.add([ - Docking.DockManager.settings, - 'changed::' + key, - this.update.bind(this) - ]); - }, this); - - // Apply glossy background - // TODO: move to enable/disableBacklit to apply itonly to the running apps? - // TODO: move to css class for theming support - this._glossyBackgroundStyle = 'background-image: url(\'' + Me.path + '/media/glossy.svg\');' + - 'background-size: contain;'; - } - - update() { - super.update(); - - // Enable / Disable the backlight of running apps - if (!Docking.DockManager.settings.get_boolean('apply-custom-theme') && - Docking.DockManager.settings.get_boolean('unity-backlit-items')) { - this._source._iconContainer.get_children()[1].set_style(this._glossyBackgroundStyle); - if (this._isRunning) - this._enableBacklight(); - else - this._disableBacklight(); - } else { - this._disableBacklight(); - this._source._iconContainer.get_children()[1].set_style(null); - } - - if (this._area) - this._area.queue_repaint(); - } - - _computeStyle() { - - let [width, height] = this._area.get_surface_size(); - this._width = height; - this._height = width; - - // By defaut re-use the style - background color, and border width and color - - // of the default dot - let themeNode = this._source._dot.get_theme_node(); - this._borderColor = themeNode.get_border_color(this._side); - this._borderWidth = themeNode.get_border_width(this._side); - this._bodyColor = themeNode.get_background_color(); - - let settings = Docking.DockManager.settings; - if (!settings.get_boolean('apply-custom-theme')) { - // Adjust for the backlit case - if (settings.get_boolean('unity-backlit-items')) { - // Use dominant color for dots too if the backlit is enables - let colorPalette = this._dominantColorExtractor._getColorPalette(); - - // Slightly adjust the styling - this._borderWidth = 2; - - if (colorPalette !== null) { - this._borderColor = Clutter.color_from_string(colorPalette.lighter)[1] ; - this._bodyColor = Clutter.color_from_string(colorPalette.darker)[1]; - } else { - // Fallback - this._borderColor = Clutter.color_from_string('white')[1]; - this._bodyColor = Clutter.color_from_string('gray')[1]; - } - } - - // Apply dominant color if requested - if (settings.get_boolean('running-indicator-dominant-color')) { - let colorPalette = this._dominantColorExtractor._getColorPalette(); - if (colorPalette !== null) { - this._bodyColor = Clutter.color_from_string(colorPalette.original)[1]; - } - } - - // Finally, use customize style if requested - if (settings.get_boolean('custom-theme-customize-running-dots')) { - this._borderColor = Clutter.color_from_string(settings.get_string('custom-theme-running-dots-border-color'))[1]; - this._borderWidth = settings.get_int('custom-theme-running-dots-border-width'); - this._bodyColor = Clutter.color_from_string(settings.get_string('custom-theme-running-dots-color'))[1]; - } - } - - // Define the radius as an arbitrary size, but keep large enough to account - // for the drawing of the border. - this._radius = Math.max(this._width/22, this._borderWidth/2); - this._padding = 0; // distance from the margin - this._spacing = this._radius + this._borderWidth; // separation between the dots - } - - _updateIndicator() { - - let area = this._area; - let cr = this._area.get_context(); - - this._computeStyle(); - this._drawIndicator(cr); - cr.$dispose(); - } - - _drawIndicator(cr) { - // Draw the required numbers of dots - let n = this._nWindows; - - cr.setLineWidth(this._borderWidth); - Clutter.cairo_set_source_color(cr, this._borderColor); - - // draw for the bottom case: - cr.translate((this._width - (2*n)*this._radius - (n-1)*this._spacing)/2, this._height - this._padding); - for (let i = 0; i < n; i++) { - cr.newSubPath(); - cr.arc((2*i+1)*this._radius + i*this._spacing, -this._radius - this._borderWidth/2, this._radius, 0, 2*Math.PI); - } - - cr.strokePreserve(); - Clutter.cairo_set_source_color(cr, this._bodyColor); - cr.fill(); - } - - destroy() { - this._area.destroy(); - super.destroy(); - } -}; - -// Adapted from dash-to-panel by Jason DeRose -// https://github.com/jderose9/dash-to-panel -var RunningIndicatorCiliora = class DashToDock_RunningIndicatorCiliora extends RunningIndicatorDots { - - _drawIndicator(cr) { - if (this._isRunning) { - - let size = Math.max(this._width/20, this._borderWidth); - let spacing = size; // separation between the dots - let lineLength = this._width - (size*(this._nWindows-1)) - (spacing*(this._nWindows-1)); - let padding = this._borderWidth; - // For the backlit case here we don't want the outer border visible - if (Docking.DockManager.settings.get_boolean('unity-backlit-items') && - !Docking.DockManager.settings.get_boolean('custom-theme-customize-running-dots')) - padding = 0; - let yOffset = this._height - padding - size; - - cr.setLineWidth(this._borderWidth); - Clutter.cairo_set_source_color(cr, this._borderColor); - - cr.translate(0, yOffset); - cr.newSubPath(); - cr.rectangle(0, 0, lineLength, size); - for (let i = 1; i < this._nWindows; i++) { - cr.newSubPath(); - cr.rectangle(lineLength + (i*spacing) + ((i-1)*size), 0, size, size); - } - - cr.strokePreserve(); - Clutter.cairo_set_source_color(cr, this._bodyColor); - cr.fill(); - } - } -}; - -// Adapted from dash-to-panel by Jason DeRose -// https://github.com/jderose9/dash-to-panel -var RunningIndicatorSegmented = class DashToDock_RunningIndicatorSegmented extends RunningIndicatorDots { - - _drawIndicator(cr) { - if (this._isRunning) { - let size = Math.max(this._width/20, this._borderWidth); - let spacing = Math.ceil(this._width/18); // separation between the dots - let dashLength = Math.ceil((this._width - ((this._nWindows-1)*spacing))/this._nWindows); - let lineLength = this._width - (size*(this._nWindows-1)) - (spacing*(this._nWindows-1)); - let padding = this._borderWidth; - // For the backlit case here we don't want the outer border visible - if (Docking.DockManager.settings.get_boolean('unity-backlit-items') && - !Docking.DockManager.settings.get_boolean('custom-theme-customize-running-dots')) - padding = 0; - let yOffset = this._height - padding - size; - - cr.setLineWidth(this._borderWidth); - Clutter.cairo_set_source_color(cr, this._borderColor); - - cr.translate(0, yOffset); - for (let i = 0; i < this._nWindows; i++) { - cr.newSubPath(); - cr.rectangle(i*dashLength + i*spacing, 0, dashLength, size); - } - - cr.strokePreserve(); - Clutter.cairo_set_source_color(cr, this._bodyColor); - cr.fill() - } - } -}; - -// Adapted from dash-to-panel by Jason DeRose -// https://github.com/jderose9/dash-to-panel -var RunningIndicatorSolid = class DashToDock_RunningIndicatorSolid extends RunningIndicatorDots { - - _drawIndicator(cr) { - if (this._isRunning) { - - let size = Math.max(this._width/20, this._borderWidth); - let padding = this._borderWidth; - // For the backlit case here we don't want the outer border visible - if (Docking.DockManager.settings.get_boolean('unity-backlit-items') && - !Docking.DockManager.settings.get_boolean('custom-theme-customize-running-dots')) - padding = 0; - let yOffset = this._height - padding - size; - - cr.setLineWidth(this._borderWidth); - Clutter.cairo_set_source_color(cr, this._borderColor); - - cr.translate(0, yOffset); - cr.newSubPath(); - cr.rectangle(0, 0, this._width, size); - - cr.strokePreserve(); - Clutter.cairo_set_source_color(cr, this._bodyColor); - cr.fill(); - - } - } -}; - -// Adapted from dash-to-panel by Jason DeRose -// https://github.com/jderose9/dash-to-panel -var RunningIndicatorSquares = class DashToDock_RunningIndicatorSquares extends RunningIndicatorDots { - - _drawIndicator(cr) { - if (this._isRunning) { - let size = Math.max(this._width/11, this._borderWidth); - let padding = this._borderWidth; - let spacing = Math.ceil(this._width/18); // separation between the dots - let yOffset = this._height - padding - size; - - cr.setLineWidth(this._borderWidth); - Clutter.cairo_set_source_color(cr, this._borderColor); - - cr.translate(Math.floor((this._width - this._nWindows*size - (this._nWindows-1)*spacing)/2), yOffset); - for (let i = 0; i < this._nWindows; i++) { - cr.newSubPath(); - cr.rectangle(i*size + i*spacing, 0, size, size); - } - cr.strokePreserve(); - Clutter.cairo_set_source_color(cr, this._bodyColor); - cr.fill(); - } - } -} - -// Adapted from dash-to-panel by Jason DeRose -// https://github.com/jderose9/dash-to-panel -var RunningIndicatorDashes = class DashToDock_RunningIndicatorDashes extends RunningIndicatorDots { - - _drawIndicator(cr) { - if (this._isRunning) { - let size = Math.max(this._width/20, this._borderWidth); - let padding = this._borderWidth; - let spacing = Math.ceil(this._width/18); // separation between the dots - let dashLength = Math.floor(this._width/4) - spacing; - let yOffset = this._height - padding - size; - - cr.setLineWidth(this._borderWidth); - Clutter.cairo_set_source_color(cr, this._borderColor); - - cr.translate(Math.floor((this._width - this._nWindows*dashLength - (this._nWindows-1)*spacing)/2), yOffset); - for (let i = 0; i < this._nWindows; i++) { - cr.newSubPath(); - cr.rectangle(i*dashLength + i*spacing, 0, dashLength, size); - } - - cr.strokePreserve(); - Clutter.cairo_set_source_color(cr, this._bodyColor); - cr.fill(); - } - } -} - -// Adapted from dash-to-panel by Jason DeRose -// https://github.com/jderose9/dash-to-panel -var RunningIndicatorMetro = class DashToDock_RunningIndicatorMetro extends RunningIndicatorDots { - - constructor(source) { - super(source); - this._source.add_style_class_name('metro'); - } - - destroy() { - this._source.remove_style_class_name('metro'); - super.destroy(); - } - - _drawIndicator(cr) { - if (this._isRunning) { - let size = Math.max(this._width/20, this._borderWidth); - let padding = 0; - // For the backlit case here we don't want the outer border visible - if (Docking.DockManager.settings.get_boolean('unity-backlit-items') && - !Docking.DockManager.settings.get_boolean('custom-theme-customize-running-dots')) - padding = 0; - let yOffset = this._height - padding - size; - - let n = this._nWindows; - if(n <= 1) { - cr.translate(0, yOffset); - Clutter.cairo_set_source_color(cr, this._bodyColor); - cr.newSubPath(); - cr.rectangle(0, 0, this._width, size); - cr.fill(); - } else { - let blackenedLength = (1/48)*this._width; // need to scale with the SVG for the stacked highlight - let darkenedLength = this._isFocused ? (2/48)*this._width : (10/48)*this._width; - let blackenedColor = this._bodyColor.shade(.3); - let darkenedColor = this._bodyColor.shade(.7); - - cr.translate(0, yOffset); - - Clutter.cairo_set_source_color(cr, this._bodyColor); - cr.newSubPath(); - cr.rectangle(0, 0, this._width - darkenedLength - blackenedLength, size); - cr.fill(); - Clutter.cairo_set_source_color(cr, blackenedColor); - cr.newSubPath(); - cr.rectangle(this._width - darkenedLength - blackenedLength, 0, 1, size); - cr.fill(); - Clutter.cairo_set_source_color(cr, darkenedColor); - cr.newSubPath(); - cr.rectangle(this._width - darkenedLength, 0, darkenedLength, size); - cr.fill(); - } - } - } -} - -/* - * Unity like notification and progress indicators - */ -var UnityIndicator = class DashToDock_UnityIndicator extends IndicatorBase { - - constructor(source) { - - super(source); - - this._notificationBadgeLabel = new St.Label(); - this._notificationBadgeBin = new St.Bin({ - child: this._notificationBadgeLabel, - x_align: Clutter.ActorAlign.END, - y_align: Clutter.ActorAlign.START, - x_expand: true, y_expand: true - }); - this._notificationBadgeLabel.add_style_class_name('notification-badge'); - this._notificationBadgeLabel.clutter_text.ellipsize = Pango.EllipsizeMode.MIDDLE; - this._notificationBadgeBin.hide(); - - this._source._iconContainer.add_child(this._notificationBadgeBin); - this.updateNotificationBadgeStyle(); - - const remoteEntry = this._source.remoteModel.lookupById(this._source.app.id); - this._signalsHandler.add([ - remoteEntry, - ['count-changed', 'count-visible-changed'], - (sender, { count, count_visible }) => - this.setNotificationCount(count_visible ? count : 0) - ], [ - remoteEntry, - ['progress-changed', 'progress-visible-changed'], - (sender, { progress, progress_visible }) => - this.setProgress(progress_visible ? progress : -1) - ], [ - remoteEntry, - 'urgent-changed', - (sender, { urgent }) => this.setUrgent(urgent) - ], [ - St.ThemeContext.get_for_stage(global.stage), - 'changed', - this.updateNotificationBadgeStyle.bind(this) - ], [ - this._source._iconContainer, - 'notify::size', - this.updateNotificationBadgeStyle.bind(this) - ]); - - this._isUrgent = false; - } - - updateNotificationBadgeStyle() { - let themeContext = St.ThemeContext.get_for_stage(global.stage); - let fontDesc = themeContext.get_font(); - let defaultFontSize = fontDesc.get_size() / 1024; - let fontSize = defaultFontSize * 0.9; - let iconSize = Main.overview.dash.iconSize; - let defaultIconSize = Docking.DockManager.settings.get_default_value( - 'dash-max-icon-size').unpack(); - - if (!fontDesc.get_size_is_absolute()) { - // fontSize was exprimed in points, so convert to pixel - fontSize /= 0.75; - } - - fontSize = Math.round((iconSize / defaultIconSize) * fontSize); - let leftMargin = Math.round((iconSize / defaultIconSize) * 3); - - this._notificationBadgeLabel.set_style( - 'font-size: ' + fontSize + 'px;' + - 'margin-left: ' + leftMargin + 'px' - ); - } - - _notificationBadgeCountToText(count) { - if (count <= 9999) { - return count.toString(); - } else if (count < 1e5) { - let thousands = count / 1e3; - return thousands.toFixed(1).toString() + "k"; - } else if (count < 1e6) { - let thousands = count / 1e3; - return thousands.toFixed(0).toString() + "k"; - } else if (count < 1e8) { - let millions = count / 1e6; - return millions.toFixed(1).toString() + "M"; - } else if (count < 1e9) { - let millions = count / 1e6; - return millions.toFixed(0).toString() + "M"; - } else { - let billions = count / 1e9; - return billions.toFixed(1).toString() + "B"; - } - } - - setNotificationCount(count) { - if (count > 0) { - let text = this._notificationBadgeCountToText(count); - this._notificationBadgeLabel.set_text(text); - this._notificationBadgeBin.show(); - } else { - this._notificationBadgeBin.hide(); - } - } - - _showProgressOverlay() { - if (this._progressOverlayArea) { - this._updateProgressOverlay(); - return; - } - - this._progressOverlayArea = new St.DrawingArea({x_expand: true, y_expand: true}); - this._progressOverlayArea.add_style_class_name('progress-bar'); - this._progressOverlayArea.connect('repaint', () => { - this._drawProgressOverlay(this._progressOverlayArea); - }); - - this._source._iconContainer.add_child(this._progressOverlayArea); - let node = this._progressOverlayArea.get_theme_node(); - - let [hasColor, color] = node.lookup_color('-progress-bar-background', false); - if (hasColor) - this._progressbar_background = color - else - this._progressbar_background = new Clutter.Color({red: 204, green: 204, blue: 204, alpha: 255}); - - [hasColor, color] = node.lookup_color('-progress-bar-border', false); - if (hasColor) - this._progressbar_border = color; - else - this._progressbar_border = new Clutter.Color({red: 230, green: 230, blue: 230, alpha: 255}); - - this._updateProgressOverlay(); - } - - _hideProgressOverlay() { - if (this._progressOverlayArea) - this._progressOverlayArea.destroy(); - this._progressOverlayArea = null; - this._progressbar_background = null; - this._progressbar_border = null; - } - - _updateProgressOverlay() { - if (this._progressOverlayArea) - this._progressOverlayArea.queue_repaint(); - } - - _drawProgressOverlay(area) { - let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; - let [surfaceWidth, surfaceHeight] = area.get_surface_size(); - let cr = area.get_context(); - - let iconSize = this._source.icon.iconSize * scaleFactor; - - let x = Math.floor((surfaceWidth - iconSize) / 2); - let y = Math.floor((surfaceHeight - iconSize) / 2); - - let lineWidth = Math.floor(1.0 * scaleFactor); - let padding = Math.floor(iconSize * 0.05); - let width = iconSize - 2.0*padding; - let height = Math.floor(Math.min(18.0*scaleFactor, 0.20*iconSize)); - x += padding; - y += iconSize - height - padding; - - cr.setLineWidth(lineWidth); - - // Draw the outer stroke - let stroke = new Cairo.LinearGradient(0, y, 0, y + height); - let fill = null; - stroke.addColorStopRGBA(0.5, 0.5, 0.5, 0.5, 0.1); - stroke.addColorStopRGBA(0.9, 0.8, 0.8, 0.8, 0.4); - Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, width, height, true, true, stroke, fill); - - // Draw the background - x += lineWidth; - y += lineWidth; - width -= 2.0*lineWidth; - height -= 2.0*lineWidth; - - stroke = Cairo.SolidPattern.createRGBA(0.20, 0.20, 0.20, 0.9); - fill = new Cairo.LinearGradient(0, y, 0, y + height); - fill.addColorStopRGBA(0.4, 0.25, 0.25, 0.25, 1.0); - fill.addColorStopRGBA(0.9, 0.35, 0.35, 0.35, 1.0); - Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, width, height, true, true, stroke, fill); - - // Draw the finished bar - x += lineWidth; - y += lineWidth; - width -= 2.0*lineWidth; - height -= 2.0*lineWidth; - - let finishedWidth = Math.ceil(this._progress * width); - - let bg = this._progressbar_background; - let bd = this._progressbar_border; - - stroke = Cairo.SolidPattern.createRGBA(bd.red/255, bd.green/255, bd.blue/255, bd.alpha/255); - fill = Cairo.SolidPattern.createRGBA(bg.red/255, bg.green/255, bg.blue/255, bg.alpha/255); - - if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) - Utils.drawRoundedLine(cr, x + lineWidth/2.0 + width - finishedWidth, y + lineWidth/2.0, finishedWidth, height, true, true, stroke, fill); - else - Utils.drawRoundedLine(cr, x + lineWidth/2.0, y + lineWidth/2.0, finishedWidth, height, true, true, stroke, fill); - - cr.$dispose(); - } - - setProgress(progress) { - if (progress < 0) { - this._hideProgressOverlay(); - } else { - this._progress = Math.min(progress, 1.0); - this._showProgressOverlay(); - } - } - - setUrgent(urgent) { - const icon = this._source.icon._iconBin; - if (urgent) { - if (!this._isUrgent) { - icon.set_pivot_point(0.5, 0.5); - this._source.iconAnimator.addAnimation(icon, 'dance'); - this._isUrgent = true; - } - } else { - if (this._isUrgent) { - this._source.iconAnimator.removeAnimation(icon, 'dance'); - this._isUrgent = false; - } - icon.rotation_angle_z = 0; - } - } -} - - -// We need an icons theme object, this is the only way I managed to get -// pixel buffers that can be used for calculating the backlight color -let themeLoader = null; - -// Global icon cache. Used for Unity7 styling. -let iconCacheMap = new Map(); -// Max number of items to store -// We don't expect to ever reach this number, but let's put an hard limit to avoid -// even the remote possibility of the cached items to grow indefinitely. -const MAX_CACHED_ITEMS = 1000; -// When the size exceed it, the oldest 'n' ones are deleted -const BATCH_SIZE_TO_DELETE = 50; -// The icon size used to extract the dominant color -const DOMINANT_COLOR_ICON_SIZE = 64; - -// Compute dominant color frim the app icon. -// The color is cached for efficiency. -var DominantColorExtractor = class DashToDock_DominantColorExtractor { - - constructor(app) { - this._app = app; - } - - /** - * Try to get the pixel buffer for the current icon, if not fail gracefully - */ - _getIconPixBuf() { - let iconTexture = this._app.create_icon_texture(16); - - if (themeLoader === null) { - let ifaceSettings = new Gio.Settings({ schema: "org.gnome.desktop.interface" }); - - themeLoader = new Gtk.IconTheme(), - themeLoader.set_custom_theme(ifaceSettings.get_string('icon-theme')); // Make sure the correct theme is loaded - } - - // Unable to load the icon texture, use fallback - if (iconTexture instanceof St.Icon === false) { - return null; - } - - iconTexture = iconTexture.get_gicon(); - - // Unable to load the icon texture, use fallback - if (iconTexture === null) { - return null; - } - - if (iconTexture instanceof Gio.FileIcon) { - // Use GdkPixBuf to load the pixel buffer from the provided file path - return GdkPixbuf.Pixbuf.new_from_file(iconTexture.get_file().get_path()); - } - - // Get the pixel buffer from the icon theme - let icon_info = themeLoader.lookup_icon(iconTexture.get_names()[0], DOMINANT_COLOR_ICON_SIZE, 0); - if (icon_info !== null) - return icon_info.load_icon(); - else - return null; - } - - /** - * The backlight color choosing algorithm was mostly ported to javascript from the - * Unity7 C++ source of Canonicals: - * https://bazaar.launchpad.net/~unity-team/unity/trunk/view/head:/launcher/LauncherIcon.cpp - * so it more or less works the same way. - */ - _getColorPalette() { - if (iconCacheMap.get(this._app.get_id())) { - // We already know the answer - return iconCacheMap.get(this._app.get_id()); - } - - let pixBuf = this._getIconPixBuf(); - if (pixBuf == null) - return null; - - let pixels = pixBuf.get_pixels(), - offset = 0; - - let total = 0, - rTotal = 0, - gTotal = 0, - bTotal = 0; - - let resample_y = 1, - resample_x = 1; - - // Resampling of large icons - // We resample icons larger than twice the desired size, as the resampling - // to a size s - // DOMINANT_COLOR_ICON_SIZE < s < 2*DOMINANT_COLOR_ICON_SIZE, - // most of the case exactly DOMINANT_COLOR_ICON_SIZE as the icon size is tipycally - // a multiple of it. - let width = pixBuf.get_width(); - let height = pixBuf.get_height(); - - // Resample - if (height >= 2* DOMINANT_COLOR_ICON_SIZE) - resample_y = Math.floor(height/DOMINANT_COLOR_ICON_SIZE); - - if (width >= 2* DOMINANT_COLOR_ICON_SIZE) - resample_x = Math.floor(width/DOMINANT_COLOR_ICON_SIZE); - - if (resample_x !==1 || resample_y !== 1) - pixels = this._resamplePixels(pixels, resample_x, resample_y); - - // computing the limit outside the for (where it would be repeated at each iteration) - // for performance reasons - let limit = pixels.length; - for (let offset = 0; offset < limit; offset+=4) { - let r = pixels[offset], - g = pixels[offset + 1], - b = pixels[offset + 2], - a = pixels[offset + 3]; - - let saturation = (Math.max(r,g, b) - Math.min(r,g, b)); - let relevance = 0.1 * 255 * 255 + 0.9 * a * saturation; - - rTotal += r * relevance; - gTotal += g * relevance; - bTotal += b * relevance; - - total += relevance; - } - - total = total * 255; - - let r = rTotal / total, - g = gTotal / total, - b = bTotal / total; - - let hsv = Utils.ColorUtils.RGBtoHSV(r * 255, g * 255, b * 255); - - if (hsv.s > 0.15) - hsv.s = 0.65; - hsv.v = 0.90; - - let rgb = Utils.ColorUtils.HSVtoRGB(hsv.h, hsv.s, hsv.v); - - // Cache the result. - let backgroundColor = { - lighter: Utils.ColorUtils.ColorLuminance(rgb.r, rgb.g, rgb.b, 0.2), - original: Utils.ColorUtils.ColorLuminance(rgb.r, rgb.g, rgb.b, 0), - darker: Utils.ColorUtils.ColorLuminance(rgb.r, rgb.g, rgb.b, -0.5) - }; - - if (iconCacheMap.size >= MAX_CACHED_ITEMS) { - //delete oldest cached values (which are in order of insertions) - let ctr=0; - for (let key of iconCacheMap.keys()) { - if (++ctr > BATCH_SIZE_TO_DELETE) - break; - iconCacheMap.delete(key); - } - } - - iconCacheMap.set(this._app.get_id(), backgroundColor); - - return backgroundColor; - } - - /** - * Downsample large icons before scanning for the backlight color to - * improve performance. - * - * @param pixBuf - * @param pixels - * @param resampleX - * @param resampleY - * - * @return []; - */ - _resamplePixels (pixels, resampleX, resampleY) { - let resampledPixels = []; - // computing the limit outside the for (where it would be repeated at each iteration) - // for performance reasons - let limit = pixels.length / (resampleX * resampleY) / 4; - for (let i = 0; i < limit; i++) { - let pixel = i * resampleX * resampleY; - - resampledPixels.push(pixels[pixel * 4]); - resampledPixels.push(pixels[pixel * 4 + 1]); - resampledPixels.push(pixels[pixel * 4 + 2]); - resampledPixels.push(pixels[pixel * 4 + 3]); - } - - return resampledPixels; - } -}; diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/appIcons.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/appIcons.js deleted file mode 100644 index e10fb46..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/appIcons.js +++ /dev/null @@ -1,1273 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Clutter = imports.gi.Clutter; -const GdkPixbuf = imports.gi.GdkPixbuf -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Signals = imports.signals; -const Meta = imports.gi.Meta; -const Shell = imports.gi.Shell; -const St = imports.gi.St; - -// Use __ () and N__() for the extension gettext domain, and reuse -// the shell domain with the default _() and N_() -const Gettext = imports.gettext.domain('dashtodock'); -const __ = Gettext.gettext; -const N__ = function(e) { return e }; - -const AppDisplay = imports.ui.appDisplay; -const AppFavorites = imports.ui.appFavorites; -const Dash = imports.ui.dash; -const DND = imports.ui.dnd; -const IconGrid = imports.ui.iconGrid; -const Main = imports.ui.main; -const PopupMenu = imports.ui.popupMenu; -const Util = imports.misc.util; -const Workspace = imports.ui.workspace; - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Docking = Me.imports.docking; -const Utils = Me.imports.utils; -const WindowPreview = Me.imports.windowPreview; -const AppIconIndicators = Me.imports.appIconIndicators; -const DbusmenuUtils = Me.imports.dbusmenuUtils; - -let tracker = Shell.WindowTracker.get_default(); - -const clickAction = { - SKIP: 0, - MINIMIZE: 1, - LAUNCH: 2, - CYCLE_WINDOWS: 3, - MINIMIZE_OR_OVERVIEW: 4, - PREVIEWS: 5, - MINIMIZE_OR_PREVIEWS: 6, - FOCUS_OR_PREVIEWS: 7, - FOCUS_MINIMIZE_OR_PREVIEWS: 8, - QUIT: 9 -}; - -const scrollAction = { - DO_NOTHING: 0, - CYCLE_WINDOWS: 1, - SWITCH_WORKSPACE: 2 -}; - -let recentlyClickedAppLoopId = 0; -let recentlyClickedApp = null; -let recentlyClickedAppWindows = null; -let recentlyClickedAppIndex = 0; -let recentlyClickedAppMonitor = -1; - -/** - * Extend AppIcon - * - * - Apply a css class based on the number of windows of each application (#N); - * - Customized indicators for running applications in place of the default "dot" style which is hidden (#N); - * a class of the form "running#N" is applied to the AppWellIcon actor. - * like the original .running one. - * - Add a .focused style to the focused app - * - Customize click actions. - * - Update minimization animation target - * - Update menu if open on windows change - */ -var MyAppIcon = GObject.registerClass( -class MyAppIcon extends Dash.DashIcon { - // settings are required inside. - _init(remoteModel, app, monitorIndex, iconAnimator) { - super._init(app); - - // a prefix is required to avoid conflicting with the parent class variable - this.monitorIndex = monitorIndex; - this._signalsHandler = new Utils.GlobalSignalsHandler(); - this.remoteModel = remoteModel; - this.iconAnimator = iconAnimator; - this._indicator = null; - - let appInfo = app.get_app_info(); - this._location = appInfo ? appInfo.get_string('XdtdUri') : null; - - this._updateIndicatorStyle(); - - // Monitor windows-changes instead of app state. - // Keep using the same Id and function callback (that is extended) - if (this._stateChangedId > 0) { - this.app.disconnect(this._stateChangedId); - this._stateChangedId = 0; - } - - this._windowsChangedId = this.app.connect('windows-changed', - this.onWindowsChanged.bind(this)); - this._focusAppChangeId = tracker.connect('notify::focus-app', - this._onFocusAppChanged.bind(this)); - - // In Wayland sessions, this signal is needed to track the state of windows dragged - // from one monitor to another. As this is triggered quite often (whenever a new winow - // of any application opened or moved to a different desktop), - // we restrict this signal to the case when 'isolate-monitors' is true, - // and if there are at least 2 monitors. - if (Docking.DockManager.settings.get_boolean('isolate-monitors') && - Main.layoutManager.monitors.length > 1) { - this._signalsHandler.removeWithLabel('isolate-monitors'); - this._signalsHandler.addWithLabel('isolate-monitors', [ - global.display, - 'window-entered-monitor', - this._onWindowEntered.bind(this) - ]); - } - - this._progressOverlayArea = null; - this._progress = 0; - - let keys = ['apply-custom-theme', - 'running-indicator-style', - ]; - - keys.forEach(function(key) { - this._signalsHandler.add([ - Docking.DockManager.settings, - 'changed::' + key, - this._updateIndicatorStyle.bind(this) - ]); - }, this); - - if (this._location) { - this._signalsHandler.add([ - Docking.DockManager.getDefault().fm1Client, - 'windows-changed', - this.onWindowsChanged.bind(this) - ]); - } - - this._numberOverlay(); - - this._previewMenuManager = null; - this._previewMenu = null; - } - - _onDestroy() { - super._onDestroy(); - - // This is necessary due to an upstream bug - // https://bugzilla.gnome.org/show_bug.cgi?id=757556 - // It can be safely removed once it get solved upstrea. - if (this._menu) - this._menu.close(false); - - // Disconect global signals - - if (this._windowsChangedId > 0) - this.app.disconnect(this._windowsChangedId); - this._windowsChangedId = 0; - - if (this._focusAppChangeId > 0) { - tracker.disconnect(this._focusAppChangeId); - this._focusAppChangeId = 0; - } - - this._signalsHandler.destroy(); - } - - // TOOD Rename this function - _updateIndicatorStyle() { - - if (this._indicator !== null) { - this._indicator.destroy(); - this._indicator = null; - } - this._indicator = new AppIconIndicators.AppIconIndicator(this); - this._indicator.update(); - } - - _onWindowEntered(metaScreen, monitorIndex, metaWin) { - let app = Shell.WindowTracker.get_default().get_window_app(metaWin); - if (app && app.get_id() == this.app.get_id()) - this.onWindowsChanged(); - } - - vfunc_scroll_event(scrollEvent) { - let settings = Docking.DockManager.settings; - let isEnabled = settings.get_enum('scroll-action') === scrollAction.CYCLE_WINDOWS; - if (!isEnabled) - return Clutter.EVENT_PROPAGATE; - - // We only activate windows of running applications, i.e. we never open new windows - // We check if the app is running, and that the # of windows is > 0 in - // case we use workspace isolation, - let appIsRunning = this.app.state == Shell.AppState.RUNNING - && this.getInterestingWindows().length > 0; - - if (!appIsRunning) - return Clutter.EVENT_PROPAGATE; - - if (this._optionalScrollCycleWindowsDeadTimeId) - return Clutter.EVENT_PROPAGATE; - else - this._optionalScrollCycleWindowsDeadTimeId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, 250, () => { - this._optionalScrollCycleWindowsDeadTimeId = 0; - }); - - let direction = null; - - switch (scrollEvent.direction) { - case Clutter.ScrollDirection.UP: - direction = Meta.MotionDirection.UP; - break; - case Clutter.ScrollDirection.DOWN: - direction = Meta.MotionDirection.DOWN; - break; - case Clutter.ScrollDirection.SMOOTH: - let [, dy] = Clutter.get_current_event().get_scroll_delta(); - if (dy < 0) - direction = Meta.MotionDirection.UP; - else if (dy > 0) - direction = Meta.MotionDirection.DOWN; - break; - } - - let focusedApp = tracker.focus_app; - if (!Main.overview._shown) { - let reversed = direction === Meta.MotionDirection.UP; - if (this.app == focusedApp) - this._cycleThroughWindows(reversed); - else { - // Activate the first window - let windows = this.getInterestingWindows(); - if (windows.length > 0) { - let w = windows[0]; - Main.activateWindow(w); - } - } - } - else - this.app.activate(); - return Clutter.EVENT_STOP; - } - - onWindowsChanged() { - - if (this._menu && this._menu.isOpen) - this._menu.update(); - - this._indicator.update(); - this.updateIconGeometry(); - } - - /** - * Update taraget for minimization animation - */ - updateIconGeometry() { - // If (for unknown reason) the actor is not on the stage the reported size - // and position are random values, which might exceeds the integer range - // resulting in an error when assigned to the a rect. This is a more like - // a workaround to prevent flooding the system with errors. - if (this.get_stage() == null) - return; - - let rect = new Meta.Rectangle(); - - [rect.x, rect.y] = this.get_transformed_position(); - [rect.width, rect.height] = this.get_transformed_size(); - - let windows = this.getWindows(); - if (Docking.DockManager.settings.get_boolean('multi-monitor')) { - let monitorIndex = this.monitorIndex; - windows = windows.filter(function(w) { - return w.get_monitor() == monitorIndex; - }); - } - windows.forEach(function(w) { - w.set_icon_geometry(rect); - }); - } - - _updateRunningStyle() { - // The logic originally in this function has been moved to - // AppIconIndicatorBase._updateDefaultDot(). However it cannot be removed as - // it called by the parent constructor. - } - - popupMenu() { - this._removeMenuTimeout(); - this.fake_release(); - this._draggable.fakeRelease(); - - if (!this._menu) { - this._menu = new MyAppIconMenu(this, this.remoteModel); - this._menu.connect('activate-window', (menu, window) => { - this.activateWindow(window); - }); - this._menu.connect('open-state-changed', (menu, isPoppedUp) => { - if (!isPoppedUp) - this._onMenuPoppedDown(); - else { - // Setting the max-height is s useful if part of the menu is - // scrollable so the minimum height is smaller than the natural height. - let monitor_index = Main.layoutManager.findIndexForActor(this); - let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor_index); - let position = Utils.getPosition(); - this._isHorizontal = ( position == St.Side.TOP || - position == St.Side.BOTTOM); - // If horizontal also remove the height of the dash - let fixedDock = Docking.DockManager.settings.get_boolean('dock-fixed'); - let additional_margin = this._isHorizontal && !fixedDock ? Main.overview.dash.height : 0; - let verticalMargins = this._menu.actor.margin_top + this._menu.actor.margin_bottom; - // Also set a max width to the menu, so long labels (long windows title) get truncated - this._menu.actor.style = ('max-height: ' + Math.round(workArea.height - additional_margin - verticalMargins) + 'px;' + - 'max-width: 400px'); - } - }); - let id = Main.overview.connect('hiding', () => { - this._menu.close(); - }); - this._menu.actor.connect('destroy', function() { - Main.overview.disconnect(id); - }); - - this._menuManager.addMenu(this._menu); - } - - this.emit('menu-state-changed', true); - - this.set_hover(true); - this._menu.popup(); - this._menuManager.ignoreRelease(); - this.emit('sync-tooltip'); - - return false; - } - - _onFocusAppChanged() { - this._indicator.update(); - } - - activate(button) { - let event = Clutter.get_current_event(); - let modifiers = event ? event.get_state() : 0; - let focusedApp = tracker.focus_app; - - // Only consider SHIFT and CONTROL as modifiers (exclude SUPER, CAPS-LOCK, etc.) - modifiers = modifiers & (Clutter.ModifierType.SHIFT_MASK | Clutter.ModifierType.CONTROL_MASK); - - // We don't change the CTRL-click behaviour: in such case we just chain - // up the parent method and return. - if (modifiers & Clutter.ModifierType.CONTROL_MASK) { - // Keep default behaviour: launch new window - // By calling the parent method I make it compatible - // with other extensions tweaking ctrl + click - super.activate(button); - return; - } - - // We check what type of click we have and if the modifier SHIFT is - // being used. We then define what buttonAction should be for this - // event. - let buttonAction = 0; - let settings = Docking.DockManager.settings; - if (button && button == 2 ) { - if (modifiers & Clutter.ModifierType.SHIFT_MASK) - buttonAction = settings.get_enum('shift-middle-click-action'); - else - buttonAction = settings.get_enum('middle-click-action'); - } - else if (button && button == 1) { - if (modifiers & Clutter.ModifierType.SHIFT_MASK) - buttonAction = settings.get_enum('shift-click-action'); - else - buttonAction = settings.get_enum('click-action'); - } - - // We check if the app is running, and that the # of windows is > 0 in - // case we use workspace isolation. - let windows = this.getInterestingWindows(); - let appIsRunning = (this.app.state == Shell.AppState.RUNNING || this.isLocation()) - && windows.length > 0; - - // Some action modes (e.g. MINIMIZE_OR_OVERVIEW) require overview to remain open - // This variable keeps track of this - let shouldHideOverview = true; - - // We customize the action only when the application is already running - if (appIsRunning) { - switch (buttonAction) { - case clickAction.MINIMIZE: - // In overview just activate the app, unless the acion is explicitely - // requested with a keyboard modifier - if (!Main.overview._shown || modifiers){ - // If we have button=2 or a modifier, allow minimization even if - // the app is not focused - if (this.app == focusedApp || button == 2 || modifiers & Clutter.ModifierType.SHIFT_MASK) { - // minimize all windows on double click and always in the case of primary click without - // additional modifiers - let click_count = 0; - if (Clutter.EventType.CLUTTER_BUTTON_PRESS) - click_count = event.get_click_count(); - let all_windows = (button == 1 && ! modifiers) || click_count > 1; - this._minimizeWindow(all_windows); - } - else - this._activateAllWindows(); - } - else { - let w = windows[0]; - Main.activateWindow(w); - } - break; - - case clickAction.MINIMIZE_OR_OVERVIEW: - // When a single window is present, toggle minimization - // If only one windows is present toggle minimization, but only when trigggered with the - // simple click action (no modifiers, no middle click). - if (windows.length == 1 && !modifiers && button == 1) { - let w = windows[0]; - if (this.app == focusedApp) { - // Window is raised, minimize it - this._minimizeWindow(w); - } else { - // Window is minimized, raise it - Main.activateWindow(w); - } - // Launch overview when multiple windows are present - // TODO: only show current app windows when gnome shell API will allow it - } else { - shouldHideOverview = false; - Main.overview.toggle(); - } - break; - - case clickAction.CYCLE_WINDOWS: - if (!Main.overview._shown){ - if (this.app == focusedApp) - this._cycleThroughWindows(); - else { - // Activate the first window - let w = windows[0]; - Main.activateWindow(w); - } - } - else - this.app.activate(); - break; - - case clickAction.FOCUS_OR_PREVIEWS: - if (this.app == focusedApp && - (windows.length > 1 || modifiers || button != 1)) { - this._windowPreviews(); - } else { - // Activate the first window - let w = windows[0]; - Main.activateWindow(w); - } - break; - - case clickAction.FOCUS_MINIMIZE_OR_PREVIEWS: - if (this.app == focusedApp) { - if (windows.length > 1 || modifiers || button != 1) - this._windowPreviews(); - else if (!Main.overview.visible) - this._minimizeWindow(); - } else { - // Activate the first window - let w = windows[0]; - Main.activateWindow(w); - } - break; - - case clickAction.LAUNCH: - this.launchNewWindow(); - break; - - case clickAction.PREVIEWS: - if (!Main.overview._shown) { - // If only one windows is present just switch to it, but only when trigggered with the - // simple click action (no modifiers, no middle click). - if (windows.length == 1 && !modifiers && button == 1) { - let w = windows[0]; - Main.activateWindow(w); - } else - this._windowPreviews(); - } - else { - this.app.activate(); - } - break; - - case clickAction.MINIMIZE_OR_PREVIEWS: - // When a single window is present, toggle minimization - // If only one windows is present toggle minimization, but only when trigggered with the - // simple click action (no modifiers, no middle click). - if (!Main.overview._shown){ - if (windows.length == 1 && !modifiers && button == 1) { - let w = windows[0]; - if (this.app == focusedApp) { - // Window is raised, minimize it - this._minimizeWindow(w); - } else { - // Window is minimized, raise it - Main.activateWindow(w); - } - } else { - // Launch previews when multiple windows are present - this._windowPreviews(); - } - } else { - this.app.activate(); - } - break; - - case clickAction.QUIT: - this.closeAllWindows(); - break; - - case clickAction.SKIP: - let w = windows[0]; - Main.activateWindow(w); - break; - } - } - else { - this.launchNewWindow(); - } - - // Hide overview except when action mode requires it - if(shouldHideOverview) { - Main.overview.hide(); - } - } - - shouldShowTooltip() { - return this.hover && (!this._menu || !this._menu.isOpen) && - (!this._previewMenu || !this._previewMenu.isOpen); - } - - _windowPreviews() { - if (!this._previewMenu) { - this._previewMenuManager = new PopupMenu.PopupMenuManager(this); - - this._previewMenu = new WindowPreview.WindowPreviewMenu(this); - - this._previewMenuManager.addMenu(this._previewMenu); - - this._previewMenu.connect('open-state-changed', (menu, isPoppedUp) => { - if (!isPoppedUp) - this._onMenuPoppedDown(); - }); - let id = Main.overview.connect('hiding', () => { - this._previewMenu.close(); - }); - this._previewMenu.actor.connect('destroy', function() { - Main.overview.disconnect(id); - }); - - } - - if (this._previewMenu.isOpen) - this._previewMenu.close(); - else - this._previewMenu.popup(); - - return false; - } - - // Try to do the right thing when attempting to launch a new window of an app. In - // particular, if the application doens't allow to launch a new window, activate - // the existing window instead. - launchNewWindow(p) { - let appInfo = this.app.get_app_info(); - let actions = appInfo.list_actions(); - if (this.app.can_open_new_window()) { - this.animateLaunch(); - // This is used as a workaround for a bug resulting in no new windows being opened - // for certain running applications when calling open_new_window(). - // - // https://bugzilla.gnome.org/show_bug.cgi?id=756844 - // - // Similar to what done when generating the popupMenu entries, if the application provides - // a "New Window" action, use it instead of directly requesting a new window with - // open_new_window(), which fails for certain application, notably Nautilus. - if (actions.indexOf('new-window') == -1) { - this.app.open_new_window(-1); - } - else { - let i = actions.indexOf('new-window'); - if (i !== -1) - this.app.launch_action(actions[i], global.get_current_time(), -1); - } - } - else { - // Try to manually activate the first window. Otherwise, when the app is activated by - // switching to a different workspace, a launch spinning icon is shown and disappers only - // after a timeout. - let windows = this.getWindows(); - if (windows.length > 0) - Main.activateWindow(windows[0]) - else - this.app.activate(); - } - } - - _numberOverlay() { - // Add label for a Hot-Key visual aid - this._numberOverlayLabel = new St.Label(); - this._numberOverlayBin = new St.Bin({ - child: this._numberOverlayLabel, - x_align: Clutter.ActorAlign.START, - y_align: Clutter.ActorAlign.START, - x_expand: true, y_expand: true - }); - this._numberOverlayLabel.add_style_class_name('number-overlay'); - this._numberOverlayOrder = -1; - this._numberOverlayBin.hide(); - - this._iconContainer.add_child(this._numberOverlayBin); - - } - - updateNumberOverlay() { - // We apply an overall scale factor that might come from a HiDPI monitor. - // Clutter dimensions are in physical pixels, but CSS measures are in logical - // pixels, so make sure to consider the scale. - let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; - // Set the font size to something smaller than the whole icon so it is - // still visible. The border radius is large to make the shape circular - let [minWidth, natWidth] = this._iconContainer.get_preferred_width(-1); - let font_size = Math.round(Math.max(12, 0.3*natWidth) / scaleFactor); - let size = Math.round(font_size*1.2); - this._numberOverlayLabel.set_style( - 'font-size: ' + font_size + 'px;' + - 'border-radius: ' + this.icon.iconSize + 'px;' + - 'width: ' + size + 'px; height: ' + size +'px;' - ); - } - - setNumberOverlay(number) { - this._numberOverlayOrder = number; - this._numberOverlayLabel.set_text(number.toString()); - } - - toggleNumberOverlay(activate) { - if (activate && this._numberOverlayOrder > -1) { - this.updateNumberOverlay(); - this._numberOverlayBin.show(); - } - else - this._numberOverlayBin.hide(); - } - - _minimizeWindow(param) { - // Param true make all app windows minimize - let windows = this.getInterestingWindows(); - let current_workspace = global.workspace_manager.get_active_workspace(); - for (let i = 0; i < windows.length; i++) { - let w = windows[i]; - if (w.get_workspace() == current_workspace && w.showing_on_its_workspace()) { - w.minimize(); - // Just minimize one window. By specification it should be the - // focused window on the current workspace. - if(!param) - break; - } - } - } - - // By default only non minimized windows are activated. - // This activates all windows in the current workspace. - _activateAllWindows() { - // First activate first window so workspace is switched if needed. - // We don't do this if isolation is on! - if (!Docking.DockManager.settings.get_boolean('isolate-workspaces') && - !Docking.DockManager.settings.get_boolean('isolate-monitors')) - this.app.activate(); - - // then activate all other app windows in the current workspace - let windows = this.getInterestingWindows(); - let activeWorkspace = global.workspace_manager.get_active_workspace_index(); - - if (windows.length <= 0) - return; - - let activatedWindows = 0; - - for (let i = windows.length - 1; i >= 0; i--) { - if (windows[i].get_workspace().index() == activeWorkspace) { - Main.activateWindow(windows[i]); - activatedWindows++; - } - } - } - - //This closes all windows of the app. - closeAllWindows() { - let windows = this.getInterestingWindows(); - for (let i = 0; i < windows.length; i++) - windows[i].delete(global.get_current_time()); - } - - _cycleThroughWindows(reversed) { - // Store for a little amount of time last clicked app and its windows - // since the order changes upon window interaction - let MEMORY_TIME=3000; - - let app_windows = this.getInterestingWindows(); - - if (app_windows.length <1) - return - - if (recentlyClickedAppLoopId > 0) - GLib.source_remove(recentlyClickedAppLoopId); - recentlyClickedAppLoopId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, MEMORY_TIME, this._resetRecentlyClickedApp); - - // If there isn't already a list of windows for the current app, - // or the stored list is outdated, use the current windows list. - let monitorIsolation = Docking.DockManager.settings.get_boolean('isolate-monitors'); - if (!recentlyClickedApp || - recentlyClickedApp.get_id() != this.app.get_id() || - recentlyClickedAppWindows.length != app_windows.length || - (recentlyClickedAppMonitor != this.monitorIndex && monitorIsolation)) { - recentlyClickedApp = this.app; - recentlyClickedAppWindows = app_windows; - recentlyClickedAppMonitor = this.monitorIndex; - recentlyClickedAppIndex = 0; - } - - if (reversed) { - recentlyClickedAppIndex--; - if (recentlyClickedAppIndex < 0) recentlyClickedAppIndex = recentlyClickedAppWindows.length - 1; - } else { - recentlyClickedAppIndex++; - } - let index = recentlyClickedAppIndex % recentlyClickedAppWindows.length; - let window = recentlyClickedAppWindows[index]; - - Main.activateWindow(window); - } - - _resetRecentlyClickedApp() { - if (recentlyClickedAppLoopId > 0) - GLib.source_remove(recentlyClickedAppLoopId); - recentlyClickedAppLoopId=0; - recentlyClickedApp =null; - recentlyClickedAppWindows = null; - recentlyClickedAppIndex = 0; - recentlyClickedAppMonitor = -1; - - return false; - } - - getWindows() { - return getWindows(this.app, this._location); - } - - // Filter out unnecessary windows, for instance - // nautilus desktop window. - getInterestingWindows() { - return getInterestingWindows(this.app, this.monitorIndex, this._location); - } - - // Does the Icon represent a location rather than an App - isLocation() { - return this._location != null; - } -}); -/** - * Extend AppIconMenu - * - * - set popup arrow side based on dash orientation - * - Add close windows option based on quitfromdash extension - * (https://github.com/deuill/shell-extension-quitfromdash) - * - Add open windows thumbnails instead of list - * - update menu when application windows change - */ -const MyAppIconMenu = class DashToDock_MyAppIconMenu extends AppDisplay.AppIconMenu { - - constructor(source, remoteModel) { - let side = Utils.getPosition(); - - // Damm it, there has to be a proper way of doing this... - // As I can't call the parent parent constructor (?) passing the side - // parameter, I overwite what I need later - super(source); - - // Change the initialized side where required. - this._arrowSide = side; - this._boxPointer._arrowSide = side; - this._boxPointer._userArrowSide = side; - - this._signalsHandler = new Utils.GlobalSignalsHandler(); - - if (remoteModel && DbusmenuUtils.haveDBusMenu()) { - const [onQuicklist, onDynamicSection] = Utils.splitHandler((sender, { quicklist }, dynamicSection) => { - dynamicSection.removeAll(); - if (quicklist) { - quicklist.get_children().forEach(remoteItem => - dynamicSection.addMenuItem(DbusmenuUtils.makePopupMenuItem(remoteItem, false))); - } - }); - - this._signalsHandler.add([ - remoteModel.lookupById(this._source.app.id), - 'quicklist-changed', - onQuicklist - ], [ - this, - 'dynamic-section-changed', - onDynamicSection - ]); - } - } - - destroy() { - this._signalsHandler.destroy(); - super.destroy(); - } - - _rebuildMenu() { - this.removeAll(); - - if (Docking.DockManager.settings.get_boolean('show-windows-preview')) { - // Display the app windows menu items and the separator between windows - // of the current desktop and other windows. - - this._allWindowsMenuItem = new PopupMenu.PopupSubMenuMenuItem(__('All Windows'), false); - this._allWindowsMenuItem.hide(); - this.addMenuItem(this._allWindowsMenuItem); - - if (!this._source.app.is_window_backed()) { - this._appendSeparator(); - - let appInfo = this._source.app.get_app_info(); - let actions = appInfo.list_actions(); - if (this._source.app.can_open_new_window() && - actions.indexOf('new-window') == -1) { - this._newWindowMenuItem = this._appendMenuItem(_('New Window')); - this._newWindowMenuItem.connect('activate', () => { - if (this._source.app.state == Shell.AppState.STOPPED) - this._source.animateLaunch(); - - this._source.app.open_new_window(-1); - this.emit('activate-window', null); - }); - this._appendSeparator(); - } - - - if (AppDisplay.discreteGpuAvailable && - this._source.app.state == Shell.AppState.STOPPED && - actions.indexOf('activate-discrete-gpu') == -1) { - this._onDiscreteGpuMenuItem = this._appendMenuItem(_('Launch using Dedicated Graphics Card')); - this._onDiscreteGpuMenuItem.connect('activate', () => { - if (this._source.app.state == Shell.AppState.STOPPED) - this._source.animateLaunch(); - - this._source.app.launch(0, -1, true); - this.emit('activate-window', null); - }); - } - - for (let i = 0; i < actions.length; i++) { - let action = actions[i]; - let item = this._appendMenuItem(appInfo.get_action_name(action)); - item.connect('activate', (emitter, event) => { - this._source.app.launch_action(action, event.get_time(), -1); - this.emit('activate-window', null); - }); - } - - let canFavorite = global.settings.is_writable('favorite-apps') && - !this._source.isLocation(); - - if (canFavorite) { - this._appendSeparator(); - - let isFavorite = AppFavorites.getAppFavorites().isFavorite(this._source.app.get_id()); - - if (isFavorite) { - let item = this._appendMenuItem(_('Remove from Favorites')); - item.connect('activate', () => { - let favs = AppFavorites.getAppFavorites(); - favs.removeFavorite(this._source.app.get_id()); - }); - } else { - let item = this._appendMenuItem(_('Add to Favorites')); - item.connect('activate', () => { - let favs = AppFavorites.getAppFavorites(); - favs.addFavorite(this._source.app.get_id()); - }); - } - } - - if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop') && - !this._source.isLocation()) { - this._appendSeparator(); - let item = this._appendMenuItem(_('Show Details')); - item.connect('activate', () => { - let id = this._source.app.get_id(); - let args = GLib.Variant.new('(ss)', [id, '']); - Gio.DBus.get(Gio.BusType.SESSION, null, - function(o, res) { - let bus = Gio.DBus.get_finish(res); - bus.call('org.gnome.Software', - '/org/gnome/Software', - 'org.gtk.Actions', 'Activate', - GLib.Variant.new('(sava{sv})', - ['details', [args], null]), - null, 0, -1, null, null); - Main.overview.hide(); - }); - }); - } - } - - } else { - if (super._rebuildMenu) - super._rebuildMenu(); - else - super._redisplay(); - } - - // dynamic menu - const items = this._getMenuItems(); - let i = items.length; - if (Shell.AppSystem.get_default().lookup_app('org.gnome.Software.desktop')) { - i -= 2; - } - if (global.settings.is_writable('favorite-apps')) { - i -= 2; - } - if (i < 0) { - i = 0; - } - const dynamicSection = new PopupMenu.PopupMenuSection(); - this.addMenuItem(dynamicSection, i); - this.emit('dynamic-section-changed', dynamicSection); - - // quit menu - this._appendSeparator(); - this._quitfromDashMenuItem = this._appendMenuItem(_('Quit')); - this._quitfromDashMenuItem.connect('activate', () => { - this._source.closeAllWindows(); - }); - - this.update(); - } - - // update menu content when application windows change. This is desirable as actions - // acting on windows (closing) are performed while the menu is shown. - update() { - - let windows = this._source.getInterestingWindows(); - - // update, show or hide the quit menu - if ( windows.length > 0) { - let quitFromDashMenuText = ""; - if (windows.length == 1) - this._quitfromDashMenuItem.label.set_text(_('Quit')); - else - this._quitfromDashMenuItem.label.set_text(__('Quit %d Windows').format(windows.length)); - - this._quitfromDashMenuItem.actor.show(); - - } else { - this._quitfromDashMenuItem.actor.hide(); - } - - if(Docking.DockManager.settings.get_boolean('show-windows-preview')){ - - // update, show, or hide the allWindows menu - // Check if there are new windows not already displayed. In such case, repopulate the allWindows - // menu. Windows removal is already handled by each preview being connected to the destroy signal - let old_windows = this._allWindowsMenuItem.menu._getMenuItems().map(function(item){ - return item._window; - }); - - let new_windows = windows.filter(function(w) {return old_windows.indexOf(w) < 0;}); - if (new_windows.length > 0) { - this._populateAllWindowMenu(windows); - - // Try to set the width to that of the submenu. - // TODO: can't get the actual size, getting a bit less. - // Temporary workaround: add 15px to compensate - this._allWindowsMenuItem.width = this._allWindowsMenuItem.menu.actor.width + 15; - - } - - // The menu is created hidden and never hidded after being shown. Instead, a singlal - // connected to its items destroy will set is insensitive if no more windows preview are shown. - if (windows.length > 0){ - this._allWindowsMenuItem.show(); - this._allWindowsMenuItem.setSensitive(true); - } - } - - // Update separators - this._getMenuItems().forEach(item => { - if ('label' in item) { - this._updateSeparatorVisibility(item); - } - }); - } - - _populateAllWindowMenu(windows) { - - this._allWindowsMenuItem.menu.removeAll(); - - if (windows.length > 0) { - - let activeWorkspace = global.workspace_manager.get_active_workspace(); - let separatorShown = windows[0].get_workspace() != activeWorkspace; - - for (let i = 0; i < windows.length; i++) { - let window = windows[i]; - if (!separatorShown && window.get_workspace() != activeWorkspace) { - this._allWindowsMenuItem.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); - separatorShown = true; - } - - let item = new WindowPreview.WindowPreviewMenuItem(window); - this._allWindowsMenuItem.menu.addMenuItem(item); - item.connect('activate', () => { - this.emit('activate-window', window); - }); - - // This is to achieve a more gracefull transition when the last windows is closed. - item.connect('destroy', () => { - if(this._allWindowsMenuItem.menu._getMenuItems().length == 1) // It's still counting the item just going to be destroyed - this._allWindowsMenuItem.setSensitive(false); - }); - } - } - } -}; -Signals.addSignalMethods(MyAppIconMenu.prototype); - -function getWindows(app, location) { - if (location != null && Docking.DockManager.getDefault().fm1Client) { - return Docking.DockManager.getDefault().fm1Client.getWindows(location); - } else { - return app.get_windows(); - } -} - -// Filter out unnecessary windows, for instance -// nautilus desktop window. -function getInterestingWindows(app, monitorIndex, location) { - let windows = getWindows(app, location).filter(function(w) { - return !w.skip_taskbar; - }); - - let settings = Docking.DockManager.settings; - - // When using workspace isolation, we filter out windows - // that are not in the current workspace - if (settings.get_boolean('isolate-workspaces')) - windows = windows.filter(function(w) { - return w.get_workspace().index() == global.workspace_manager.get_active_workspace_index(); - }); - - if (settings.get_boolean('isolate-monitors')) - windows = windows.filter(function(w) { - return w.get_monitor() == monitorIndex; - }); - - return windows; -} - -/** - * A ShowAppsIcon improved class. - * - * - set label position based on dash orientation (Note, I am reusing most machinery of the appIcon class) - * - implement a popupMenu based on the AppIcon code (Note, I am reusing most machinery of the appIcon class) - * - */ - -var MyShowAppsIcon = GObject.registerClass({ - Signals: { - 'menu-state-changed': { param_types: [GObject.TYPE_BOOLEAN] }, - 'sync-tooltip': {} - } -} -, class DashToDock_MyShowAppsIcon extends Dash.ShowAppsIcon { - _init() { - super._init(); - - // Re-use appIcon methods - let appIconPrototype = AppDisplay.AppIcon.prototype; - this.toggleButton.y_expand = false; - this.toggleButton.connect('popup-menu', - appIconPrototype._onKeyboardPopupMenu.bind(this)); - this.toggleButton.connect('clicked', - this._removeMenuTimeout.bind(this)); - - this.reactive = true; - this.toggleButton.popupMenu = () => this.popupMenu.call(this); - this.toggleButton._removeMenuTimeout = () => this._removeMenuTimeout.call(this); - - this._menu = null; - this._menuManager = new PopupMenu.PopupMenuManager(this); - this._menuTimeoutId = 0; - } - - vfunc_leave_event(leaveEvent) - { - return AppDisplay.AppIcon.prototype.vfunc_leave_event.call( - this.toggleButton, leaveEvent); - } - - vfunc_button_press_event(buttonPressEvent) - { - return AppDisplay.AppIcon.prototype.vfunc_button_press_event.call( - this.toggleButton, buttonPressEvent); - } - - vfunc_touch_event(touchEvent) - { - return AppDisplay.AppIcon.prototype.vfunc_touch_event.call( - this.toggleButton, touchEvent); - } - - showLabel() { - itemShowLabel.call(this); - } - - _onMenuPoppedDown() { - AppDisplay.AppIcon.prototype._onMenuPoppedDown.apply(this, arguments); - } - - _setPopupTimeout() { - AppDisplay.AppIcon.prototype._onMenuPoppedDown.apply(this, arguments); - } - - _removeMenuTimeout() { - AppDisplay.AppIcon.prototype._removeMenuTimeout.apply(this, arguments); - } - - popupMenu() { - this._removeMenuTimeout(); - this.toggleButton.fake_release(); - - if (!this._menu) { - this._menu = new MyShowAppsIconMenu(this); - this._menu.connect('open-state-changed', (menu, isPoppedUp) => { - if (!isPoppedUp) - this._onMenuPoppedDown(); - }); - let id = Main.overview.connect('hiding', () => { - this._menu.close(); - }); - this._menu.actor.connect('destroy', function() { - Main.overview.disconnect(id); - }); - this._menuManager.addMenu(this._menu); - } - - this.emit('menu-state-changed', true); - - this.toggleButton.set_hover(true); - this._menu.popup(); - this._menuManager.ignoreRelease(); - this.emit('sync-tooltip'); - - return false; - } -}); - - -/** - * A menu for the showAppsIcon - */ -var MyShowAppsIconMenu = class DashToDock_MyShowAppsIconMenu extends MyAppIconMenu { - _rebuildMenu() { - this.removeAll(); - - /* Translators: %s is "Settings", which is automatically translated. You - can also translate the full message if this fits better your language. */ - let name = __('Dash to Dock %s').format(_('Settings')) - let item = this._appendMenuItem(name); - - item.connect('activate', function () { - if (typeof ExtensionUtils.openPrefs === 'function') { - ExtensionUtils.openPrefs(); - } else { - Util.spawn(["gnome-shell-extension-prefs", Me.metadata.uuid]); - } - }); - } -}; - -/** - * This function is used for both extendShowAppsIcon and extendDashItemContainer - */ -function itemShowLabel() { - // Check if the label is still present at all. When switching workpaces, the - // item might have been destroyed in between. - if (!this._labelText || this.label.get_stage() == null) - return; - - this.label.set_text(this._labelText); - this.label.opacity = 0; - this.label.show(); - - let [stageX, stageY] = this.get_transformed_position(); - let node = this.label.get_theme_node(); - - let itemWidth = this.allocation.x2 - this.allocation.x1; - let itemHeight = this.allocation.y2 - this.allocation.y1; - - let labelWidth = this.label.get_width(); - let labelHeight = this.label.get_height(); - - let x, y, xOffset, yOffset; - - let position = Utils.getPosition(); - this._isHorizontal = ((position == St.Side.TOP) || (position == St.Side.BOTTOM)); - let labelOffset = node.get_length('-x-offset'); - - switch (position) { - case St.Side.LEFT: - yOffset = Math.floor((itemHeight - labelHeight) / 2); - y = stageY + yOffset; - xOffset = labelOffset; - x = stageX + this.get_width() + xOffset; - break; - case St.Side.RIGHT: - yOffset = Math.floor((itemHeight - labelHeight) / 2); - y = stageY + yOffset; - xOffset = labelOffset; - x = Math.round(stageX) - labelWidth - xOffset; - break; - case St.Side.TOP: - y = stageY + labelOffset + itemHeight; - xOffset = Math.floor((itemWidth - labelWidth) / 2); - x = stageX + xOffset; - break; - case St.Side.BOTTOM: - yOffset = labelOffset; - y = stageY - labelHeight - yOffset; - xOffset = Math.floor((itemWidth - labelWidth) / 2); - x = stageX + xOffset; - break; - } - - // keep the label inside the screen border - // Only needed fot the x coordinate. - - // Leave a few pixel gap - let gap = 5; - let monitor = Main.layoutManager.findMonitorForActor(this); - if (x - monitor.x < gap) - x += monitor.x - x + labelOffset; - else if (x + labelWidth > monitor.x + monitor.width - gap) - x -= x + labelWidth - (monitor.x + monitor.width) + gap; - - this.label.remove_all_transitions(); - this.label.set_position(x, y); - this.label.ease({ - opacity: 255, - duration: Dash.DASH_ITEM_LABEL_SHOW_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD - }); -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/dash.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/dash.js deleted file mode 100644 index bac49c2..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/dash.js +++ /dev/null @@ -1,1072 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Clutter = imports.gi.Clutter; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Meta = imports.gi.Meta; -const Shell = imports.gi.Shell; -const St = imports.gi.St; - -const AppDisplay = imports.ui.appDisplay; -const AppFavorites = imports.ui.appFavorites; -const Dash = imports.ui.dash; -const DND = imports.ui.dnd; -const IconGrid = imports.ui.iconGrid; -const Main = imports.ui.main; -const PopupMenu = imports.ui.popupMenu; -const Util = imports.misc.util; -const Workspace = imports.ui.workspace; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Docking = Me.imports.docking; -const Utils = Me.imports.utils; -const AppIcons = Me.imports.appIcons; -const Locations = Me.imports.locations; - -const DASH_ANIMATION_TIME = Dash.DASH_ANIMATION_TIME; -const DASH_ITEM_LABEL_HIDE_TIME = Dash.DASH_ITEM_LABEL_HIDE_TIME; -const DASH_ITEM_HOVER_TIMEOUT = Dash.DASH_ITEM_HOVER_TIMEOUT; - -/** - * Extend DashItemContainer - * - * - set label position based on dash orientation - * - */ -let MyDashItemContainer = GObject.registerClass( -class DashToDock_MyDashItemContainer extends Dash.DashItemContainer { - - showLabel() { - return AppIcons.itemShowLabel.call(this); - } -}); - -const MyDashIconsVerticalLayout = GObject.registerClass( - class DashToDock_MyDashIconsVerticalLayout extends Clutter.BoxLayout { - _init() { - super._init({ - orientation: Clutter.Orientation.VERTICAL, - }); - } - - vfunc_get_preferred_height(container, forWidth) { - const [natHeight] = super.vfunc_get_preferred_height(container, forWidth); - return [natHeight, 0]; - } -}); - - -const baseIconSizes = [16, 22, 24, 32, 48, 64, 96, 128]; - -/** - * This class is a fork of the upstream dash class (ui.dash.js) - * - * Summary of changes: - * - disconnect global signals adding a destroy method; - * - play animations even when not in overview mode - * - set a maximum icon size - * - show running and/or favorite applications - * - hide showApps label when the custom menu is shown. - * - add scrollview - * ensure actor is visible on keyfocus inseid the scrollview - * - add 128px icon size, might be usefull for hidpi display - * - sync minimization application target position. - * - keep running apps ordered. - */ -var MyDash = GObject.registerClass({ - Signals: { - 'menu-closed': {}, - 'icon-size-changed': {}, - } -}, class DashToDock_MyDash extends St.Widget { - - _init(remoteModel, monitorIndex) { - // Initialize icon variables and size - this._maxWidth = -1; - this._maxHeight = -1; - this.iconSize = Docking.DockManager.settings.get_int('dash-max-icon-size'); - this._availableIconSizes = baseIconSizes; - this._shownInitially = false; - this._initializeIconSize(this.iconSize); - - this._separator = null; - - this._remoteModel = remoteModel; - this._monitorIndex = monitorIndex; - this._position = Utils.getPosition(); - this._isHorizontal = ((this._position == St.Side.TOP) || - (this._position == St.Side.BOTTOM)); - this._signalsHandler = new Utils.GlobalSignalsHandler(); - - this._dragPlaceholder = null; - this._dragPlaceholderPos = -1; - this._animatingPlaceholdersCount = 0; - this._showLabelTimeoutId = 0; - this._resetHoverTimeoutId = 0; - this._labelShowing = false; - - super._init({ - name: 'dash', - offscreen_redirect: Clutter.OffscreenRedirect.ALWAYS, - layout_manager: new Clutter.BinLayout() - }); - - this._dashContainer = new St.BoxLayout({ - x_align: Clutter.ActorAlign.CENTER, - y_align: this._isHorizontal ? Clutter.ActorAlign.CENTER: Clutter.ActorAlign.START, - vertical: !this._isHorizontal, - y_expand: this._isHorizontal, - x_expand: !this._isHorizontal, - pack_start: Docking.DockManager.settings.get_boolean('show-apps-at-top') - }); - - this._scrollView = new St.ScrollView({ - name: 'dashtodockDashScrollview', - // TODO: Fix scrolling - hscrollbar_policy: this._isHorizontal ? St.PolicyType.EXTERNAL : St.PolicyType.NEVER, - vscrollbar_policy: this._isHorizontal ? St.PolicyType.NEVER : St.PolicyType.EXTERNAL, - x_expand: this._isHorizontal, - y_expand: !this._isHorizontal, - enable_mouse_scrolling: false - }); - - if (Docking.DockManager.settings.get_boolean('extend-height')) { - if (!this._isHorizontal) { - this._scrollView.y_align = Clutter.ActorAlign.START; - } else { - this._scrollView.x_align = Clutter.ActorAlign.START; - } - } - - this._scrollView.connect('scroll-event', this._onScrollEvent.bind(this)); - - let rtl = Clutter.get_default_text_direction() == Clutter.TextDirection.RTL; - this._box = new St.BoxLayout({ - vertical: !this._isHorizontal, - clip_to_allocation: false, - ...(!this._isHorizontal ? { layout_manager: new MyDashIconsVerticalLayout() } : {}), - x_align: rtl ? Clutter.ActorAlign.END : Clutter.ActorAlign.START, - y_align: this._isHorizontal ? Clutter.ActorAlign.CENTER: Clutter.ActorAlign.START, - y_expand: !this._isHorizontal, - x_expand: this._isHorizontal - }); - this._box._delegate = this; - this._dashContainer.add_actor(this._scrollView); - this._scrollView.add_actor(this._box); - - this._showAppsIcon = new AppIcons.MyShowAppsIcon(); - this._showAppsIcon.show(false); - this._showAppsIcon.icon.setIconSize(this.iconSize); - this._showAppsIcon.x_expand = false; - this._showAppsIcon.y_expand = false; - if (!this._isHorizontal) - this._showAppsIcon.y_align = Clutter.ActorAlign.START; - this._hookUpLabel(this._showAppsIcon); - this._showAppsIcon.connect('menu-state-changed', (_icon, opened) => { - this._itemMenuStateChanged(this._showAppsIcon, opened); - }); - - this._dashContainer.add_child(this._showAppsIcon); - - this._background = new St.Widget({ - style_class: 'dash-background', - y_expand: this._isHorizontal, - x_expand: !this._isHorizontal, - }); - - const sizerBox = new Clutter.Actor(); - sizerBox.add_constraint(new Clutter.BindConstraint({ - source: this._isHorizontal ? this._showAppsIcon.icon : this._dashContainer, - coordinate: Clutter.BindCoordinate.HEIGHT, - })); - sizerBox.add_constraint(new Clutter.BindConstraint({ - source: this._isHorizontal ? this._dashContainer : this._showAppsIcon.icon, - coordinate: Clutter.BindCoordinate.WIDTH, - })); - this._background.add_child(sizerBox); - - this.add_child(this._background); - this.add_child(this._dashContainer); - - this._workId = Main.initializeDeferredWork(this._box, this._redisplay.bind(this)); - - this._shellSettings = new Gio.Settings({ - schema_id: 'org.gnome.shell' - }); - - this._appSystem = Shell.AppSystem.get_default(); - - this.iconAnimator = new Docking.IconAnimator(this); - - this._signalsHandler.add([ - this._appSystem, - 'installed-changed', - () => { - AppFavorites.getAppFavorites().reload(); - this._queueRedisplay(); - } - ], [ - AppFavorites.getAppFavorites(), - 'changed', - this._queueRedisplay.bind(this) - ], [ - this._appSystem, - 'app-state-changed', - this._queueRedisplay.bind(this) - ], [ - Main.overview, - 'item-drag-begin', - this._onItemDragBegin.bind(this) - ], [ - Main.overview, - 'item-drag-end', - this._onItemDragEnd.bind(this) - ], [ - Main.overview, - 'item-drag-cancelled', - this._onItemDragCancelled.bind(this) - ], [ - Main.overview, - 'window-drag-begin', - this._onWindowDragBegin.bind(this) - ], [ - Main.overview, - 'window-drag-cancelled', - this._onWindowDragEnd.bind(this) - ], [ - Main.overview, - 'window-drag-end', - this._onWindowDragEnd.bind(this) - ]); - - this.connect('destroy', this._onDestroy.bind(this)); - } - - vfunc_get_preferred_height(forWidth) { - let [minHeight, natHeight] = super.vfunc_get_preferred_height.call(this, forWidth); - if (!this._isHorizontal && this._maxHeight !== -1 && natHeight > this._maxHeight) - return [minHeight, this._maxHeight] - else - return [minHeight, natHeight] - } - - vfunc_get_preferred_width(forHeight) { - let [minWidth, natWidth] = super.vfunc_get_preferred_width.call(this, forHeight); - if (this._isHorizontal && this._maxWidth !== -1 && natWidth > this._maxWidth) - return [minWidth, this._maxWidth] - else - return [minWidth, natWidth] - } - - get _container() { - return this._dashContainer; - } - - _onDestroy() { - this.iconAnimator.destroy(); - this._signalsHandler.destroy(); - } - - - _onItemDragBegin() { - return Dash.Dash.prototype._onItemDragBegin.call(this, ...arguments); - } - - _onItemDragCancelled() { - return Dash.Dash.prototype._onItemDragCancelled.call(this, ...arguments); - } - - _onItemDragEnd() { - return Dash.Dash.prototype._onItemDragEnd.call(this, ...arguments); - } - - _endItemDrag() { - return Dash.Dash.prototype._endItemDrag.call(this, ...arguments); - } - - _onItemDragMotion() { - return Dash.Dash.prototype._onItemDragMotion.call(this, ...arguments); - } - - _appIdListToHash() { - return Dash.Dash.prototype._appIdListToHash.call(this, ...arguments); - } - - _queueRedisplay() { - return Dash.Dash.prototype._queueRedisplay.call(this, ...arguments); - } - - _hookUpLabel() { - return Dash.Dash.prototype._hookUpLabel.call(this, ...arguments); - } - - _syncLabel() { - return Dash.Dash.prototype._syncLabel.call(this, ...arguments); - } - - _clearDragPlaceholder() { - return Dash.Dash.prototype._clearDragPlaceholder.call(this, ...arguments); - } - - _clearEmptyDropTarget() { - return Dash.Dash.prototype._clearEmptyDropTarget.call(this, ...arguments); - } - - handleDragOver(source, actor, x, y, time) { - let ret; - if (this._isHorizontal) { - ret = Dash.Dash.prototype.handleDragOver.call(this, source, actor, x, y, time); - - if (ret == DND.DragMotionResult.CONTINUE) - return ret; - } else { - Object.defineProperty(this._box, 'height', { - configurable: true, - get: () => this._box.get_children().reduce((a, c) => a + c.height, 0), - }); - - let replacedPlaceholderWidth = false; - if (this._dragPlaceholder) { - replacedPlaceholderWidth = true; - Object.defineProperty(this._dragPlaceholder, 'width', { - configurable: true, - get: () => this._dragPlaceholder.height, - }); - } - - ret = Dash.Dash.prototype.handleDragOver.call(this, source, actor, y, x, time); - - delete this._box.height; - if (replacedPlaceholderWidth && this._dragPlaceholder) - delete this._dragPlaceholder.width; - - if (ret == DND.DragMotionResult.CONTINUE) - return ret; - - if (this._dragPlaceholder) { - this._dragPlaceholder.child.set_width(this.iconSize / 2); - this._dragPlaceholder.child.set_height(this.iconSize); - - let pos = this._dragPlaceholderPos; - if (this._isHorizontal && (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)) - pos = this._box.get_children() - 1 - pos; - - if (pos != this._dragPlaceholderPos) { - this._dragPlaceholderPos = pos; - this._box.set_child_at_index(this._dragPlaceholder, - this._dragPlaceholderPos) - } - } - } - - if (this._dragPlaceholder) { - // Ensure the next and previous icon are visible when moving the placeholder - // (I assume there's room for both of them) - if (this._dragPlaceholderPos > 0) - ensureActorVisibleInScrollView(this._scrollView, - this._box.get_children()[this._dragPlaceholderPos - 1]); - - if (this._dragPlaceholderPos < this._box.get_children().length - 1) - ensureActorVisibleInScrollView(this._scrollView, - this._box.get_children()[this._dragPlaceholderPos + 1]); - } - - return ret; - } - - acceptDrop() { - return Dash.Dash.prototype.acceptDrop.call(this, ...arguments); - } - - _onWindowDragBegin() { - return Dash.Dash.prototype._onWindowDragBegin.call(this, ...arguments); - } - - _onWindowDragEnd() { - return Dash.Dash.prototype._onWindowDragEnd.call(this, ...arguments); - } - - _onScrollEvent(actor, event) { - // If scroll is not used because the icon is resized, let the scroll event propagate. - if (!Docking.DockManager.settings.get_boolean('icon-size-fixed')) - return Clutter.EVENT_PROPAGATE; - - // reset timeout to avid conflicts with the mousehover event - if (this._ensureAppIconVisibilityTimeoutId > 0) { - GLib.source_remove(this._ensureAppIconVisibilityTimeoutId); - this._ensureAppIconVisibilityTimeoutId = 0; - } - - // Skip to avoid double events mouse - // TODO: Horizontal events are emulated, potentially due to a conflict - // with the workspace switching gesture. - if (!this._isHorizontal && event.is_pointer_emulated()) { - return Clutter.EVENT_STOP; - } - - let adjustment, delta = 0; - - if (this._isHorizontal) - adjustment = this._scrollView.get_hscroll_bar().get_adjustment(); - else - adjustment = this._scrollView.get_vscroll_bar().get_adjustment(); - - let increment = adjustment.step_increment; - - if (this._isHorizontal) { - switch (event.get_scroll_direction()) { - case Clutter.ScrollDirection.LEFT: - delta = -increment; - break; - case Clutter.ScrollDirection.RIGHT: - delta = +increment; - break; - case Clutter.ScrollDirection.SMOOTH: - let [dx, dy] = event.get_scroll_delta(); - // TODO: Handle y - //delta = dy * increment; - // Also consider horizontal component, for instance touchpad - delta = dx * increment; - break; - } - } else { - switch (event.get_scroll_direction()) { - case Clutter.ScrollDirection.UP: - delta = -increment; - break; - case Clutter.ScrollDirection.DOWN: - delta = +increment; - break; - case Clutter.ScrollDirection.SMOOTH: - let [, dy] = event.get_scroll_delta(); - delta = dy * increment; - break; - } - } - - const value = adjustment.get_value(); - - // TODO: Remove this if possible. - if (Number.isNaN(value)) { - adjustment.set_value(delta); - } else { - adjustment.set_value(value + delta); - } - - return Clutter.EVENT_STOP; - } - - _createAppItem(app) { - let appIcon = new AppIcons.MyAppIcon(this._remoteModel, app, - this._monitorIndex, this.iconAnimator); - - if (appIcon._draggable) { - appIcon._draggable.connect('drag-begin', () => { - appIcon.opacity = 50; - }); - appIcon._draggable.connect('drag-end', () => { - appIcon.opacity = 255; - }); - } - - appIcon.connect('menu-state-changed', (appIcon, opened) => { - this._itemMenuStateChanged(item, opened); - }); - - let item = new MyDashItemContainer(); - item.setChild(appIcon); - - appIcon.connect('notify::hover', () => { - if (appIcon.hover) { - this._ensureAppIconVisibilityTimeoutId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, 100, () => { - ensureActorVisibleInScrollView(this._scrollView, appIcon); - this._ensureAppIconVisibilityTimeoutId = 0; - return GLib.SOURCE_REMOVE; - }); - } - else { - if (this._ensureAppIconVisibilityTimeoutId > 0) { - GLib.source_remove(this._ensureAppIconVisibilityTimeoutId); - this._ensureAppIconVisibilityTimeoutId = 0; - } - } - }); - - appIcon.connect('clicked', (actor) => { - ensureActorVisibleInScrollView(this._scrollView, actor); - }); - - appIcon.connect('key-focus-in', (actor) => { - let [x_shift, y_shift] = ensureActorVisibleInScrollView(this._scrollView, actor); - - // This signal is triggered also by mouse click. The popup menu is opened at the original - // coordinates. Thus correct for the shift which is going to be applied to the scrollview. - if (appIcon._menu) { - appIcon._menu._boxPointer.xOffset = -x_shift; - appIcon._menu._boxPointer.yOffset = -y_shift; - } - }); - - // Override default AppIcon label_actor, now the - // accessible_name is set at DashItemContainer.setLabelText - appIcon.label_actor = null; - item.setLabelText(app.get_name()); - - appIcon.icon.setIconSize(this.iconSize); - this._hookUpLabel(item, appIcon); - - return item; - } - - /** - * Return an array with the "proper" appIcons currently in the dash - */ - getAppIcons() { - // Only consider children which are "proper" - // icons (i.e. ignoring drag placeholders) and which are not - // animating out (which means they will be destroyed at the end of - // the animation) - let iconChildren = this._box.get_children().filter(function(actor) { - return actor.child && - !!actor.child.icon && - !actor.animatingOut; - }); - - let appIcons = iconChildren.map(function(actor) { - return actor.child; - }); - - return appIcons; - } - - _updateAppsIconGeometry() { - let appIcons = this.getAppIcons(); - appIcons.forEach(function(icon) { - icon.updateIconGeometry(); - }); - } - - _itemMenuStateChanged(item, opened) { - Dash.Dash.prototype._itemMenuStateChanged.call(this, item, opened); - - if (!opened) { - // I want to listen from outside when a menu is closed. I used to - // add a custom signal to the appIcon, since gnome 3.8 the signal - // calling this callback was added upstream. - this.emit('menu-closed'); - } - } - - _adjustIconSize() { - // For the icon size, we only consider children which are "proper" - // icons (i.e. ignoring drag placeholders) and which are not - // animating out (which means they will be destroyed at the end of - // the animation) - let iconChildren = this._box.get_children().filter(actor => { - return actor.child && - actor.child._delegate && - actor.child._delegate.icon && - !actor.animatingOut; - }); - - iconChildren.push(this._showAppsIcon); - - if (this._maxWidth === -1 && this._maxHeight === -1) - return; - - // Check if the container is present in the stage. This avoids critical - // errors when unlocking the screen - if (!this._container.get_stage()) - return; - - const themeNode = this.get_theme_node(); - const maxAllocation = new Clutter.ActorBox({ - x1: 0, - y1: 0, - x2: this._isHorizontal ? this._maxWidth : 42 /* whatever */, - y2: this._isHorizontal ? 42 : this._maxHeight - }); - let maxContent = themeNode.get_content_box(maxAllocation); - let availWidth; - if (this._isHorizontal) - availWidth = maxContent.x2 - maxContent.x1; - else - availWidth = maxContent.y2 - maxContent.y1; - let spacing = themeNode.get_length('spacing'); - - let firstButton = iconChildren[0].child; - let firstIcon = firstButton._delegate.icon; - - // Enforce valid spacings during the size request - firstIcon.icon.ensure_style(); - const [, , iconWidth, iconHeight] = firstIcon.icon.get_preferred_size(); - const [, , buttonWidth, buttonHeight] = firstButton.get_preferred_size(); - - // Subtract icon padding and box spacing from the available height - if (this._isHorizontal) - // Subtract icon padding and box spacing from the available width - availWidth -= iconChildren.length * (buttonWidth - iconWidth) + - (iconChildren.length - 1) * spacing; - else - availWidth -= iconChildren.length * (buttonHeight - iconHeight) + - (iconChildren.length - 1) * spacing; - - // let availHeight = this._maxHeight; - // availHeight -= this._background.get_theme_node().get_vertical_padding(); - // availHeight -= themeNode.get_vertical_padding(); - // availHeight -= buttonHeight - iconHeight; - - const maxIconSize = // TODO: Math.min( - availWidth / iconChildren.length // ); , availHeight); - let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; - let iconSizes = this._availableIconSizes.map(s => s * scaleFactor); - - let newIconSize = this._availableIconSizes[0]; - for (let i = 0; i < iconSizes.length; i++) { - if (iconSizes[i] <= maxIconSize) - newIconSize = this._availableIconSizes[i]; - } - - if (newIconSize == this.iconSize) - return; - - let oldIconSize = this.iconSize; - this.iconSize = newIconSize; - this.emit('icon-size-changed'); - - let scale = oldIconSize / newIconSize; - for (let i = 0; i < iconChildren.length; i++) { - let icon = iconChildren[i].child._delegate.icon; - - // Set the new size immediately, to keep the icons' sizes - // in sync with this.iconSize - icon.setIconSize(this.iconSize); - - // Don't animate the icon size change when the overview - // is transitioning, not visible or when initially filling - // the dash - if (!Main.overview.visible || Main.overview.animationInProgress || - !this._shownInitially) - continue; - - let [targetWidth, targetHeight] = icon.icon.get_size(); - - // Scale the icon's texture to the previous size and - // tween to the new size - icon.icon.set_size(icon.icon.width * scale, - icon.icon.height * scale); - - icon.icon.ease({ - width: targetWidth, - height: targetHeight, - duration: DASH_ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - }); - } - - if (this._separator) { - if (this._isHorizontal) { - this._separator.ease({ - height: this.iconSize, - duration: DASH_ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - }); - } else { - this._separator.ease({ - width: this.iconSize, - duration: DASH_ANIMATION_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - }); - } - } - } - - _redisplay() { - let favorites = AppFavorites.getAppFavorites().getFavoriteMap(); - - let running = this._appSystem.get_running(); - let settings = Docking.DockManager.settings; - - if (settings.get_boolean('isolate-workspaces') || - settings.get_boolean('isolate-monitors')) { - // When using isolation, we filter out apps that have no windows in - // the current workspace - let monitorIndex = this._monitorIndex; - running = running.filter(function(_app) { - return AppIcons.getInterestingWindows(_app, monitorIndex).length != 0; - }); - } - - let children = this._box.get_children().filter(actor => { - return actor.child && - actor.child._delegate && - actor.child._delegate.app; - }); - // Apps currently in the dash - let oldApps = children.map(actor => actor.child._delegate.app); - // Apps supposed to be in the dash - let newApps = []; - - if (settings.get_boolean('show-favorites')) { - for (let id in favorites) - newApps.push(favorites[id]); - } - - if (settings.get_boolean('show-running')) { - for (let i = 0; i < running.length; i++) { - let app = running[i]; - if (settings.get_boolean('show-favorites') && app.get_id() in favorites) - continue; - newApps.push(app); - } - } - - if (settings.get_boolean('show-mounts')) { - if (!this._removables) { - this._removables = new Locations.Removables(); - this._signalsHandler.addWithLabel('show-mounts', - [ this._removables, - 'changed', - this._queueRedisplay.bind(this) ]); - } - Array.prototype.push.apply(newApps, this._removables.getApps()); - } else if (this._removables) { - this._signalsHandler.removeWithLabel('show-mounts'); - this._removables.destroy(); - this._removables = null; - } - - if (settings.get_boolean('show-trash')) { - if (!this._trash) { - this._trash = new Locations.Trash(); - this._signalsHandler.addWithLabel('show-trash', - [ this._trash, - 'changed', - this._queueRedisplay.bind(this) ]); - } - newApps.push(this._trash.getApp()); - } else if (this._trash) { - this._signalsHandler.removeWithLabel('show-trash'); - this._trash.destroy(); - this._trash = null; - } - - // Figure out the actual changes to the list of items; we iterate - // over both the list of items currently in the dash and the list - // of items expected there, and collect additions and removals. - // Moves are both an addition and a removal, where the order of - // the operations depends on whether we encounter the position - // where the item has been added first or the one from where it - // was removed. - // There is an assumption that only one item is moved at a given - // time; when moving several items at once, everything will still - // end up at the right position, but there might be additional - // additions/removals (e.g. it might remove all the launchers - // and add them back in the new order even if a smaller set of - // additions and removals is possible). - // If above assumptions turns out to be a problem, we might need - // to use a more sophisticated algorithm, e.g. Longest Common - // Subsequence as used by diff. - - let addedItems = []; - let removedActors = []; - - let newIndex = 0; - let oldIndex = 0; - while (newIndex < newApps.length || oldIndex < oldApps.length) { - let oldApp = oldApps.length > oldIndex ? oldApps[oldIndex] : null; - let newApp = newApps.length > newIndex ? newApps[newIndex] : null; - - // No change at oldIndex/newIndex - if (oldApp == newApp) { - oldIndex++; - newIndex++; - continue; - } - - // App removed at oldIndex - if (oldApp && !newApps.includes(oldApp)) { - removedActors.push(children[oldIndex]); - oldIndex++; - continue; - } - - // App added at newIndex - if (newApp && !oldApps.includes(newApp)) { - addedItems.push({ app: newApp, - item: this._createAppItem(newApp), - pos: newIndex }); - newIndex++; - continue; - } - - // App moved - let nextApp = newApps.length > newIndex + 1 - ? newApps[newIndex + 1] : null; - let insertHere = nextApp && nextApp == oldApp; - let alreadyRemoved = removedActors.reduce((result, actor) => { - let removedApp = actor.child._delegate.app; - return result || removedApp == newApp; - }, false); - - if (insertHere || alreadyRemoved) { - let newItem = this._createAppItem(newApp); - addedItems.push({ app: newApp, - item: newItem, - pos: newIndex + removedActors.length }); - newIndex++; - } else { - removedActors.push(children[oldIndex]); - oldIndex++; - } - } - - for (let i = 0; i < addedItems.length; i++) { - this._box.insert_child_at_index(addedItems[i].item, - addedItems[i].pos); - } - - for (let i = 0; i < removedActors.length; i++) { - let item = removedActors[i]; - - // Don't animate item removal when the overview is transitioning - // or hidden - if (!Main.overview.animationInProgress) - item.animateOutAndDestroy(); - else - item.destroy(); - } - - this._adjustIconSize(); - - // Skip animations on first run when adding the initial set - // of items, to avoid all items zooming in at once - - let animate = this._shownInitially && - !Main.overview.animationInProgress; - - if (!this._shownInitially) - this._shownInitially = true; - - for (let i = 0; i < addedItems.length; i++) - addedItems[i].item.show(animate); - - // Update separator - const nFavorites = Object.keys(favorites).length; - const nIcons = children.length + addedItems.length - removedActors.length; - if (nFavorites > 0 && nFavorites < nIcons) { - if (!this._separator) { - if (!this._isHorizontal) { - this._separator = new St.Widget({ - style_class: 'vertical-dash-separator', - x_align: Clutter.ActorAlign.CENTER, - width: this.iconSize, - }); - } else { - this._separator = new St.Widget({ - style_class: 'dash-separator', - y_align: Clutter.ActorAlign.CENTER, - height: this.iconSize, - }); - } - - this._box.add_child(this._separator); - } - let pos = nFavorites; - if (this._dragPlaceholder) - pos++; - this._box.set_child_at_index(this._separator, pos); - } else if (this._separator) { - this._separator.destroy(); - this._separator = null; - } - - // Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744 - // Without it, StBoxLayout may use a stale size cache - this._box.queue_relayout(); - // TODO - // This is required for icon reordering when the scrollview is used. - this._updateAppsIconGeometry(); - - // This will update the size, and the corresponding number for each icon - this._updateNumberOverlay(); - } - - _updateNumberOverlay() { - let appIcons = this.getAppIcons(); - let counter = 1; - appIcons.forEach(function(icon) { - if (counter < 10){ - icon.setNumberOverlay(counter); - counter++; - } else if (counter == 10) { - icon.setNumberOverlay(0); - counter++; - } else { - // No overlay after 10 - icon.setNumberOverlay(-1); - } - icon.updateNumberOverlay(); - }); - - } - - toggleNumberOverlay(activate) { - let appIcons = this.getAppIcons(); - appIcons.forEach(function(icon) { - icon.toggleNumberOverlay(activate); - }); - } - - _initializeIconSize(max_size) { - let max_allowed = baseIconSizes[baseIconSizes.length-1]; - max_size = Math.min(max_size, max_allowed); - - if (Docking.DockManager.settings.get_boolean('icon-size-fixed')) - this._availableIconSizes = [max_size]; - else { - this._availableIconSizes = baseIconSizes.filter(function(val) { - return (val vvalue + vpageSize - voffset) - vvalue = Math.min(vupper -vpageSize, y2 + voffset - vpageSize); - - if (x1 < hvalue + hoffset) - hvalue = Math.max(0, x1 - hoffset); - else if (hvalue < hupper - hpageSize && x2 > hvalue + hpageSize - hoffset) - hvalue = Math.min(hupper - hpageSize, x2 + hoffset - hpageSize); - - if (vvalue !== vvalue0) { - vadjustment.ease(vvalue, { - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - duration: Util.SCROLL_TIME - }); - } - - if (hvalue !== hvalue0) { - hadjustment.ease(hvalue, { - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - duration: Util.SCROLL_TIME - }); - } - - return [hvalue- hvalue0, vvalue - vvalue0]; -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/dbusmenuUtils.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/dbusmenuUtils.js deleted file mode 100644 index 0d2793d..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/dbusmenuUtils.js +++ /dev/null @@ -1,274 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Atk = imports.gi.Atk; -const Clutter = imports.gi.Clutter; -let Dbusmenu = null; /* Dynamically imported */ -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const St = imports.gi.St; - -const PopupMenu = imports.ui.popupMenu; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Utils = Me.imports.utils; - -// Dbusmenu features not (yet) supported: -// -// * The CHILD_DISPLAY property -// -// This seems to have only one possible value in the Dbusmenu API, so -// there's little point in depending on it--the code in libdbusmenu sets it -// if and only if an item has children, so for our purposes it's simpler -// and more intuitive to just check children.length. (This does ignore the -// possibility of a program not using libdbusmenu and setting CHILD_DISPLAY -// independently, perhaps to indicate that an childless menu item should -// nevertheless be displayed like a submenu.) -// -// * Children more than two levels deep -// -// PopupMenu doesn't seem to support submenus in submenus. -// -// * Shortcut keys -// -// If these keys are supposed to be installed as global shortcuts, we'd -// have to query these aggressively and not wait for the DBus menu to be -// mapped to a popup menu. A shortcut key that only works once the popup -// menu is open and has key focus is possibly of marginal value. - -function haveDBusMenu() { - if (Dbusmenu) - return Dbusmenu; - - try { - Dbusmenu = imports.gi.Dbusmenu; - return Dbusmenu; - } catch (e) { - log(`Failed to import DBusMenu, quicklists are not avaialble: ${e}`); - return null; - } -} - - -function makePopupMenuItem(dbusmenuItem, deep) { - // These are the only properties guaranteed to be available when the root - // item is first announced. Other properties might be loaded already, but - // be sure to connect to Dbusmenu.MENUITEM_SIGNAL_PROPERTY_CHANGED to get - // the most up-to-date values in case they aren't. - const itemType = dbusmenuItem.property_get(Dbusmenu.MENUITEM_PROP_TYPE); - const label = dbusmenuItem.property_get(Dbusmenu.MENUITEM_PROP_LABEL); - const visible = dbusmenuItem.property_get_bool(Dbusmenu.MENUITEM_PROP_VISIBLE); - const enabled = dbusmenuItem.property_get_bool(Dbusmenu.MENUITEM_PROP_ENABLED); - const accessibleDesc = dbusmenuItem.property_get(Dbusmenu.MENUITEM_PROP_ACCESSIBLE_DESC); - //const childDisplay = dbusmenuItem.property_get(Dbusmenu.MENUITEM_PROP_CHILD_DISPLAY); - - let item; - const signalsHandler = new Utils.GlobalSignalsHandler(); - const wantIcon = itemType === Dbusmenu.CLIENT_TYPES_IMAGE; - - // If the basic type of the menu item needs to change, call this. - const recreateItem = () => { - const newItem = makePopupMenuItem(dbusmenuItem, deep); - const parentMenu = item._parent; - parentMenu.addMenuItem(newItem); - // Reminder: Clutter thinks of later entries in the child list as - // "above" earlier ones, so "above" here means "below" in terms of the - // menu's vertical order. - parentMenu.actor.set_child_above_sibling(newItem.actor, item.actor); - if (newItem.menu) { - parentMenu.actor.set_child_above_sibling(newItem.menu.actor, newItem.actor); - } - parentMenu.actor.remove_child(item.actor); - item.destroy(); - item = null; - }; - - const updateDisposition = () => { - const disposition = dbusmenuItem.property_get(Dbusmenu.MENUITEM_PROP_DISPOSITION); - let icon_name = null; - switch (disposition) { - case Dbusmenu.MENUITEM_DISPOSITION_ALERT: - case Dbusmenu.MENUITEM_DISPOSITION_WARNING: - icon_name = 'dialog-warning-symbolic'; - break; - case Dbusmenu.MENUITEM_DISPOSITION_INFORMATIVE: - icon_name = 'dialog-information-symbolic'; - break; - } - if (icon_name) { - item._dispositionIcon = new St.Icon({ - icon_name, - style_class: 'popup-menu-icon', - y_align: Clutter.ActorAlign.CENTER, - y_expand: true, - }); - let expander; - for (let child = item.label.get_next_sibling();; child = child.get_next_sibling()) { - if (!child) { - expander = new St.Bin({ - style_class: 'popup-menu-item-expander', - x_expand: true, - }); - item.actor.add_child(expander); - break; - } else if (child instanceof St.Widget && child.has_style_class_name('popup-menu-item-expander')) { - expander = child; - break; - } - } - item.actor.insert_child_above(item._dispositionIcon, expander); - } else if (item._dispositionIcon) { - item.actor.remove_child(item._dispositionIcon); - item._dispositionIcon = null; - } - }; - - const updateIcon = () => { - if (!wantIcon) { - return; - } - const iconData = dbusmenuItem.property_get_byte_array(Dbusmenu.MENUITEM_PROP_ICON_DATA); - const iconName = dbusmenuItem.property_get(Dbusmenu.MENUITEM_PROP_ICON_NAME); - if (iconName) { - item.icon.icon_name = iconName; - } else if (iconData.length) { - item.icon.gicon = Gio.BytesIcon.new(iconData); - } - }; - - const updateOrnament = () => { - const toggleType = dbusmenuItem.property_get(Dbusmenu.MENUITEM_PROP_TOGGLE_TYPE); - switch (toggleType) { - case Dbusmenu.MENUITEM_TOGGLE_CHECK: - item.actor.accessible_role = Atk.Role.CHECK_MENU_ITEM; - break; - case Dbusmenu.MENUITEM_TOGGLE_RADIO: - item.actor.accessible_role = Atk.Role.RADIO_MENU_ITEM; - break; - default: - item.actor.accessible_role = Atk.Role.MENU_ITEM; - } - let ornament = PopupMenu.Ornament.NONE; - const state = dbusmenuItem.property_get_int(Dbusmenu.MENUITEM_PROP_TOGGLE_STATE); - if (state === Dbusmenu.MENUITEM_TOGGLE_STATE_UNKNOWN) { - // PopupMenu doesn't natively support an "unknown" ornament, but we - // can hack one in: - item.setOrnament(ornament); - item.actor.add_accessible_state(Atk.StateType.INDETERMINATE); - item._ornamentLabel.text = '\u2501'; - item.actor.remove_style_pseudo_class('checked'); - } else { - item.actor.remove_accessible_state(Atk.StateType.INDETERMINATE); - if (state === Dbusmenu.MENUITEM_TOGGLE_STATE_CHECKED) { - if (toggleType === Dbusmenu.MENUITEM_TOGGLE_CHECK) { - ornament = PopupMenu.Ornament.CHECK; - } else if (toggleType === Dbusmenu.MENUITEM_TOGGLE_RADIO) { - ornament = PopupMenu.Ornament.DOT; - } - item.actor.add_style_pseudo_class('checked'); - } else { - item.actor.remove_style_pseudo_class('checked'); - } - item.setOrnament(ornament); - } - }; - - const onPropertyChanged = (dbusmenuItem, name, value) => { - // `value` is null when a property is cleared, so handle those cases - // with sensible defaults. - switch (name) { - case Dbusmenu.MENUITEM_PROP_TYPE: - recreateItem(); - break; - case Dbusmenu.MENUITEM_PROP_ENABLED: - item.setSensitive(value ? value.unpack() : false); - break; - case Dbusmenu.MENUITEM_PROP_LABEL: - item.label.text = value ? value.unpack() : ''; - break; - case Dbusmenu.MENUITEM_PROP_VISIBLE: - item.actor.visible = value ? value.unpack() : false; - break; - case Dbusmenu.MENUITEM_PROP_DISPOSITION: - updateDisposition(); - break; - case Dbusmenu.MENUITEM_PROP_ACCESSIBLE_DESC: - item.actor.get_accessible().accessible_description = value && value.unpack() || ''; - break; - case Dbusmenu.MENUITEM_PROP_ICON_DATA: - case Dbusmenu.MENUITEM_PROP_ICON_NAME: - updateIcon(); - break; - case Dbusmenu.MENUITEM_PROP_TOGGLE_TYPE: - case Dbusmenu.MENUITEM_PROP_TOGGLE_STATE: - updateOrnament(); - break; - } - }; - - - // Start actually building the menu item. - const children = dbusmenuItem.get_children(); - if (children.length && !deep) { - // Make a submenu. - item = new PopupMenu.PopupSubMenuMenuItem(label, wantIcon); - const updateChildren = () => { - const children = dbusmenuItem.get_children(); - if (!children.length) { - return recreateItem(); - } - item.menu.removeAll(); - children.forEach(remoteChild => - item.menu.addMenuItem(makePopupMenuItem(remoteChild, true))); - }; - updateChildren(); - signalsHandler.add( - [dbusmenuItem, Dbusmenu.MENUITEM_SIGNAL_CHILD_ADDED, updateChildren], - [dbusmenuItem, Dbusmenu.MENUITEM_SIGNAL_CHILD_MOVED, updateChildren], - [dbusmenuItem, Dbusmenu.MENUITEM_SIGNAL_CHILD_REMOVED, updateChildren]); - - } else { - // Don't make a submenu. - if (!deep) { - // We only have the potential to get a submenu if we aren't deep. - signalsHandler.add( - [dbusmenuItem, Dbusmenu.MENUITEM_SIGNAL_CHILD_ADDED, recreateItem], - [dbusmenuItem, Dbusmenu.MENUITEM_SIGNAL_CHILD_MOVED, recreateItem], - [dbusmenuItem, Dbusmenu.MENUITEM_SIGNAL_CHILD_REMOVED, recreateItem]); - } - - if (itemType === Dbusmenu.CLIENT_TYPES_SEPARATOR) { - item = new PopupMenu.PopupSeparatorMenuItem(); - } else if (wantIcon) { - item = new PopupMenu.PopupImageMenuItem(label, null); - item.icon = item._icon; - } else { - item = new PopupMenu.PopupMenuItem(label); - } - } - - // Set common initial properties. - item.actor.visible = visible; - item.setSensitive(enabled); - if (accessibleDesc) { - item.actor.get_accessible().accessible_description = accessibleDesc; - } - updateDisposition(); - updateIcon(); - updateOrnament(); - - // Prevent an initial resize flicker. - if (wantIcon) { - item.icon.icon_size = 16; - } - - signalsHandler.add([dbusmenuItem, Dbusmenu.MENUITEM_SIGNAL_PROPERTY_CHANGED, onPropertyChanged]); - - // Connections on item will be lost when item is disposed; there's no need - // to add them to signalsHandler. - item.connect('activate', () => { - dbusmenuItem.handle_event(Dbusmenu.MENUITEM_EVENT_ACTIVATED, new GLib.Variant('i', 0), Math.floor(Date.now()/1000)); - }); - item.connect('destroy', () => signalsHandler.destroy()); - - return item; -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/docking.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/docking.js deleted file mode 100644 index daa9de5..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/docking.js +++ /dev/null @@ -1,1967 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Clutter = imports.gi.Clutter; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Meta = imports.gi.Meta; -const Shell = imports.gi.Shell; -const St = imports.gi.St; -const Params = imports.misc.params; - -const Main = imports.ui.main; -const Dash = imports.ui.dash; -const IconGrid = imports.ui.iconGrid; -const Overview = imports.ui.overview; -const OverviewControls = imports.ui.overviewControls; -const PointerWatcher = imports.ui.pointerWatcher; -const Signals = imports.signals; -const SearchController = imports.ui.searchController; -const WorkspaceSwitcherPopup= imports.ui.workspaceSwitcherPopup; -const Layout = imports.ui.layout; -const LayoutManager = imports.ui.main.layoutManager; - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Utils = Me.imports.utils; -const Intellihide = Me.imports.intellihide; -const Theming = Me.imports.theming; -const MyDash = Me.imports.dash; -const LauncherAPI = Me.imports.launcherAPI; -const FileManager1API = Me.imports.fileManager1API; - -const DOCK_DWELL_CHECK_INTERVAL = 100; - -var State = { - HIDDEN: 0, - SHOWING: 1, - SHOWN: 2, - HIDING: 3 -}; - -const scrollAction = { - DO_NOTHING: 0, - CYCLE_WINDOWS: 1, - SWITCH_WORKSPACE: 2 -}; - -/** - * Ported from GNOME Shell 3.38 - * - * In GNOME Shell 40+ the dash is always visible, - * we need to re-include a spacer because our dash - * is not always visible. - */ -var DashSpacer = GObject.registerClass( - class DashSpacer extends Clutter.Actor { - _init(source) { - super._init(); - - this._bindConstraint = new Clutter.BindConstraint({ - source, - coordinate: Clutter.BindCoordinate.SIZE, - }); - this.add_constraint(this._bindConstraint); - } - - setMaxSize(size) { - // Handles overview controls trying to set the dash' max size. - } - - vfunc_get_preferred_width(forHeight) { - if (this._bindConstraint) - return this._bindConstraint.source.get_preferred_width(forHeight); - return super.vfunc_get_preferred_width(forHeight); - } - - vfunc_get_preferred_height(forWidth) { - if (this._bindConstraint) - return this._bindConstraint.source.get_preferred_height(forWidth); - return super.vfunc_get_preferred_height(forWidth); - } - } -); - - -/** - * A simple St.Widget with one child whose allocation takes into account the - * slide out of its child via the _slidex parameter ([0:1]). - * - * Required since I want to track the input region of this container which is - * based on its allocation even if the child overlows the parent actor. By doing - * this the region of the dash that is slideout is not steling anymore the input - * regions making the extesion usable when the primary monitor is the right one. - * - * The slidex parameter can be used to directly animate the sliding. The parent - * must have a WEST (SOUTH) anchor_point to achieve the sliding to the RIGHT (BOTTOM) - * side. -*/ -var DashSlideContainer = GObject.registerClass({ - Properties: { - 'side': GObject.ParamSpec.enum( - 'side', 'side', 'side', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - St.Side, St.Side.LEFT), - 'slidex': GObject.ParamSpec.double( - 'slidex', 'slidex', 'slidex', - GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, - 0, 1, 1), - } -}, class DashToDock_DashSlideContainer extends St.Bin { - - _init(params = {}) { - super._init(params); - - // slide parameter: 1 = visible, 0 = hidden. - this._slidex = params.slidex || 1; - this._slideoutSize = 0; // minimum size when slided out - } - - vfunc_allocate(box, flags) { - let contentBox = this.get_theme_node().get_content_box(box); - - this.set_allocation(box); - - if (this.child == null) - return; - - let availWidth = contentBox.x2 - contentBox.x1; - let availHeight = contentBox.y2 - contentBox.y1; - let [, , natChildWidth, natChildHeight] = - this.child.get_preferred_size(); - - let childWidth = natChildWidth; - let childHeight = natChildHeight; - - let childBox = new Clutter.ActorBox(); - - let slideoutSize = this._slideoutSize; - - if (this.side == St.Side.LEFT) { - childBox.x1 = (this._slidex -1) * (childWidth - slideoutSize); - childBox.x2 = slideoutSize + this._slidex*(childWidth - slideoutSize); - childBox.y1 = 0; - childBox.y2 = childBox.y1 + childHeight; - } - else if ((this.side == St.Side.RIGHT) || (this.side == St.Side.BOTTOM)) { - childBox.x1 = 0; - childBox.x2 = childWidth; - childBox.y1 = 0; - childBox.y2 = childBox.y1 + childHeight; - } - else if (this.side == St.Side.TOP) { - childBox.x1 = 0; - childBox.x2 = childWidth; - childBox.y1 = (this._slidex -1) * (childHeight - slideoutSize); - childBox.y2 = slideoutSize + this._slidex * (childHeight - slideoutSize); - } - - this.child.allocate(childBox); - - this.child.set_clip(-childBox.x1, -childBox.y1, - -childBox.x1+availWidth, -childBox.y1 + availHeight); - } - - /** - * Just the child width but taking into account the slided out part - */ - vfunc_get_preferred_width(forHeight) { - let [minWidth, natWidth] = super.vfunc_get_preferred_width(forHeight); - if ((this.side == St.Side.LEFT) || (this.side == St.Side.RIGHT)) { - minWidth = (minWidth - this._slideoutSize) * this._slidex + this._slideoutSize; - natWidth = (natWidth - this._slideoutSize) * this._slidex + this._slideoutSize; - } - return [minWidth, natWidth]; - } - - /** - * Just the child height but taking into account the slided out part - */ - vfunc_get_preferred_height(forWidth) { - let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth); - if ((this.side == St.Side.TOP) || (this.side == St.Side.BOTTOM)) { - minHeight = (minHeight - this._slideoutSize) * this._slidex + this._slideoutSize; - natHeight = (natHeight - this._slideoutSize) * this._slidex + this._slideoutSize; - } - return [minHeight, natHeight]; - } - - set slidex(value) { - if (value == this._slidex) - return; - - this._slidex = value; - this.notify('slidex'); - - this.queue_relayout(); - } - - get slidex() { - return this._slidex; - } -}); - -var DockedDash = GObject.registerClass({ - Signals: { - 'showing': {}, - 'hiding': {}, - } -}, class DashToDock extends St.Bin { - - _init(remoteModel, monitorIndex) { - this._rtl = (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL); - - // Load settings - let settings = DockManager.settings; - this._remoteModel = remoteModel; - this._monitorIndex = monitorIndex; - // Connect global signals - this._signalsHandler = new Utils.GlobalSignalsHandler(); - - this._bindSettingsChanges(); - - this._position = Utils.getPosition(); - this._isHorizontal = ((this._position == St.Side.TOP) || (this._position == St.Side.BOTTOM)); - - // Temporary ignore hover events linked to autohide for whatever reason - this._ignoreHover = false; - this._oldignoreHover = null; - // This variables are linked to the settings regardles of autohide or intellihide - // being temporary disable. Get set by _updateVisibilityMode; - this._autohideIsEnabled = null; - this._intellihideIsEnabled = null; - this._fixedIsEnabled = null; - - // Create intellihide object to monitor windows overlapping - this._intellihide = new Intellihide.Intellihide(this._monitorIndex); - - // initialize dock state - this._dockState = State.HIDDEN; - - // Put dock on the required monitor - this._monitor = Main.layoutManager.monitors[this._monitorIndex]; - - // this store size and the position where the dash is shown; - // used by intellihide module to check window overlap. - this.staticBox = new Clutter.ActorBox(); - - // Initialize pressure barrier variables - this._canUsePressure = false; - this._pressureBarrier = null; - this._barrier = null; - this._removeBarrierTimeoutId = 0; - - // Initialize dwelling system variables - this._dockDwelling = false; - this._dockWatch = null; - this._dockDwellUserTime = 0; - this._dockDwellTimeoutId = 0 - - // Create a new dash object - this.dash = new MyDash.MyDash(this._remoteModel, this._monitorIndex); - - if (Main.overview.isDummy || !settings.get_boolean('show-show-apps-button')) - this.dash.hideShowAppsButton(); - - // Create the main actor and the containers for sliding in and out and - // centering, turn on track hover - - let positionStyleClass = ['top', 'right', 'bottom', 'left']; - // This is the centering actor - super._init({ - name: 'dashtodockContainer', - reactive: false, - style_class: positionStyleClass[this._position], - }); - - // This is the sliding actor whose allocation is to be tracked for input regions - this._slider = new DashSlideContainer({ - side: this._position, - slidex: 0, - ...(this._isHorizontal ? { - x_align: Clutter.ActorAlign.CENTER, - } : { - y_align: Clutter.ActorAlign.CENTER, - }) - }); - - // This is the actor whose hover status us tracked for autohide - this._box = new St.BoxLayout({ - name: 'dashtodockBox', - reactive: true, - track_hover: true - }); - this._box.connect('notify::hover', this._hoverChanged.bind(this)); - - this._signalsHandler.add([ - // update when workarea changes, for instance if other extensions modify the struts - //(like moving th panel at the bottom) - global.display, - 'workareas-changed', - this._resetPosition.bind(this) - ], [ - global.display, - 'in-fullscreen-changed', - this._updateBarrier.bind(this) - ], [ - // Monitor windows overlapping - this._intellihide, - 'status-changed', - this._updateDashVisibility.bind(this) - ], [ - // sync hover after a popupmenu is closed - this.dash, - 'menu-closed', - () => { this._box.sync_hover() } - ]); - - if (!Main.overview.isDummy) { - this._signalsHandler.add([ - Main.overview, - 'item-drag-begin', - this._onDragStart.bind(this) - ], [ - Main.overview, - 'item-drag-end', - this._onDragEnd.bind(this) - ], [ - Main.overview, - 'item-drag-cancelled', - this._onDragEnd.bind(this) - ], [ - Main.overview, - 'showing', - this._onOverviewShowing.bind(this) - ], [ - Main.overview, - 'hiding', - this._onOverviewHiding.bind(this) - ], - [ - Main.overview, - 'hidden', - this._onOverviewHidden.bind(this) - ]); - } - - this._injectionsHandler = new Utils.InjectionsHandler(); - this._themeManager = new Theming.ThemeManager(this); - - // Since the actor is not a topLevel child and its parent is now not added to the Chrome, - // the allocation change of the parent container (slide in and slideout) doesn't trigger - // anymore an update of the input regions. Force the update manually. - this.connect('notify::allocation', - Main.layoutManager._queueUpdateRegions.bind(Main.layoutManager)); - - - // Since Clutter has no longer ClutterAllocationFlags, - // "allocation-changed" signal has been removed. MR !1245 - this.dash._container.connect('notify::allocation', this._updateStaticBox.bind(this)); - this._slider.connect(this._isHorizontal ? 'notify::x' : 'notify::y', this._updateStaticBox.bind(this)); - - // Load optional features that need to be activated for one dock only - if (this._monitorIndex == settings.get_int('preferred-monitor')) - this._enableExtraFeatures(); - // Load optional features that need to be activated once per dock - this._optionalScrollWorkspaceSwitch(); - - // Delay operations that require the shell to be fully loaded and with - // user theme applied. - - this._paintId = global.stage.connect('after-paint', this._initialize.bind(this)); - - // Reserve space for the dash in the overview. - this._dashSpacer = new DashSpacer(this._box); - - // Add dash container actor and the container to the Chrome. - this.set_child(this._slider); - this._slider.set_child(this._box); - this._box.add_actor(this.dash); - - // Add aligning container without tracking it for input region - Main.uiGroup.add_child(this); - if (Main.uiGroup.contains(global.top_window_group)) - Main.uiGroup.set_child_below_sibling(this, global.top_window_group); - - if (settings.get_boolean('dock-fixed')) { - // Note: tracking the fullscreen directly on the slider actor causes some hiccups when fullscreening - // windows of certain applications - Main.layoutManager._trackActor(this, {affectsInputRegion: false, trackFullscreen: true}); - Main.layoutManager._trackActor(this._slider, {affectsStruts: true}); - } - else - Main.layoutManager._trackActor(this._slider); - - // Create and apply height/width constraint to the dash. - if (this._isHorizontal) { - this.connect('notify::width', () => { - this.dash.setMaxSize(this.width, this.height); - }); - } else { - this.connect('notify::height', () => { - this.dash.setMaxSize(this.width, this.height) - }); - } - - if (this._position == St.Side.RIGHT) - this.connect('notify::width', () => this.translation_x = -this.width); - else if (this._position == St.Side.BOTTOM) - this.connect('notify::height', () => this.translation_y = -this.height); - - // Set initial position - this._resetPosition(); - - this.connect('destroy', this._onDestroy.bind(this)); - } - - _untrackDock() { - Main.layoutManager._untrackActor(this); - Main.layoutManager._untrackActor(this._slider); - - } - - _trackDock() { - if (DockManager.settings.get_boolean('dock-fixed')) { - if (Main.layoutManager._findActor(this) == -1) - Main.layoutManager._trackActor(this, { affectsInputRegion: false, trackFullscreen: true }); - if (Main.layoutManager._findActor(this._slider) == -1) - Main.layoutManager._trackActor(this._slider, { affectsStruts: true }); - } else { - if (Main.layoutManager._findActor(this._slider) == -1) - Main.layoutManager._trackActor(this._slider); - } - } - - _initialize() { - log('[dash-to-dock] initializing...'); - - if (this._paintId > 0) { - global.stage.disconnect(this._paintId); - this._paintId = 0; - } - - // Apply custome css class according to the settings - this._themeManager.updateCustomTheme(); - - this._updateVisibilityMode(); - - // In case we are already inside the overview when the extension is loaded, - // for instance on unlocking the screen if it was locked with the overview open. - if (Main.overview.visibleTarget) { - this._onOverviewShowing(); - } - - // Setup pressure barrier (GS38+ only) - this._updatePressureBarrier(); - this._updateBarrier(); - - // setup dwelling system if pressure barriers are not available - this._setupDockDwellIfNeeded(); - } - - _onDestroy() { - // Disconnect global signals - this._signalsHandler.destroy(); - // The dash, intellihide and themeManager have global signals as well internally - this.dash.destroy(); - this._intellihide.destroy(); - this._themeManager.destroy(); - - this._injectionsHandler.destroy(); - - if (this._marginLater) { - Meta.later_remove(this._marginLater); - delete this._marginLater; - } - - // Remove barrier timeout - if (this._removeBarrierTimeoutId > 0) - GLib.source_remove(this._removeBarrierTimeoutId); - - // Remove existing barrier - this._removeBarrier(); - - // Remove pointer watcher - if (this._dockWatch) { - PointerWatcher.getPointerWatcher()._removeWatch(this._dockWatch); - this._dockWatch = null; - } - } - - _bindSettingsChanges() { - let settings = DockManager.settings; - this._signalsHandler.add([ - settings, - 'changed::scroll-action', - () => { this._optionalScrollWorkspaceSwitch(); } - ], [ - settings, - 'changed::dash-max-icon-size', - () => { this.dash.setIconSize(settings.get_int('dash-max-icon-size')); } - ], [ - settings, - 'changed::icon-size-fixed', - () => { this.dash.setIconSize(settings.get_int('dash-max-icon-size')); } - ], [ - settings, - 'changed::show-favorites', - () => { this.dash.resetAppIcons(); } - ], [ - settings, - 'changed::show-trash', - () => { this.dash.resetAppIcons(); }, - Utils.SignalsHandlerFlags.CONNECT_AFTER, - ], [ - settings, - 'changed::show-mounts', - () => { this.dash.resetAppIcons(); }, - Utils.SignalsHandlerFlags.CONNECT_AFTER - ], [ - settings, - 'changed::show-running', - () => { this.dash.resetAppIcons(); } - ], [ - settings, - 'changed::show-apps-at-top', - () => { this.dash.updateShowAppsButton(); } - ], [ - settings, - 'changed::show-show-apps-button', - () => { - if (!Main.overview.isDummy && - settings.get_boolean('show-show-apps-button')) - this.dash.showShowAppsButton(); - else - this.dash.hideShowAppsButton(); - } - ], [ - settings, - 'changed::dock-fixed', - () => { - this._untrackDock(); - this._trackDock(); - - this._resetPosition(); - - // Add or remove barrier depending on if dock-fixed - this._updateBarrier(); - - this._updateVisibilityMode(); - } - ], [ - settings, - 'changed::intellihide', - this._updateVisibilityMode.bind(this) - ], [ - settings, - 'changed::intellihide-mode', - () => { this._intellihide.forceUpdate(); } - ], [ - settings, - 'changed::autohide', - () => { - this._updateVisibilityMode(); - this._updateBarrier(); - } - ], [ - settings, - 'changed::autohide-in-fullscreen', - this._updateBarrier.bind(this) - ], - [ - settings, - 'changed::extend-height', - this._resetPosition.bind(this) - ], [ - settings, - 'changed::height-fraction', - this._resetPosition.bind(this) - ], [ - settings, - 'changed::require-pressure-to-show', - () => { - // Remove pointer watcher - if (this._dockWatch) { - PointerWatcher.getPointerWatcher()._removeWatch(this._dockWatch); - this._dockWatch = null; - } - this._setupDockDwellIfNeeded(); - this._updateBarrier(); - } - ], [ - settings, - 'changed::pressure-threshold', - () => { - this._updatePressureBarrier(); - this._updateBarrier(); - } - ]); - - } - - /** - * This is call when visibility settings change - */ - _updateVisibilityMode() { - let settings = DockManager.settings; - if (settings.get_boolean('dock-fixed')) { - this._fixedIsEnabled = true; - this._autohideIsEnabled = false; - this._intellihideIsEnabled = false; - } - else { - this._fixedIsEnabled = false; - this._autohideIsEnabled = settings.get_boolean('autohide') - this._intellihideIsEnabled = settings.get_boolean('intellihide') - } - - if (this._autohideIsEnabled) - this.add_style_class_name('autohide'); - else - this.remove_style_class_name('autohide'); - - if (this._intellihideIsEnabled) - this._intellihide.enable(); - else - this._intellihide.disable(); - - this._updateDashVisibility(); - } - - /** - * Show/hide dash based on, in order of priority: - * overview visibility - * fixed mode - * intellihide - * autohide - * overview visibility - */ - _updateDashVisibility() { - if (Main.overview.visibleTarget) - return; - - let settings = DockManager.settings; - - if (this._fixedIsEnabled) { - this._removeAnimations(); - this._animateIn(settings.get_double('animation-time'), 0); - } - else if (this._intellihideIsEnabled) { - if (this._intellihide.getOverlapStatus()) { - this._ignoreHover = false; - // Do not hide if autohide is enabled and mouse is hover - if (!this._box.hover || !this._autohideIsEnabled) - this._animateOut(settings.get_double('animation-time'), 0); - } - else { - this._ignoreHover = true; - this._removeAnimations(); - this._animateIn(settings.get_double('animation-time'), 0); - } - } - else { - if (this._autohideIsEnabled) { - this._ignoreHover = false; - - if (this._box.hover) - this._animateIn(settings.get_double('animation-time'), 0); - else - this._animateOut(settings.get_double('animation-time'), 0); - } - else - this._animateOut(settings.get_double('animation-time'), 0); - } - } - - _onOverviewShowing() { - this.add_style_class_name('overview'); - - this._ignoreHover = true; - this._intellihide.disable(); - this._removeAnimations(); - // The overview uses the monitor's work area to calculate background size. - // If our dock is fixed, it will shrink the monitor's work area unexpectedly. - this._untrackDock(); - this._animateIn(DockManager.settings.get_double('animation-time'), 0); - } - - _onOverviewHiding() { - this._ignoreHover = false; - this._intellihide.enable(); - this._trackDock(); - this._updateDashVisibility(); - } - - _onOverviewHidden() { - this.remove_style_class_name('overview'); - } - - _hoverChanged() { - if (!this._ignoreHover) { - // Skip if dock is not in autohide mode for instance because it is shown - // by intellihide. - if (this._autohideIsEnabled) { - if (this._box.hover) - this._show(); - else - this._hide(); - } - } - } - - getDockState() { - return this._dockState; - } - - _show() { - this._delayedHide = false; - if ((this._dockState == State.HIDDEN) || (this._dockState == State.HIDING)) { - if (this._dockState == State.HIDING) - // suppress all potential queued transitions - i.e. added but not started, - // always give priority to show - this._removeAnimations(); - - this.emit('showing'); - this._animateIn(DockManager.settings.get_double('animation-time'), 0); - } - } - - _hide() { - // If no hiding animation is running or queued - if ((this._dockState == State.SHOWN) || (this._dockState == State.SHOWING)) { - let settings = DockManager.settings; - let delay = settings.get_double('hide-delay'); - - if (this._dockState == State.SHOWING) { - // if a show already started, let it finish; queue hide without removing the show. - // to obtain this, we wait for the animateIn animation to be completed - this._delayedHide = true; - return; - } - - this.emit('hiding'); - this._animateOut(settings.get_double('animation-time'), delay); - } - } - - _animateIn(time, delay) { - this._dockState = State.SHOWING; - this.dash.iconAnimator.start(); - this._delayedHide = false; - - this._slider.ease_property('slidex', 1, { - duration: time * 1000, - delay: delay * 1000, - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => { - this._dockState = State.SHOWN; - // Remove barrier so that mouse pointer is released and can access monitors on other side of dock - // NOTE: Delay needed to keep mouse from moving past dock and re-hiding dock immediately. This - // gives users an opportunity to hover over the dock - if (this._removeBarrierTimeoutId > 0) - GLib.source_remove(this._removeBarrierTimeoutId); - - if (!this._delayedHide) { - this._removeBarrierTimeoutId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, 100, this._removeBarrier.bind(this)); - } else { - this._hide(); - } - } - }); - } - - _animateOut(time, delay) { - this._dockState = State.HIDING; - - this._slider.ease_property('slidex', 0, { - duration: time * 1000, - delay: delay * 1000, - mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => { - this._dockState = State.HIDDEN; - // Remove queued barried removal if any - if (this._removeBarrierTimeoutId > 0) - GLib.source_remove(this._removeBarrierTimeoutId); - this._updateBarrier(); - this.dash.iconAnimator.pause(); - } - }); - } - - /** - * Dwelling system based on the GNOME Shell 3.14 messageTray code. - */ - _setupDockDwellIfNeeded() { - // If we don't have extended barrier features, then we need - // to support the old tray dwelling mechanism. - if (!global.display.supports_extended_barriers() || - !DockManager.settings.get_boolean('require-pressure-to-show')) { - let pointerWatcher = PointerWatcher.getPointerWatcher(); - this._dockWatch = pointerWatcher.addWatch(DOCK_DWELL_CHECK_INTERVAL, this._checkDockDwell.bind(this)); - this._dockDwelling = false; - this._dockDwellUserTime = 0; - } - } - - _checkDockDwell(x, y) { - - let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitor.index) - let shouldDwell; - // Check for the correct screen edge, extending the sensitive area to the whole workarea, - // minus 1 px to avoid conflicting with other active corners. - if (this._position == St.Side.LEFT) - shouldDwell = (x == this._monitor.x) && (y > workArea.y) && (y < workArea.y + workArea.height); - else if (this._position == St.Side.RIGHT) - shouldDwell = (x == this._monitor.x + this._monitor.width - 1) && (y > workArea.y) && (y < workArea.y + workArea.height); - else if (this._position == St.Side.TOP) - shouldDwell = (y == this._monitor.y) && (x > workArea.x) && (x < workArea.x + workArea.width); - else if (this._position == St.Side.BOTTOM) - shouldDwell = (y == this._monitor.y + this._monitor.height - 1) && (x > workArea.x) && (x < workArea.x + workArea.width); - - if (shouldDwell) { - // We only set up dwell timeout when the user is not hovering over the dock - // already (!this._box.hover). - // The _dockDwelling variable is used so that we only try to - // fire off one dock dwell - if it fails (because, say, the user has the mouse down), - // we don't try again until the user moves the mouse up and down again. - if (!this._dockDwelling && !this._box.hover && (this._dockDwellTimeoutId == 0)) { - // Save the interaction timestamp so we can detect user input - let focusWindow = global.display.focus_window; - this._dockDwellUserTime = focusWindow ? focusWindow.user_time : 0; - - this._dockDwellTimeoutId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, - DockManager.settings.get_double('show-delay') * 1000, - this._dockDwellTimeout.bind(this)); - GLib.Source.set_name_by_id(this._dockDwellTimeoutId, '[dash-to-dock] this._dockDwellTimeout'); - } - this._dockDwelling = true; - } - else { - this._cancelDockDwell(); - this._dockDwelling = false; - } - } - - _cancelDockDwell() { - if (this._dockDwellTimeoutId != 0) { - GLib.source_remove(this._dockDwellTimeoutId); - this._dockDwellTimeoutId = 0; - } - } - - _dockDwellTimeout() { - this._dockDwellTimeoutId = 0; - - if (!DockManager.settings.get_boolean('autohide-in-fullscreen') && - this._monitor.inFullscreen) - return GLib.SOURCE_REMOVE; - - // We don't want to open the tray when a modal dialog - // is up, so we check the modal count for that. When we are in the - // overview we have to take the overview's modal push into account - if (Main.modalCount > (Main.overview.visible ? 1 : 0)) - return GLib.SOURCE_REMOVE; - - // If the user interacted with the focus window since we started the tray - // dwell (by clicking or typing), don't activate the message tray - let focusWindow = global.display.focus_window; - let currentUserTime = focusWindow ? focusWindow.user_time : 0; - if (currentUserTime != this._dockDwellUserTime) - return GLib.SOURCE_REMOVE; - - // Reuse the pressure version function, the logic is the same - this._onPressureSensed(); - return GLib.SOURCE_REMOVE; - } - - _updatePressureBarrier() { - let settings = DockManager.settings; - this._canUsePressure = global.display.supports_extended_barriers(); - let pressureThreshold = settings.get_double('pressure-threshold'); - - // Remove existing pressure barrier - if (this._pressureBarrier) { - this._pressureBarrier.destroy(); - this._pressureBarrier = null; - } - - if (this._barrier) { - this._barrier.destroy(); - this._barrier = null; - } - - // Create new pressure barrier based on pressure threshold setting - if (this._canUsePressure) { - this._pressureBarrier = new Layout.PressureBarrier(pressureThreshold, settings.get_double('show-delay')*1000, - Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW); - this._pressureBarrier.connect('trigger', (barrier) => { - if (!settings.get_boolean('autohide-in-fullscreen') && this._monitor.inFullscreen) - return; - this._onPressureSensed(); - }); - } - } - - /** - * handler for mouse pressure sensed - */ - _onPressureSensed() { - if (Main.overview.visibleTarget) - return; - - // In case the mouse move away from the dock area before hovering it, in such case the leave event - // would never be triggered and the dock would stay visible forever. - let triggerTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 250, () => { - triggerTimeoutId = 0; - - let [x, y, mods] = global.get_pointer(); - let shouldHide = true; - switch (this._position) { - case St.Side.LEFT: - if (x <= this.staticBox.x2 && - x >= this._monitor.x && - y >= this._monitor.y && - y <= this._monitor.y + this._monitor.height) { - shouldHide = false; - } - break; - case St.Side.RIGHT: - if (x >= this.staticBox.x1 && - x <= this._monitor.x + this._monitor.width && - y >= this._monitor.y && - y <= this._monitor.y + this._monitor.height) { - shouldHide = false; - } - break; - case St.Side.TOP: - if (x >= this._monitor.x && - x <= this._monitor.x + this._monitor.width && - y <= this.staticBox.y2 && - y >= this._monitor.y) { - shouldHide = false; - } - break; - case St.Side.BOTTOM: - if (x >= this._monitor.x && - x <= this._monitor.x + this._monitor.width && - y >= this.staticBox.y1 && - y <= this._monitor.y + this._monitor.height) { - shouldHide = false; - } - } - if (shouldHide) { - this._hoverChanged(); - return GLib.SOURCE_REMOVE; - } - else { - return GLib.SOURCE_CONTINUE; - } - - }); - - this._show(); - } - - /** - * Remove pressure barrier - */ - _removeBarrier() { - if (this._barrier) { - if (this._pressureBarrier) - this._pressureBarrier.removeBarrier(this._barrier); - this._barrier.destroy(); - this._barrier = null; - } - this._removeBarrierTimeoutId = 0; - return false; - } - - /** - * Update pressure barrier size - */ - _updateBarrier() { - // Remove existing barrier - this._removeBarrier(); - - // The barrier needs to be removed in fullscreen with autohide disabled, otherwise the mouse can - // get trapped on monitor. - if (this._monitor.inFullscreen && - !DockManager.settings.get_boolean('autohide-in-fullscreen')) - return - - // Manually reset pressure barrier - // This is necessary because we remove the pressure barrier when it is triggered to show the dock - if (this._pressureBarrier) { - this._pressureBarrier._reset(); - this._pressureBarrier._isTriggered = false; - } - - // Create new barrier - // The barrier extends to the whole workarea, minus 1 px to avoid conflicting with other active corners - // Note: dash in fixed position doesn't use pressure barrier. - if (this._canUsePressure && this._autohideIsEnabled && - DockManager.settings.get_boolean('require-pressure-to-show')) { - let x1, x2, y1, y2, direction; - let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitor.index) - - if (this._position == St.Side.LEFT) { - x1 = this._monitor.x + 1; - x2 = x1; - y1 = workArea.y + 1; - y2 = workArea.y + workArea.height - 1; - direction = Meta.BarrierDirection.POSITIVE_X; - } - else if (this._position == St.Side.RIGHT) { - x1 = this._monitor.x + this._monitor.width - 1; - x2 = x1; - y1 = workArea.y + 1; - y2 = workArea.y + workArea.height - 1; - direction = Meta.BarrierDirection.NEGATIVE_X; - } - else if (this._position == St.Side.TOP) { - x1 = workArea.x + 1; - x2 = workArea.x + workArea.width - 1; - y1 = this._monitor.y; - y2 = y1; - direction = Meta.BarrierDirection.POSITIVE_Y; - } - else if (this._position == St.Side.BOTTOM) { - x1 = workArea.x + 1; - x2 = workArea.x + workArea.width - 1; - y1 = this._monitor.y + this._monitor.height; - y2 = y1; - direction = Meta.BarrierDirection.NEGATIVE_Y; - } - - if (this._pressureBarrier && this._dockState == State.HIDDEN) { - this._barrier = new Meta.Barrier({ - display: global.display, - x1: x1, - x2: x2, - y1: y1, - y2: y2, - directions: direction - }); - this._pressureBarrier.addBarrier(this._barrier); - } - } - } - - _isPrimaryMonitor() { - return (this._monitorIndex == Main.layoutManager.primaryIndex); - } - - _resetPosition() { - // Ensure variables linked to settings are updated. - this._updateVisibilityMode(); - - let extendHeight = DockManager.settings.get_boolean('extend-height'); - - // Note: do not use the workarea coordinates in the direction on which the dock is placed, - // to avoid a loop [position change -> workArea change -> position change] with - // fixed dock. - let workArea = Main.layoutManager.getWorkAreaForMonitor(this._monitorIndex); - - - let fraction = DockManager.settings.get_double('height-fraction'); - - if (extendHeight) - fraction = 1; - else if ((fraction < 0) || (fraction > 1)) - fraction = 0.95; - - if (this._isHorizontal) { - this.width = Math.round(fraction * workArea.width); - - let pos_y = this._monitor.y; - if (this._position == St.Side.BOTTOM) - pos_y += this._monitor.height; - - this.x = workArea.x + Math.round((1 - fraction) / 2 * workArea.width); - this.y = pos_y; - - if (extendHeight) { - this.dash._container.set_width(this.width); - this.add_style_class_name('extended'); - } else { - this.dash._container.set_width(-1); - this.remove_style_class_name('extended'); - } - } else { - this.height = Math.round(fraction * workArea.height); - - let pos_x = this._monitor.x; - if (this._position == St.Side.RIGHT) - pos_x += this._monitor.width; - - this.x = pos_x; - this.y = workArea.y + Math.round((1 - fraction) / 2 * workArea.height); - - this._signalsHandler.removeWithLabel('verticalOffsetChecker'); - - if (extendHeight) { - this.dash._container.set_height(this.height); - this.add_style_class_name('extended'); - } else { - this.dash._container.set_height(-1); - this.remove_style_class_name('extended'); - } - } - } - - _updateStaticBox() { - this.staticBox.init_rect( - this.x + this._slider.x - (this._position == St.Side.RIGHT ? this._box.width : 0), - this.y + this._slider.y - (this._position == St.Side.BOTTOM ? this._box.height : 0), - this._box.width, - this._box.height - ); - - this._intellihide.updateTargetBox(this.staticBox); - } - - _removeAnimations() { - this._slider.remove_all_transitions(); - } - - _onDragStart() { - this._oldignoreHover = this._ignoreHover; - this._ignoreHover = true; - this._animateIn(DockManager.settings.get_double('animation-time'), 0); - } - - _onDragEnd() { - if (this._oldignoreHover !== null) - this._ignoreHover = this._oldignoreHover; - this._oldignoreHover = null; - this._box.sync_hover(); - } - - /** - * Show dock and give key focus to it - */ - _onAccessibilityFocus() { - this._box.navigate_focus(null, St.DirectionType.TAB_FORWARD, false); - this._animateIn(DockManager.settings.get_double('animation-time'), 0); - } - - // Optional features to be enabled only for the main Dock - _enableExtraFeatures() { - // Restore dash accessibility - Main.ctrlAltTabManager.addGroup( - this.dash, _('Dash'), 'user-bookmarks-symbolic', - {focusCallback: this._onAccessibilityFocus.bind(this)}); - } - - /** - * Switch workspace by scrolling over the dock - */ - _optionalScrollWorkspaceSwitch() { - let label = 'optionalScrollWorkspaceSwitch'; - - function isEnabled() { - return DockManager.settings.get_enum('scroll-action') === scrollAction.SWITCH_WORKSPACE; - } - - DockManager.settings.connect('changed::scroll-action', () => { - if (isEnabled.bind(this)()) - enable.bind(this)(); - else - disable.bind(this)(); - }); - - if (isEnabled.bind(this)()) - enable.bind(this)(); - - function enable() { - this._signalsHandler.removeWithLabel(label); - - this._signalsHandler.addWithLabel(label, [ - this._box, - 'scroll-event', - onScrollEvent.bind(this) - ]); - } - - function disable() { - this._signalsHandler.removeWithLabel(label); - - if (this._optionalScrollWorkspaceSwitchDeadTimeId) { - GLib.source_remove(this._optionalScrollWorkspaceSwitchDeadTimeId); - this._optionalScrollWorkspaceSwitchDeadTimeId = 0; - } - } - - // This was inspired to desktop-scroller@obsidien.github.com - function onScrollEvent(actor, event) { - // When in overview change workspace only in windows view - if (Main.overview.visible) - return false; - - let activeWs = global.workspace_manager.get_active_workspace(); - let direction = null; - - switch (event.get_scroll_direction()) { - case Clutter.ScrollDirection.UP: - direction = Meta.MotionDirection.LEFT; - break; - case Clutter.ScrollDirection.DOWN: - direction = Meta.MotionDirection.RIGHT; - break; - case Clutter.ScrollDirection.SMOOTH: - let [dx, dy] = event.get_scroll_delta(); - if (dy < 0) - direction = Meta.MotionDirection.LEFT; - else if (dy > 0) - direction = Meta.MotionDirection.RIGHT; - break; - } - - if (direction !== null) { - // Prevent scroll events from triggering too many workspace switches - // by adding a 250ms deadtime between each scroll event. - // Usefull on laptops when using a touchpad. - - // During the deadtime do nothing - if (this._optionalScrollWorkspaceSwitchDeadTimeId) - return false; - else - this._optionalScrollWorkspaceSwitchDeadTimeId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, 250, () => { - this._optionalScrollWorkspaceSwitchDeadTimeId = 0; - }); - - let ws; - - ws = activeWs.get_neighbor(direction) - - if (Main.wm._workspaceSwitcherPopup == null) - // Support Workspace Grid extension showing their custom Grid Workspace Switcher - if (global.workspace_manager.workspace_grid !== undefined) { - Main.wm._workspaceSwitcherPopup = - global.workspace_manager.workspace_grid.getWorkspaceSwitcherPopup(); - } else { - Main.wm._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup(); - } - // Set the actor non reactive, so that it doesn't prevent the - // clicks events from reaching the dash actor. I can't see a reason - // why it should be reactive. - Main.wm._workspaceSwitcherPopup.reactive = false; - Main.wm._workspaceSwitcherPopup.connect('destroy', function() { - Main.wm._workspaceSwitcherPopup = null; - }); - - // If Workspace Grid is installed, let them handle the scroll behaviour. - if (global.workspace_manager.workspace_grid !== undefined) - ws = global.workspace_manager.workspace_grid.actionMoveWorkspace(direction); - else - Main.wm.actionMoveWorkspace(ws); - - // Do not show workspaceSwitcher in overview - if (!Main.overview.visible) - Main.wm._workspaceSwitcherPopup.display(direction, ws.index()); - - return true; - } - else - return false; - } - } - - _activateApp(appIndex) { - let children = this.dash._box.get_children().filter(function(actor) { - return actor.child && - actor.child.app; - }); - - // Apps currently in the dash - let apps = children.map(function(actor) { - return actor.child; - }); - - // Activate with button = 1, i.e. same as left click - let button = 1; - if (appIndex < apps.length) - apps[appIndex].activate(button); - } -}); - -/* - * Handle keybaord shortcuts - */ -const DashToDock_KeyboardShortcuts_NUM_HOTKEYS = 10; - -var KeyboardShortcuts = class DashToDock_KeyboardShortcuts { - - constructor() { - this._signalsHandler = new Utils.GlobalSignalsHandler(); - - this._hotKeysEnabled = false; - if (DockManager.settings.get_boolean('hot-keys')) - this._enableHotKeys(); - - this._signalsHandler.add([ - DockManager.settings, - 'changed::hot-keys', - () => { - if (DockManager.settings.get_boolean('hot-keys')) - this._enableHotKeys.bind(this)(); - else - this._disableHotKeys.bind(this)(); - } - ]); - - this._optionalNumberOverlay(); - } - - destroy() { - // Remove keybindings - this._disableHotKeys(); - this._disableExtraShortcut(); - this._signalsHandler.destroy(); - } - - _enableHotKeys() { - if (this._hotKeysEnabled) - return; - - // Setup keyboard bindings for dash elements - let keys = ['app-hotkey-', 'app-shift-hotkey-', 'app-ctrl-hotkey-']; - keys.forEach( function(key) { - for (let i = 0; i < DashToDock_KeyboardShortcuts_NUM_HOTKEYS; i++) { - let appNum = i; - Main.wm.addKeybinding(key + (i + 1), DockManager.settings, - Meta.KeyBindingFlags.IGNORE_AUTOREPEAT, - Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, - () => { - DockManager.getDefault().mainDock._activateApp(appNum); - this._showOverlay(); - }); - } - }, this); - - this._hotKeysEnabled = true; - } - - _disableHotKeys() { - if (!this._hotKeysEnabled) - return; - - let keys = ['app-hotkey-', 'app-shift-hotkey-', 'app-ctrl-hotkey-']; - keys.forEach( function(key) { - for (let i = 0; i < DashToDock_KeyboardShortcuts_NUM_HOTKEYS; i++) - Main.wm.removeKeybinding(key + (i + 1)); - }, this); - - this._hotKeysEnabled = false; - } - - _optionalNumberOverlay() { - let settings = DockManager.settings; - this._shortcutIsSet = false; - // Enable extra shortcut if either 'overlay' or 'show-dock' are true - if (settings.get_boolean('hot-keys') && - (settings.get_boolean('hotkeys-overlay') || settings.get_boolean('hotkeys-show-dock'))) - this._enableExtraShortcut(); - - this._signalsHandler.add([ - settings, - 'changed::hot-keys', - this._checkHotkeysOptions.bind(this) - ], [ - settings, - 'changed::hotkeys-overlay', - this._checkHotkeysOptions.bind(this) - ], [ - settings, - 'changed::hotkeys-show-dock', - this._checkHotkeysOptions.bind(this) - ]); - } - - _checkHotkeysOptions() { - let settings = DockManager.settings; - - if (settings.get_boolean('hot-keys') && - (settings.get_boolean('hotkeys-overlay') || settings.get_boolean('hotkeys-show-dock'))) - this._enableExtraShortcut(); - else - this._disableExtraShortcut(); - } - - _enableExtraShortcut() { - if (!this._shortcutIsSet) { - Main.wm.addKeybinding('shortcut', DockManager.settings, - Meta.KeyBindingFlags.IGNORE_AUTOREPEAT, - Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW, - this._showOverlay.bind(this)); - this._shortcutIsSet = true; - } - } - - _disableExtraShortcut() { - if (this._shortcutIsSet) { - Main.wm.removeKeybinding('shortcut'); - this._shortcutIsSet = false; - } - } - - _showOverlay() { - for (let dock of DockManager.allDocks) { - if (DockManager.settings.get_boolean('hotkeys-overlay')) - dock.dash.toggleNumberOverlay(true); - - // Restart the counting if the shortcut is pressed again - if (dock._numberOverlayTimeoutId) { - GLib.source_remove(dock._numberOverlayTimeoutId); - dock._numberOverlayTimeoutId = 0; - } - - // Hide the overlay/dock after the timeout - let timeout = DockManager.settings.get_double('shortcut-timeout') * 1000; - dock._numberOverlayTimeoutId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, timeout, () => { - dock._numberOverlayTimeoutId = 0; - dock.dash.toggleNumberOverlay(false); - // Hide the dock again if necessary - dock._updateDashVisibility(); - }); - - // Show the dock if it is hidden - if (DockManager.settings.get_boolean('hotkeys-show-dock')) { - let showDock = (dock._intellihideIsEnabled || dock._autohideIsEnabled); - if (showDock) - dock._show(); - } - } - } -}; - -/** - * Isolate overview to open new windows for inactive apps - * Note: the future implementaion is not fully contained here. Some bits are around in other methods of other classes. - * This class just take care of enabling/disabling the option. - */ -var WorkspaceIsolation = class DashToDock_WorkspaceIsolation { - - constructor() { - - let settings = DockManager.settings; - - this._signalsHandler = new Utils.GlobalSignalsHandler(); - this._injectionsHandler = new Utils.InjectionsHandler(); - - this._signalsHandler.add([ - settings, - 'changed::isolate-workspaces', - () => { - DockManager.allDocks.forEach((dock) => - dock.dash.resetAppIcons()); - if (settings.get_boolean('isolate-workspaces') || - settings.get_boolean('isolate-monitors')) - this._enable.bind(this)(); - else - this._disable.bind(this)(); - } - ],[ - settings, - 'changed::isolate-monitors', - () => { - DockManager.allDocks.forEach((dock) => - dock.dash.resetAppIcons()); - if (settings.get_boolean('isolate-workspaces') || - settings.get_boolean('isolate-monitors')) - this._enable.bind(this)(); - else - this._disable.bind(this)(); - } - ]); - - if (settings.get_boolean('isolate-workspaces') || - settings.get_boolean('isolate-monitors')) - this._enable(); - - } - - _enable() { - - // ensure I never double-register/inject - // although it should never happen - this._disable(); - - DockManager.allDocks.forEach((dock) => { - this._signalsHandler.addWithLabel('isolation', [ - global.display, - 'restacked', - dock.dash._queueRedisplay.bind(dock.dash) - ], [ - global.window_manager, - 'switch-workspace', - dock.dash._queueRedisplay.bind(dock.dash) - ]); - - // This last signal is only needed for monitor isolation, as windows - // might migrate from one monitor to another without triggering 'restacked' - if (DockManager.settings.get_boolean('isolate-monitors')) - this._signalsHandler.addWithLabel('isolation', [ - global.display, - 'window-entered-monitor', - dock.dash._queueRedisplay.bind(dock.dash) - ]); - - }, this); - - // here this is the Shell.App - function IsolatedOverview() { - // These lines take care of Nautilus for icons on Desktop - let windows = this.get_windows().filter(function(w) { - return w.get_workspace().index() == global.workspace_manager.get_active_workspace_index(); - }); - if (windows.length == 1) - if (windows[0].skip_taskbar) - return this.open_new_window(-1); - - if (this.is_on_workspace(global.workspace_manager.get_active_workspace())) - return Main.activateWindow(windows[0]); - return this.open_new_window(-1); - } - - this._injectionsHandler.addWithLabel('isolation', [ - Shell.App.prototype, - 'activate', - IsolatedOverview - ]); - } - - _disable () { - this._signalsHandler.removeWithLabel('isolation'); - this._injectionsHandler.removeWithLabel('isolation'); - } - - destroy() { - this._signalsHandler.destroy(); - this._injectionsHandler.destroy(); - } -}; - - -var DockManager = class DashToDock_DockManager { - - constructor() { - if (Me.imports.extension.dockManager) - throw new Error('DashToDock has been already initialized'); - - Me.imports.extension.dockManager = this; - - this._remoteModel = new LauncherAPI.LauncherEntryRemoteModel(); - this._signalsHandler = new Utils.GlobalSignalsHandler(); - this._settings = ExtensionUtils.getSettings('org.gnome.shell.extensions.dash-to-dock'); - this._oldDash = Main.overview.isDummy ? null : Main.overview.dash; - - this._ensureFileManagerClient(); - - /* Array of all the docks created */ - this._allDocks = []; - this._createDocks(); - - // status variable: true when the overview is shown through the dash - // applications button. - this._forcedOverview = false; - - // Connect relevant signals to the toggling function - this._bindSettingsChanges(); - } - - static getDefault() { - return Me.imports.extension.dockManager - } - - static get allDocks() { - return DockManager.getDefault()._allDocks; - } - - static get settings() { - return DockManager.getDefault()._settings; - } - - get fm1Client() { - return this._fm1Client; - } - - get mainDock() { - return this._allDocks.length ? this._allDocks[0] : null; - } - - _ensureFileManagerClient() { - let supportsLocations = ['show-trash', 'show-mounts'].some((s) => { - return this._settings.get_boolean(s); - }); - - if (supportsLocations) { - if (!this._fm1Client) - this._fm1Client = new FileManager1API.FileManager1Client(); - } else if (this._fm1Client) { - this._fm1Client.destroy(); - this._fm1Client = null; - } - } - - _toggle() { - if (this._toggleLater) - Meta.later_remove(this._toggleLater); - - this._toggleLater = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { - delete this._toggleLater; - this._restoreDash(); - this._deleteDocks(); - this._createDocks(); - this.emit('toggled'); - }); - } - - _bindSettingsChanges() { - // Connect relevant signals to the toggling function - this._signalsHandler.add([ - Meta.MonitorManager.get(), - 'monitors-changed', - this._toggle.bind(this) - ], [ - Main.sessionMode, - 'updated', - this._toggle.bind(this) - ], [ - this._settings, - 'changed::multi-monitor', - this._toggle.bind(this) - ], [ - this._settings, - 'changed::preferred-monitor', - this._toggle.bind(this) - ], [ - this._settings, - 'changed::dock-position', - this._toggle.bind(this) - ], [ - this._settings, - 'changed::extend-height', - this._adjustPanelCorners.bind(this) - ], [ - this._settings, - 'changed::dock-fixed', - this._adjustPanelCorners.bind(this) - ], [ - this._settings, - 'changed::show-trash', - () => this._ensureFileManagerClient() - ], [ - this._settings, - 'changed::show-mounts', - () => this._ensureFileManagerClient() - ]); - } - - _createDocks() { - - // If there are no monitors (headless configurations, but it can also happen temporary while disconnecting - // and reconnecting monitors), just do nothing. When a monitor will be connected we we'll be notified and - // and thus create the docks. This prevents pointing trying to access monitors throughout the code, were we - // are assuming that at least the primary monitor is present. - if (Main.layoutManager.monitors.length <= 0) { - return; - } - - this._preferredMonitorIndex = this._settings.get_int('preferred-monitor'); - // In case of multi-monitor, we consider the dock on the primary monitor to be the preferred (main) one - // regardless of the settings - // The dock goes on the primary monitor also if the settings are incosistent (e.g. desired monitor not connected). - if (this._settings.get_boolean('multi-monitor') || - this._preferredMonitorIndex < 0 || this._preferredMonitorIndex > Main.layoutManager.monitors.length - 1 - ) { - this._preferredMonitorIndex = Main.layoutManager.primaryIndex; - } else { - // Gdk and shell monitors numbering differ at least under wayland: - // While the primary monitor appears to be always index 0 in Gdk, - // the shell can assign a different number (Main.layoutManager.primaryMonitor) - // This ensure the indexing in the settings (Gdk) and in the shell are matched, - // i.e. that we start counting from the primaryMonitorIndex - this._preferredMonitorIndex = (Main.layoutManager.primaryIndex + this._preferredMonitorIndex) % Main.layoutManager.monitors.length ; - } - - // First we create the main Dock, to get the extra features to bind to this one - let dock = new DockedDash(this._remoteModel, this._preferredMonitorIndex); - this._allDocks.push(dock); - - // connect app icon into the view selector - dock.dash.showAppsButton.connect('notify::checked', this._onShowAppsButtonToggled.bind(this)); - - // Make the necessary changes to Main.overview.dash - this._prepareMainDash(); - - // Adjust corners if necessary - this._adjustPanelCorners(); - - if (this._settings.get_boolean('multi-monitor')) { - let nMon = Main.layoutManager.monitors.length; - for (let iMon = 0; iMon < nMon; iMon++) { - if (iMon == this._preferredMonitorIndex) - continue; - let dock = new DockedDash(this._remoteModel, iMon); - this._allDocks.push(dock); - // connect app icon into the view selector - dock.dash.showAppsButton.connect('notify::checked', this._onShowAppsButtonToggled.bind(this)); - } - } - - // Load optional features. We load *after* the docks are created, since - // we need to connect the signals to all dock instances. - this._workspaceIsolation = new WorkspaceIsolation(); - this._keyboardShortcuts = new KeyboardShortcuts(); - } - - _prepareMainDash() { - // Ensure Main.overview.dash is set to our dash in dummy mode - // while just use the default getter otherwise. - // The getter must be dynamic and not set only when we've a dummy - // overview because the mode can change dynamically. - let defaultDashGetter = Object.getOwnPropertyDescriptor( - Main.overview.constructor.prototype, 'dash').get; - Object.defineProperty(Main.overview, 'dash', { - configurable: true, - get: () => Main.overview.isDummy ? - this.mainDock.dash : defaultDashGetter.call(Main.overview), - }); - - if (Main.overview.isDummy) - return; - - this._signalsHandler.removeWithLabel('old-dash-changes'); - - // Hide usual Dash - this._oldDash.hide(); - - // Also set dash width to 1, so it's almost not taken into account by code - // calculaing the reserved space in the overview. The reason to keep it at 1 is - // to allow its visibility change to trigger an allocaion of the appGrid which - // in turn is triggergin the appsIcon spring animation, required when no other - // actors has this effect, i.e in horizontal mode and without the workspaceThumnails - // 1 static workspace only) - this._oldDash.set_height(1); - - this._signalsHandler.addWithLabel('old-dash-changes', [ - this._oldDash, - 'notify::visible', - () => this._prepareMainDash() - ], [ - this._oldDash, - 'notify::width', - () => this._prepareMainDash() - ]); - - // Pretend I'm the dash: meant to make appgrid swarm animation come from - // the right position of the appShowButton. - let overviewControls = Main.overview._overview._controls; - overviewControls.dash = this.mainDock.dash; - overviewControls._searchController._showAppsButton = this.mainDock.dash.showAppsButton; - - if (this.mainDock.dash._isHorizontal) { - overviewControls._dashSpacer = this.mainDock._dashSpacer; - Main.overview._overview._controls.add_child(this.mainDock._dashSpacer); - Main.overview._overview._controls.layout_manager._dash = this.mainDock._dashSpacer; - } - } - - _deleteDocks() { - if (!this._allDocks.length) - return; - - // Remove extra features - this._workspaceIsolation.destroy(); - this._keyboardShortcuts.destroy(); - - // Delete all docks - this._allDocks.forEach(d => d.destroy()); - this._allDocks = []; - } - - _restoreDash() { - Object.defineProperty(Main.overview, 'dash', - Object.getOwnPropertyDescriptor( - Main.overview.constructor.prototype, 'dash')); - - if (!this._oldDash) - return; - - this._signalsHandler.removeWithLabel('old-dash-changes'); - - let overviewControls = Main.overview._overview._controls; - Main.overview._overview._controls.layout_manager._dash = this._oldDash; - if (this.mainDock._dashSpacer) { - Main.overview._overview._controls.remove_child(this.mainDock._dashSpacer); - } - - overviewControls.dash = this._oldDash; - overviewControls._searchController._showAppsButton = this._oldDash.showAppsButton; - Main.overview.dash.show(); - Main.overview.dash.set_height(-1); // reset default dash size - // This force the recalculation of the icon size - Main.overview.dash._maxHeight = -1; - } - - get searchController() { - return Main.overview._overview.controls._searchController; - } - - _onShowAppsButtonToggled(button) { - const checked = button.checked; - const overviewControls = Main.overview._overview.controls; - - if (!Main.overview.visible) { - this.mainDock.dash.showAppsButton._fromDesktop = true; - Main.overview.show(OverviewControls.ControlsState.APP_GRID); - } else { - if (!checked && this.mainDock.dash.showAppsButton._fromDesktop) { - Main.overview.hide(); - this.mainDock.dash.showAppsButton._fromDesktop = false; - } else { - // TODO: I'm not sure how reliable this is, we might need to move the - // _onShowAppsButtonToggled logic into the extension. - if (!checked) { - this.mainDock.dash.showAppsButton._fromDesktop = false; - } - - // Instead of "syncing" the stock button, let's call its callback directly. - overviewControls._onShowAppsButtonToggled.call(overviewControls); - } - } - - // Because we "disconnected" from the search controller, we have to manage its state. - this.searchController._setSearchActive(false); - } - - destroy() { - this._signalsHandler.destroy(); - if (this._toggleLater) { - Meta.later_remove(this._toggleLater); - delete this._toggleLater; - } - this._restoreDash(); - this._deleteDocks(); - this._revertPanelCorners(); - if (this._oldSelectorMargin) - Main.overview._overview.controls._searchController.margin_bottom = this._oldSelectorMargin; - if (this._fm1Client) { - this._fm1Client.destroy(); - this._fm1Client = null; - } - this._remoteModel.destroy(); - this._settings.run_dispose(); - this._settings = null; - this._oldDash = null; - - Me.imports.extension.dockManager = null; - } - - /** - * Adjust Panel corners - */ - _adjustPanelCorners() { - let position = Utils.getPosition(); - let isHorizontal = ((position == St.Side.TOP) || (position == St.Side.BOTTOM)); - let extendHeight = this._settings.get_boolean('extend-height'); - let fixedIsEnabled = this._settings.get_boolean('dock-fixed'); - let dockOnPrimary = this._settings.get_boolean('multi-monitor') || - this._preferredMonitorIndex == Main.layoutManager.primaryIndex; - - if (!isHorizontal && dockOnPrimary && extendHeight && fixedIsEnabled) { - Main.panel._rightCorner.hide(); - Main.panel._leftCorner.hide(); - } - else - this._revertPanelCorners(); - } - - _revertPanelCorners() { - Main.panel._leftCorner.show(); - Main.panel._rightCorner.show(); - } -}; -Signals.addSignalMethods(DockManager.prototype); - -// This class drives long-running icon animations, to keep them running in sync -// with each other, and to save CPU by pausing them when the dock is hidden. -var IconAnimator = class DashToDock_IconAnimator { - constructor(actor) { - this._count = 0; - this._started = false; - this._animations = { - dance: [], - }; - this._timeline = new Clutter.Timeline({ - duration: 3000, - repeat_count: -1, - actor - }); - - this._timeline.connect('new-frame', () => { - const progress = this._timeline.get_progress(); - const danceRotation = progress < 1/6 ? 15*Math.sin(progress*24*Math.PI) : 0; - const dancers = this._animations.dance; - for (let i = 0, iMax = dancers.length; i < iMax; i++) { - dancers[i].target.rotation_angle_z = danceRotation; - } - }); - } - - destroy() { - this._timeline.stop(); - this._timeline = null; - for (const name in this._animations) { - const pairs = this._animations[name]; - for (let i = 0, iMax = pairs.length; i < iMax; i++) { - const pair = pairs[i]; - pair.target.disconnect(pair.targetDestroyId); - } - } - this._animations = null; - } - - pause() { - if (this._started && this._count > 0) { - this._timeline.stop(); - } - this._started = false; - } - - start() { - if (!this._started && this._count > 0) { - this._timeline.start(); - } - this._started = true; - } - - addAnimation(target, name) { - const targetDestroyId = target.connect('destroy', () => this.removeAnimation(target, name)); - this._animations[name].push({ target, targetDestroyId }); - if (this._started && this._count === 0) { - this._timeline.start(); - } - this._count++; - } - - removeAnimation(target, name) { - const pairs = this._animations[name]; - for (let i = 0, iMax = pairs.length; i < iMax; i++) { - const pair = pairs[i]; - if (pair.target === target) { - target.disconnect(pair.targetDestroyId); - pairs.splice(i, 1); - this._count--; - if (this._started && this._count === 0) { - this._timeline.stop(); - } - return; - } - } - } -}; diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/extension.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/extension.js deleted file mode 100644 index 0b7b5c6..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/extension.js +++ /dev/null @@ -1,21 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Docking = Me.imports.docking; - -// We declare this with var so it can be accessed by other extensions in -// GNOME Shell 3.26+ (mozjs52+). -var dockManager; - -function init() { - ExtensionUtils.initTranslations('dashtodock'); -} - -function enable() { - new Docking.DockManager(); -} - -function disable() { - dockManager.destroy(); -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/fileManager1API.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/fileManager1API.js deleted file mode 100644 index 64ec621..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/fileManager1API.js +++ /dev/null @@ -1,226 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Gio = imports.gi.Gio; -const Signals = imports.signals; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Utils = Me.imports.utils; - -const FileManager1Iface = '\ - \ - \ - '; - -const FileManager1Proxy = Gio.DBusProxy.makeProxyWrapper(FileManager1Iface); - -/** - * This class implements a client for the org.freedesktop.FileManager1 dbus - * interface, and specifically for the OpenWindowsWithLocations property - * which is published by Nautilus, but is not an official part of the interface. - * - * The property is a map from window identifiers to a list of locations open in - * the window. - * - * While OpeWindowsWithLocations is part of upstream Nautilus, for many years - * prior, Ubuntu patched Nautilus to publish XUbuntuOpenLocationsXids, which is - * similar but uses Xids as the window identifiers instead of gtk window paths. - * - * When an old or unpatched Nautilus is running, we will observe the properties - * to always be empty arrays, but there will not be any correctness issues. - */ -var FileManager1Client = class DashToDock_FileManager1Client { - - constructor() { - this._signalsHandler = new Utils.GlobalSignalsHandler(); - this._cancellable = new Gio.Cancellable(); - - this._locationMap = new Map(); - this._proxy = new FileManager1Proxy(Gio.DBus.session, - "org.freedesktop.FileManager1", - "/org/freedesktop/FileManager1", - (initable, error) => { - // Use async construction to avoid blocking on errors. - if (error) { - if (!error.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) - global.log(error); - } else { - this._updateLocationMap(); - } - }, this._cancellable); - - this._signalsHandler.add([ - this._proxy, - 'g-properties-changed', - this._onPropertyChanged.bind(this) - ], [ - // We must additionally listen for Screen events to know when to - // rebuild our location map when the set of available windows changes. - global.workspace_manager, - 'workspace-switched', - this._updateLocationMap.bind(this) - ], [ - global.display, - 'window-entered-monitor', - this._updateLocationMap.bind(this) - ], [ - global.display, - 'window-left-monitor', - this._updateLocationMap.bind(this) - ]); - } - - destroy() { - this._cancellable.cancel(); - this._signalsHandler.destroy(); - this._proxy.run_dispose(); - } - - /** - * Return an array of windows that are showing a location or - * sub-directories of that location. - */ - getWindows(location) { - let ret = new Set(); - let locationEsc = location; - - if (!location.endsWith('/')) { - locationEsc += '/'; - } - - for (let [k,v] of this._locationMap) { - if ((k + '/').startsWith(locationEsc)) { - for (let l of v) { - ret.add(l); - } - } - } - return Array.from(ret); - } - - _onPropertyChanged(proxy, changed, invalidated) { - let property = changed.unpack(); - if (property && - ('XUbuntuOpenLocationsXids' in property || - 'OpenWindowsWithLocations' in property)) { - this._updateLocationMap(); - } - } - - _updateLocationMap() { - let properties = this._proxy.get_cached_property_names(); - if (properties == null) { - // Nothing to check yet. - return; - } - - if (properties.includes('OpenWindowsWithLocations')) { - this._updateFromPaths(); - } else if (properties.includes('XUbuntuOpenLocationsXids')) { - this._updateFromXids(); - } - } - - _updateFromPaths() { - let pathToLocations = this._proxy.OpenWindowsWithLocations; - let pathToWindow = getPathToWindow(); - - let locationToWindow = new Map(); - for (let path in pathToLocations) { - let locations = pathToLocations[path]; - for (let i = 0; i < locations.length; i++) { - let l = locations[i]; - // Use a set to deduplicate when a window has a - // location open in multiple tabs. - if (!locationToWindow.has(l)) { - locationToWindow.set(l, new Set()); - } - let window = pathToWindow.get(path); - if (window != null) { - locationToWindow.get(l).add(window); - } - } - } - this._locationMap = locationToWindow; - this.emit('windows-changed'); - } - - _updateFromXids() { - let xidToLocations = this._proxy.XUbuntuOpenLocationsXids; - let xidToWindow = getXidToWindow(); - - let locationToWindow = new Map(); - for (let xid in xidToLocations) { - let locations = xidToLocations[xid]; - for (let i = 0; i < locations.length; i++) { - let l = locations[i]; - // Use a set to deduplicate when a window has a - // location open in multiple tabs. - if (!locationToWindow.has(l)) { - locationToWindow.set(l, new Set()); - } - let window = xidToWindow.get(parseInt(xid)); - if (window != null) { - locationToWindow.get(l).add(window); - } - } - } - this._locationMap = locationToWindow; - this.emit('windows-changed'); - } -} -Signals.addSignalMethods(FileManager1Client.prototype); - -/** - * Construct a map of gtk application window object paths to MetaWindows. - */ -function getPathToWindow() { - let pathToWindow = new Map(); - - for (let i = 0; i < global.workspace_manager.n_workspaces; i++) { - let ws = global.workspace_manager.get_workspace_by_index(i); - ws.list_windows().map(function(w) { - let path = w.get_gtk_window_object_path(); - if (path != null) { - pathToWindow.set(path, w); - } - }); - } - return pathToWindow; -} - -/** - * Construct a map of XIDs to MetaWindows. - * - * This is somewhat annoying as you cannot lookup a window by - * XID in any way, and must iterate through all of them looking - * for a match. - */ -function getXidToWindow() { - let xidToWindow = new Map(); - - for (let i = 0; i < global.workspace_manager.n_workspaces; i++) { - let ws = global.workspace_manager.get_workspace_by_index(i); - ws.list_windows().map(function(w) { - let xid = guessWindowXID(w); - if (xid != null) { - xidToWindow.set(parseInt(xid), w); - } - }); - } - return xidToWindow; -} - -/** - * Guesses the X ID of a window. - * - * This is the basic implementation that is sufficient for Nautilus - * windows. The pixel-saver extension has a much more complex - * implementation if we ever need it. - */ -function guessWindowXID(win) { - try { - return win.get_description().match(/0x[0-9a-f]+/)[0]; - } catch (err) { - return null; - } -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/intellihide.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/intellihide.js deleted file mode 100644 index 9c10938..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/intellihide.js +++ /dev/null @@ -1,321 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const GLib = imports.gi.GLib; -const Meta = imports.gi.Meta; -const Shell = imports.gi.Shell; - -const Main = imports.ui.main; -const Signals = imports.signals; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Docking = Me.imports.docking; -const Utils = Me.imports.utils; - -// A good compromise between reactivity and efficiency; to be tuned. -const INTELLIHIDE_CHECK_INTERVAL = 100; - -const OverlapStatus = { - UNDEFINED: -1, - FALSE: 0, - TRUE: 1 -}; - -const IntellihideMode = { - ALL_WINDOWS: 0, - FOCUS_APPLICATION_WINDOWS: 1, - MAXIMIZED_WINDOWS : 2 -}; - -// List of windows type taken into account. Order is important (keep the original -// enum order). -const handledWindowTypes = [ - Meta.WindowType.NORMAL, - Meta.WindowType.DOCK, - Meta.WindowType.DIALOG, - Meta.WindowType.MODAL_DIALOG, - Meta.WindowType.TOOLBAR, - Meta.WindowType.MENU, - Meta.WindowType.UTILITY, - Meta.WindowType.SPLASHSCREEN -]; - -/** - * A rough and ugly implementation of the intellihide behaviour. - * Intallihide object: emit 'status-changed' signal when the overlap of windows - * with the provided targetBoxClutter.ActorBox changes; - */ -var Intellihide = class DashToDock_Intellihide { - - constructor(monitorIndex) { - // Load settings - this._monitorIndex = monitorIndex; - - this._signalsHandler = new Utils.GlobalSignalsHandler(); - this._tracker = Shell.WindowTracker.get_default(); - this._focusApp = null; // The application whose window is focused. - this._topApp = null; // The application whose window is on top on the monitor with the dock. - - this._isEnabled = false; - this.status = OverlapStatus.UNDEFINED; - this._targetBox = null; - - this._checkOverlapTimeoutContinue = false; - this._checkOverlapTimeoutId = 0; - - this._trackedWindows = new Map(); - - // Connect global signals - this._signalsHandler.add([ - // Add signals on windows created from now on - global.display, - 'window-created', - this._windowCreated.bind(this) - ], [ - // triggered for instance when the window list order changes, - // included when the workspace is switched - global.display, - 'restacked', - this._checkOverlap.bind(this) - ], [ - // when windows are alwasy on top, the focus window can change - // without the windows being restacked. Thus monitor window focus change. - this._tracker, - 'notify::focus-app', - this._checkOverlap.bind(this) - ], [ - // update wne monitor changes, for instance in multimonitor when monitor are attached - Meta.MonitorManager.get(), - 'monitors-changed', - this._checkOverlap.bind(this) - ]); - } - - destroy() { - // Disconnect global signals - this._signalsHandler.destroy(); - - // Remove residual windows signals - this.disable(); - } - - enable() { - this._isEnabled = true; - this._status = OverlapStatus.UNDEFINED; - global.get_window_actors().forEach(function(wa) { - this._addWindowSignals(wa); - }, this); - this._doCheckOverlap(); - } - - disable() { - this._isEnabled = false; - - for (let wa of this._trackedWindows.keys()) { - this._removeWindowSignals(wa); - } - this._trackedWindows.clear(); - - if (this._checkOverlapTimeoutId > 0) { - GLib.source_remove(this._checkOverlapTimeoutId); - this._checkOverlapTimeoutId = 0; - } - } - - _windowCreated(display, metaWindow) { - this._addWindowSignals(metaWindow.get_compositor_private()); - } - - _addWindowSignals(wa) { - if (!this._handledWindow(wa)) - return; - let signalId = wa.connect('notify::allocation', this._checkOverlap.bind(this)); - this._trackedWindows.set(wa, signalId); - wa.connect('destroy', this._removeWindowSignals.bind(this)); - } - - _removeWindowSignals(wa) { - if (this._trackedWindows.get(wa)) { - wa.disconnect(this._trackedWindows.get(wa)); - this._trackedWindows.delete(wa); - } - - } - - updateTargetBox(box) { - this._targetBox = box; - this._checkOverlap(); - } - - forceUpdate() { - this._status = OverlapStatus.UNDEFINED; - this._doCheckOverlap(); - } - - getOverlapStatus() { - return (this._status == OverlapStatus.TRUE); - } - - _checkOverlap() { - if (!this._isEnabled || (this._targetBox == null)) - return; - - /* Limit the number of calls to the doCheckOverlap function */ - if (this._checkOverlapTimeoutId) { - this._checkOverlapTimeoutContinue = true; - return - } - - this._doCheckOverlap(); - - this._checkOverlapTimeoutId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, INTELLIHIDE_CHECK_INTERVAL, () => { - this._doCheckOverlap(); - if (this._checkOverlapTimeoutContinue) { - this._checkOverlapTimeoutContinue = false; - return GLib.SOURCE_CONTINUE; - } else { - this._checkOverlapTimeoutId = 0; - return GLib.SOURCE_REMOVE; - } - }); - } - - _doCheckOverlap() { - - if (!this._isEnabled || (this._targetBox == null)) - return; - - let overlaps = OverlapStatus.FALSE; - let windows = global.get_window_actors(); - - if (windows.length > 0) { - /* - * Get the top window on the monitor where the dock is placed. - * The idea is that we dont want to overlap with the windows of the topmost application, - * event is it's not the focused app -- for instance because in multimonitor the user - * select a window in the secondary monitor. - */ - - let topWindow = null; - for (let i = windows.length - 1; i >= 0; i--) { - let meta_win = windows[i].get_meta_window(); - if (this._handledWindow(windows[i]) && (meta_win.get_monitor() == this._monitorIndex)) { - topWindow = meta_win; - break; - } - } - - if (topWindow !== null) { - this._topApp = this._tracker.get_window_app(topWindow); - // If there isn't a focused app, use that of the window on top - this._focusApp = this._tracker.focus_app || this._topApp - - windows = windows.filter(this._intellihideFilterInteresting, this); - - for (let i = 0; i < windows.length; i++) { - let win = windows[i].get_meta_window(); - - if (win) { - let rect = win.get_frame_rect(); - - let test = (rect.x < this._targetBox.x2) && - (rect.x + rect.width > this._targetBox.x1) && - (rect.y < this._targetBox.y2) && - (rect.y + rect.height > this._targetBox.y1); - - if (test) { - overlaps = OverlapStatus.TRUE; - break; - } - } - } - } - } - - if (this._status !== overlaps) { - this._status = overlaps; - this.emit('status-changed', this._status); - } - - } - - // Filter interesting windows to be considered for intellihide. - // Consider all windows visible on the current workspace. - // Optionally skip windows of other applications - _intellihideFilterInteresting(wa) { - let meta_win = wa.get_meta_window(); - if (!this._handledWindow(wa)) - return false; - - let currentWorkspace = global.workspace_manager.get_active_workspace_index(); - let wksp = meta_win.get_workspace(); - let wksp_index = wksp.index(); - - // Depending on the intellihide mode, exclude non-relevent windows - switch (Docking.DockManager.settings.get_enum('intellihide-mode')) { - case IntellihideMode.ALL_WINDOWS: - // Do nothing - break; - - case IntellihideMode.FOCUS_APPLICATION_WINDOWS: - // Skip windows of other apps - if (this._focusApp) { - // The DropDownTerminal extension is not an application per se - // so we match its window by wm class instead - if (meta_win.get_wm_class() == 'DropDownTerminalWindow') - return true; - - let currentApp = this._tracker.get_window_app(meta_win); - let focusWindow = global.display.get_focus_window() - - // Consider half maximized windows side by side - // and windows which are alwayson top - if((currentApp != this._focusApp) && (currentApp != this._topApp) - && !((focusWindow && focusWindow.maximized_vertically && !focusWindow.maximized_horizontally) - && (meta_win.maximized_vertically && !meta_win.maximized_horizontally) - && meta_win.get_monitor() == focusWindow.get_monitor()) - && !meta_win.is_above()) - return false; - } - break; - - case IntellihideMode.MAXIMIZED_WINDOWS: - // Skip unmaximized windows - if (!meta_win.maximized_vertically && !meta_win.maximized_horizontally) - return false; - break; - } - - if ( wksp_index == currentWorkspace && meta_win.showing_on_its_workspace() ) - return true; - else - return false; - - } - - // Filter windows by type - // inspired by Opacify@gnome-shell.localdomain.pl - _handledWindow(wa) { - let metaWindow = wa.get_meta_window(); - - if (!metaWindow) - return false; - - // The DropDownTerminal extension uses the POPUP_MENU window type hint - // so we match its window by wm class instead - if (metaWindow.get_wm_class() == 'DropDownTerminalWindow') - return true; - - let wtype = metaWindow.get_window_type(); - for (let i = 0; i < handledWindowTypes.length; i++) { - var hwtype = handledWindowTypes[i]; - if (hwtype == wtype) - return true; - else if (hwtype > wtype) - return false; - } - return false; - } -}; - -Signals.addSignalMethods(Intellihide.prototype); diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/launcherAPI.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/launcherAPI.js deleted file mode 100644 index 55f44f7..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/launcherAPI.js +++ /dev/null @@ -1,281 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Gio = imports.gi.Gio; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const DbusmenuUtils = Me.imports.dbusmenuUtils; - -const Dbusmenu = DbusmenuUtils.haveDBusMenu(); - -var LauncherEntryRemoteModel = class DashToDock_LauncherEntryRemoteModel { - - constructor() { - this._entrySourceStacks = new Map(); - this._remoteMaps = new Map(); - - this._launcher_entry_dbus_signal_id = - Gio.DBus.session.signal_subscribe(null, // sender - 'com.canonical.Unity.LauncherEntry', // iface - 'Update', // member - null, // path - null, // arg0 - Gio.DBusSignalFlags.NONE, - (connection, sender_name, object_path, interface_name, signal_name, parameters) => - this._onUpdate(sender_name, ...parameters.deep_unpack())); - - this._dbus_name_owner_changed_signal_id = - Gio.DBus.session.signal_subscribe('org.freedesktop.DBus', // sender - 'org.freedesktop.DBus', // interface - 'NameOwnerChanged', // member - '/org/freedesktop/DBus', // path - null, // arg0 - Gio.DBusSignalFlags.NONE, - (connection, sender_name, object_path, interface_name, signal_name, parameters) => - this._onDBusNameChange(...parameters.deep_unpack().slice(1))); - - this._acquireUnityDBus(); - } - - destroy() { - if (this._launcher_entry_dbus_signal_id) { - Gio.DBus.session.signal_unsubscribe(this._launcher_entry_dbus_signal_id); - } - - if (this._dbus_name_owner_changed_signal_id) { - Gio.DBus.session.signal_unsubscribe(this._dbus_name_owner_changed_signal_id); - } - - this._releaseUnityDBus(); - } - - _lookupStackById(appId) { - let sourceStack = this._entrySourceStacks.get(appId); - if (!sourceStack) { - this._entrySourceStacks.set(appId, sourceStack = new PropertySourceStack(new LauncherEntry(), launcherEntryDefaults)); - } - return sourceStack; - } - - lookupById(appId) { - return this._lookupStackById(appId).target; - } - - _acquireUnityDBus() { - if (!this._unity_bus_id) { - this._unity_bus_id = Gio.DBus.session.own_name('com.canonical.Unity', - Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT | Gio.BusNameOwnerFlags.REPLACE, - null, () => this._unity_bus_id = 0); - } - } - - _releaseUnityDBus() { - if (this._unity_bus_id) { - Gio.DBus.session.unown_name(this._unity_bus_id); - this._unity_bus_id = 0; - } - } - - _onDBusNameChange(before, after) { - if (!before || !this._remoteMaps.size) { - return; - } - const remoteMap = this._remoteMaps.get(before); - if (!remoteMap) { - return; - } - this._remoteMaps.delete(before); - if (after && !this._remoteMaps.has(after)) { - this._remoteMaps.set(after, remoteMap); - } else { - for (const [appId, remote] of remoteMap) { - const sourceStack = this._entrySourceStacks.get(appId); - const changed = sourceStack.remove(remote); - if (changed) { - sourceStack.target._emitChangedEvents(changed); - } - } - } - } - - _onUpdate(senderName, appUri, properties) { - if (!senderName) { - return; - } - - const appId = appUri.replace(/(^\w+:|^)\/\//, ''); - if (!appId) { - return; - } - - let remoteMap = this._remoteMaps.get(senderName); - if (!remoteMap) { - this._remoteMaps.set(senderName, remoteMap = new Map()); - } - let remote = remoteMap.get(appId); - if (!remote) { - remoteMap.set(appId, remote = Object.assign({}, launcherEntryDefaults)); - } - for (const name in properties) { - if (name === 'quicklist' && Dbusmenu) { - const quicklistPath = properties[name].unpack(); - if (quicklistPath && (!remote._quicklistMenuClient || remote._quicklistMenuClient.dbus_object !== quicklistPath)) { - remote.quicklist = null; - let menuClient = remote._quicklistMenuClient; - if (menuClient) { - menuClient.dbus_object = quicklistPath; - } else { - // This property should not be enumerable - Object.defineProperty(remote, '_quicklistMenuClient', { - writable: true, - value: menuClient = new Dbusmenu.Client({ dbus_name: senderName, dbus_object: quicklistPath }), - }); - } - const handler = () => { - const root = menuClient.get_root(); - if (remote.quicklist !== root) { - remote.quicklist = root; - if (sourceStack.isTop(remote)) { - sourceStack.target.quicklist = root; - sourceStack.target._emitChangedEvents(['quicklist']); - } - } - }; - menuClient.connect(Dbusmenu.CLIENT_SIGNAL_ROOT_CHANGED, handler); - } - } else { - remote[name] = properties[name].unpack(); - } - } - - const sourceStack = this._lookupStackById(appId); - sourceStack.target._emitChangedEvents(sourceStack.update(remote)); - } -}; - -const launcherEntryDefaults = { - count: 0, - progress: 0, - urgent: false, - quicklist: null, - 'count-visible': false, - 'progress-visible': false, -}; - -const LauncherEntry = class DashToDock_LauncherEntry { - constructor() { - this._connections = new Map(); - this._handlers = new Map(); - this._nextId = 0; - } - - connect(eventNames, callback) { - if (typeof eventNames === 'string') { - eventNames = [eventNames]; - } - callback(this, this); - const id = this._nextId++; - const handler = { id, callback }; - eventNames.forEach(name => { - let handlerList = this._handlers.get(name); - if (!handlerList) { - this._handlers.set(name, handlerList = []); - } - handlerList.push(handler); - }); - this._connections.set(id, eventNames); - return id; - } - - disconnect(id) { - const eventNames = this._connections.get(id); - if (!eventNames) { - return; - } - this._connections.delete(id); - eventNames.forEach(name => { - const handlerList = this._handlers.get(name); - if (handlerList) { - for (let i = 0, iMax = handlerList.length; i < iMax; i++) { - if (handlerList[i].id === id) { - handlerList.splice(i, 1); - break; - } - } - } - }); - } - - _emitChangedEvents(propertyNames) { - const handlers = new Set(); - propertyNames.forEach(name => { - const handlerList = this._handlers.get(name + '-changed'); - if (handlerList) { - for (let i = 0, iMax = handlerList.length; i < iMax; i++) { - handlers.add(handlerList[i]); - } - } - }); - Array.from(handlers).sort((x, y) => x.id - y.id).forEach(handler => handler.callback(this, this)); - } -} - -for (const name in launcherEntryDefaults) { - const jsName = name.replace(/-/g, '_'); - LauncherEntry.prototype[jsName] = launcherEntryDefaults[name]; - if (jsName !== name) { - Object.defineProperty(LauncherEntry.prototype, name, { - get() { - return this[jsName]; - }, - set(value) { - this[jsName] = value; - }, - }); - } -} - -const PropertySourceStack = class DashToDock_PropertySourceStack { - constructor(target, bottom) { - this.target = target; - this._bottom = bottom; - this._stack = []; - } - - isTop(source) { - return this._stack.length > 0 && this._stack[this._stack.length - 1] === source; - } - - update(source) { - if (!this.isTop(source)) { - this.remove(source); - this._stack.push(source); - } - return this._assignFrom(source); - } - - remove(source) { - const stack = this._stack; - const top = stack[stack.length - 1]; - if (top === source) { - stack.length--; - return this._assignFrom(stack.length > 0 ? stack[stack.length - 1] : this._bottom); - } - for (let i = 0, iMax = stack.length; i < iMax; i++) { - if (stack[i] === source) { - stack.splice(i, 1); - break; - } - } - } - - _assignFrom(source) { - const changedProperties = []; - for (const name in source) { - if (this.target[name] !== source[name]) { - this.target[name] = source[name]; - changedProperties.push(name); - } - } - return changedProperties; - } -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ar/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ar/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 78deaa5..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ar/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/cs/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/cs/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 1cc799d..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/cs/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/de/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/de/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index f7b2ed5..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/de/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/el/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/el/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index b116119..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/el/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/es/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/es/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 99888b0..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/es/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/eu/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/eu/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 03fec78..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/eu/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/fr/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/fr/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index a9a712c..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/fr/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/gl/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/gl/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index b89c102..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/gl/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/hu/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/hu/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 6e2d85e..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/hu/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/id/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/id/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 950b3ff..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/id/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/it/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/it/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index fc1f722..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/it/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ja/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ja/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 9b9b943..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ja/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/nb/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/nb/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 005884f..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/nb/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/nl/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/nl/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 91063e8..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/nl/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pl/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pl/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index c9d87d9..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pl/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pt/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pt/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index b298694..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pt/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pt_BR/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pt_BR/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index cbe7c66..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/pt_BR/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ru/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ru/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 0c187f3..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/ru/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sk/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sk/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 5b25bec..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sk/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sr/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sr/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index da3e086..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sr/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sr@latin/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sr@latin/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 1fcfb47..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sr@latin/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sv/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sv/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index bab036e..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/sv/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/tr/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/tr/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index b2e36b6..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/tr/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/uk_UA/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/uk_UA/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index a475c96..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/uk_UA/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/zh_CN/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/zh_CN/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 8ebfc33..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/zh_CN/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/zh_TW/LC_MESSAGES/dashtodock.mo b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/zh_TW/LC_MESSAGES/dashtodock.mo deleted file mode 100644 index 3ca257a..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locale/zh_TW/LC_MESSAGES/dashtodock.mo and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locations.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locations.js deleted file mode 100644 index 9dae93f..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/locations.js +++ /dev/null @@ -1,293 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const Gtk = imports.gi.Gtk; -const Shell = imports.gi.Shell; -const Signals = imports.signals; - -// Use __ () and N__() for the extension gettext domain, and reuse -// the shell domain with the default _() and N_() -const Gettext = imports.gettext.domain('dashtodock'); -const __ = Gettext.gettext; -const N__ = function(e) { return e }; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Utils = Me.imports.utils; - -const UPDATE_TRASH_DELAY = 500; - -/** - * This class maintains a Shell.App representing the Trash and keeps it - * up-to-date as the trash fills and is emptied over time. - */ -var Trash = class DashToDock_Trash { - - constructor() { - this._file = Gio.file_new_for_uri('trash://'); - try { - this._monitor = this._file.monitor_directory(0, null); - this._signalId = this._monitor.connect( - 'changed', - this._onTrashChange.bind(this) - ); - } catch (e) { - log(`Impossible to monitor trash: ${e}`) - } - this._lastEmpty = true; - this._empty = true; - this._schedUpdateId = 0; - this._updateTrash(); - } - - destroy() { - if (this._monitor) { - this._monitor.disconnect(this._signalId); - this._monitor.run_dispose(); - } - this._file.run_dispose(); - } - - _onTrashChange() { - if (this._schedUpdateId) { - GLib.source_remove(this._schedUpdateId); - } - this._schedUpdateId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, UPDATE_TRASH_DELAY, () => { - this._schedUpdateId = 0; - this._updateTrash(); - return GLib.SOURCE_REMOVE; - }); - } - - _updateTrash() { - try { - let children = this._file.enumerate_children('*', 0, null); - this._empty = children.next_file(null) == null; - children.close(null); - } catch (e) { - log(`Impossible to enumerate trash children: ${e}`) - return; - } - - this._ensureApp(); - } - - _ensureApp() { - if (this._trashApp == null || - this._lastEmpty != this._empty) { - let trashKeys = new GLib.KeyFile(); - trashKeys.set_string('Desktop Entry', 'Name', __('Trash')); - trashKeys.set_string('Desktop Entry', 'Icon', - this._empty ? 'user-trash' : 'user-trash-full'); - trashKeys.set_string('Desktop Entry', 'Type', 'Application'); - trashKeys.set_string('Desktop Entry', 'Exec', 'gio open trash:///'); - trashKeys.set_string('Desktop Entry', 'StartupNotify', 'false'); - trashKeys.set_string('Desktop Entry', 'XdtdUri', 'trash:///'); - if (!this._empty) { - trashKeys.set_string('Desktop Entry', 'Actions', 'empty-trash;'); - trashKeys.set_string('Desktop Action empty-trash', 'Name', __('Empty Trash')); - trashKeys.set_string('Desktop Action empty-trash', 'Exec', - 'dbus-send --print-reply --dest=org.gnome.Nautilus /org/gnome/Nautilus org.gnome.Nautilus.FileOperations.EmptyTrash'); - } - - let trashAppInfo = Gio.DesktopAppInfo.new_from_keyfile(trashKeys); - this._trashApp = new Shell.App({appInfo: trashAppInfo}); - this._lastEmpty = this._empty; - - this.emit('changed'); - } - } - - getApp() { - this._ensureApp(); - return this._trashApp; - } -} -Signals.addSignalMethods(Trash.prototype); - -/** - * This class maintains Shell.App representations for removable devices - * plugged into the system, and keeps the list of Apps up-to-date as - * devices come and go and are mounted and unmounted. - */ -var Removables = class DashToDock_Removables { - - constructor() { - this._signalsHandler = new Utils.GlobalSignalsHandler(); - - this._monitor = Gio.VolumeMonitor.get(); - this._volumeApps = [] - this._mountApps = [] - - this._monitor.get_volumes().forEach( - (volume) => { - this._onVolumeAdded(this._monitor, volume); - } - ); - - this._monitor.get_mounts().forEach( - (mount) => { - this._onMountAdded(this._monitor, mount); - } - ); - - this._signalsHandler.add([ - this._monitor, - 'mount-added', - this._onMountAdded.bind(this) - ], [ - this._monitor, - 'mount-removed', - this._onMountRemoved.bind(this) - ], [ - this._monitor, - 'volume-added', - this._onVolumeAdded.bind(this) - ], [ - this._monitor, - 'volume-removed', - this._onVolumeRemoved.bind(this) - ]); - } - - destroy() { - this._signalsHandler.destroy(); - this._monitor.run_dispose(); - } - - _getWorkingIconName(icon) { - if (icon instanceof Gio.EmblemedIcon) { - icon = icon.get_icon(); - } - if (icon instanceof Gio.ThemedIcon) { - let iconTheme = Gtk.IconTheme.get_default(); - let names = icon.get_names(); - for (let i = 0; i < names.length; i++) { - let iconName = names[i]; - if (iconTheme.has_icon(iconName)) { - return iconName; - } - } - return ''; - } else { - return icon.to_string(); - } - } - - _onVolumeAdded(monitor, volume) { - if (!volume.can_mount()) { - return; - } - - if (volume.get_identifier('class') == 'network') { - return; - } - - let activationRoot = volume.get_activation_root(); - if (!activationRoot) { - // Can't offer to mount a device if we don't know - // where to mount it. - // These devices are usually ejectable so you - // don't normally unmount them anyway. - return; - } - - let escapedUri = activationRoot.get_uri() - let uri = GLib.uri_unescape_string(escapedUri, null); - - let volumeKeys = new GLib.KeyFile(); - volumeKeys.set_string('Desktop Entry', 'Name', volume.get_name()); - volumeKeys.set_string('Desktop Entry', 'Icon', this._getWorkingIconName(volume.get_icon())); - volumeKeys.set_string('Desktop Entry', 'Type', 'Application'); - volumeKeys.set_string('Desktop Entry', 'Exec', 'gio open "' + uri + '"'); - volumeKeys.set_string('Desktop Entry', 'StartupNotify', 'false'); - volumeKeys.set_string('Desktop Entry', 'XdtdUri', escapedUri); - volumeKeys.set_string('Desktop Entry', 'Actions', 'mount;'); - volumeKeys.set_string('Desktop Action mount', 'Name', __('Mount')); - volumeKeys.set_string('Desktop Action mount', 'Exec', 'gio mount "' + uri + '"'); - let volumeAppInfo = Gio.DesktopAppInfo.new_from_keyfile(volumeKeys); - let volumeApp = new Shell.App({appInfo: volumeAppInfo}); - this._volumeApps.push(volumeApp); - this.emit('changed'); - } - - _onVolumeRemoved(monitor, volume) { - for (let i = 0; i < this._volumeApps.length; i++) { - let app = this._volumeApps[i]; - if (app.get_name() == volume.get_name()) { - this._volumeApps.splice(i, 1); - } - } - this.emit('changed'); - } - - _onMountAdded(monitor, mount) { - // Filter out uninteresting mounts - if (!mount.can_eject() && !mount.can_unmount()) - return; - if (mount.is_shadowed()) - return; - - let volume = mount.get_volume(); - if (!volume || volume.get_identifier('class') == 'network') { - return; - } - - let escapedUri = mount.get_root().get_uri() - let uri = GLib.uri_unescape_string(escapedUri, null); - - let mountKeys = new GLib.KeyFile(); - mountKeys.set_string('Desktop Entry', 'Name', mount.get_name()); - mountKeys.set_string('Desktop Entry', 'Icon', - this._getWorkingIconName(volume.get_icon())); - mountKeys.set_string('Desktop Entry', 'Type', 'Application'); - mountKeys.set_string('Desktop Entry', 'Exec', 'gio open "' + uri + '"'); - mountKeys.set_string('Desktop Entry', 'StartupNotify', 'false'); - mountKeys.set_string('Desktop Entry', 'XdtdUri', escapedUri); - mountKeys.set_string('Desktop Entry', 'Actions', 'unmount;'); - if (mount.can_eject()) { - mountKeys.set_string('Desktop Action unmount', 'Name', __('Eject')); - mountKeys.set_string('Desktop Action unmount', 'Exec', - 'gio mount -e "' + uri + '"'); - } else { - mountKeys.set_string('Desktop Entry', 'Actions', 'unmount;'); - mountKeys.set_string('Desktop Action unmount', 'Name', __('Unmount')); - mountKeys.set_string('Desktop Action unmount', 'Exec', - 'gio mount -u "' + uri + '"'); - } - let mountAppInfo = Gio.DesktopAppInfo.new_from_keyfile(mountKeys); - let mountApp = new Shell.App({appInfo: mountAppInfo}); - this._mountApps.push(mountApp); - this.emit('changed'); - } - - _onMountRemoved(monitor, mount) { - for (let i = 0; i < this._mountApps.length; i++) { - let app = this._mountApps[i]; - if (app.get_name() == mount.get_name()) { - this._mountApps.splice(i, 1); - } - } - this.emit('changed'); - } - - getApps() { - // When we have both a volume app and a mount app, we prefer - // the mount app. - let apps = new Map(); - this._volumeApps.map(function(app) { - apps.set(app.get_name(), app); - }); - this._mountApps.map(function(app) { - apps.set(app.get_name(), app); - }); - - let ret = []; - for (let app of apps.values()) { - ret.push(app); - } - return ret; - } -} -Signals.addSignalMethods(Removables.prototype); diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/glossy.svg b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/glossy.svg deleted file mode 100644 index 55b71ba..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/glossy.svg +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/highlight_stacked_bg.svg b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/highlight_stacked_bg.svg deleted file mode 100644 index 19be5a9..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/highlight_stacked_bg.svg +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/highlight_stacked_bg_h.svg b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/highlight_stacked_bg_h.svg deleted file mode 100644 index eeaa869..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/highlight_stacked_bg_h.svg +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/logo.svg b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/logo.svg deleted file mode 100644 index eebd0b1..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/media/logo.svg +++ /dev/null @@ -1,528 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dash to Dock - Michele - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/metadata.json b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/metadata.json deleted file mode 100644 index fadda6a..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/metadata.json +++ /dev/null @@ -1,12 +0,0 @@ -{ -"shell-version": [ - "40" -], -"uuid": "dash-to-dock@micxgx.gmail.com", -"name": "Dash to Dock", -"description": "A dock for the Gnome Shell. This extension moves the dash out of the overview transforming it in a dock for an easier launching of applications and a faster switching between windows and desktops. Side and bottom placement options are available.", -"original-author": "micxgx@gmail.com", -"url": "https://micheleg.github.io/dash-to-dock/", -"gettext-domain": "dashtodock", -"version": 69 -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/prefs.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/prefs.js deleted file mode 100644 index 88c6df4..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/prefs.js +++ /dev/null @@ -1,838 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Gdk = imports.gi.Gdk; - -// Use __ () and N__() for the extension gettext domain, and reuse -// the shell domain with the default _() and N_() -const Gettext = imports.gettext.domain('dashtodock'); -const __ = Gettext.gettext; -const N__ = function (e) { return e }; - -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); - -const SCALE_UPDATE_TIMEOUT = 500; -const DEFAULT_ICONS_SIZES = [128, 96, 64, 48, 32, 24, 16]; - -const TransparencyMode = { - DEFAULT: 0, - FIXED: 1, - DYNAMIC: 3 -}; - -const RunningIndicatorStyle = { - DEFAULT: 0, - DOTS: 1, - SQUARES: 2, - DASHES: 3, - SEGMENTED: 4, - SOLID: 5, - CILIORA: 6, - METRO: 7 -}; - -// TODO: -// function setShortcut(settings) { -// let shortcut_text = settings.get_string('shortcut-text'); -// let [key, mods] = Gtk.accelerator_parse(shortcut_text); - -// if (Gtk.accelerator_valid(key, mods)) { -// let shortcut = Gtk.accelerator_name(key, mods); -// settings.set_strv('shortcut', [shortcut]); -// } -// else { -// settings.set_strv('shortcut', []); -// } -// } - -var Settings = GObject.registerClass({ - Implements: [Gtk.BuilderScope], -}, class DashToDock_Settings extends GObject.Object { - - _init() { - super._init(); - - this._settings = ExtensionUtils.getSettings('org.gnome.shell.extensions.dash-to-dock'); - - this._rtl = (Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL); - - this._builder = new Gtk.Builder(); - this._builder.set_scope(this); - this._builder.set_translation_domain(Me.metadata['gettext-domain']); - this._builder.add_from_file(Me.path + '/Settings.ui'); - - this.widget = new Gtk.ScrolledWindow({ hscrollbar_policy: Gtk.PolicyType.NEVER }); - this._notebook = this._builder.get_object('settings_notebook'); - this.widget.set_child(this._notebook); - - // Timeout to delay the update of the settings - this._dock_size_timeout = 0; - this._icon_size_timeout = 0; - this._opacity_timeout = 0; - - this._bindSettings(); - } - - vfunc_create_closure(builder, handlerName, flags, connectObject) { - if (flags & Gtk.BuilderClosureFlags.SWAPPED) - throw new Error('Unsupported template signal flag "swapped"'); - - if (typeof this[handlerName] === 'undefined') - throw new Error(`${handlerName} is undefined`); - - return this[handlerName].bind(connectObject || this); - } - - dock_display_combo_changed_cb(combo) { - this._settings.set_int('preferred-monitor', this._monitors[combo.get_active()]); - } - - position_top_button_toggled_cb(button) { - if (button.get_active()) - this._settings.set_enum('dock-position', 0); - } - - position_right_button_toggled_cb(button) { - if (button.get_active()) - this._settings.set_enum('dock-position', 1); - } - - position_bottom_button_toggled_cb(button) { - if (button.get_active()) - this._settings.set_enum('dock-position', 2); - } - - position_left_button_toggled_cb(button) { - if (button.get_active()) - this._settings.set_enum('dock-position', 3); - } - - icon_size_combo_changed_cb(combo) { - this._settings.set_int('dash-max-icon-size', this._allIconSizes[combo.get_active()]); - } - - dock_size_scale_value_changed_cb(scale) { - // Avoid settings the size continuously - if (this._dock_size_timeout > 0) - GLib.source_remove(this._dock_size_timeout); - const id = this._dock_size_timeout = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, SCALE_UPDATE_TIMEOUT, () => { - if (id === this._dock_size_timeout) { - this._settings.set_double('height-fraction', scale.get_value()); - this._dock_size_timeout = 0; - return GLib.SOURCE_REMOVE; - } - }); - } - - icon_size_scale_value_changed_cb(scale) { - // Avoid settings the size consinuosly - if (this._icon_size_timeout > 0) - GLib.source_remove(this._icon_size_timeout); - this._icon_size_timeout = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, SCALE_UPDATE_TIMEOUT, () => { - log(scale.get_value()); - this._settings.set_int('dash-max-icon-size', scale.get_value()); - this._icon_size_timeout = 0; - return GLib.SOURCE_REMOVE; - }); - } - custom_opacity_scale_value_changed_cb(scale) { - // Avoid settings the opacity consinuosly as it's change is animated - if (this._opacity_timeout > 0) - GLib.source_remove(this._opacity_timeout); - this._opacity_timeout = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, SCALE_UPDATE_TIMEOUT, () => { - this._settings.set_double('background-opacity', scale.get_value()); - this._opacity_timeout = 0; - return GLib.SOURCE_REMOVE; - }); - } - min_opacity_scale_value_changed_cb(scale) { - // Avoid settings the opacity consinuosly as it's change is animated - if (this._opacity_timeout > 0) - GLib.source_remove(this._opacity_timeout); - this._opacity_timeout = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, SCALE_UPDATE_TIMEOUT, () => { - this._settings.set_double('min-alpha', scale.get_value()); - this._opacity_timeout = 0; - return GLib.SOURCE_REMOVE; - }); - } - max_opacity_scale_value_changed_cb(scale) { - // Avoid settings the opacity consinuosly as it's change is animated - if (this._opacity_timeout > 0) - GLib.source_remove(this._opacity_timeout); - this._opacity_timeout = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, SCALE_UPDATE_TIMEOUT, () => { - this._settings.set_double('max-alpha', scale.get_value()); - this._opacity_timeout = 0; - return GLib.SOURCE_REMOVE; - }); - } - - all_windows_radio_button_toggled_cb(button) { - if (button.get_active()) - this._settings.set_enum('intellihide-mode', 0); - } - focus_application_windows_radio_button_toggled_cb(button) { - if (button.get_active()) - this._settings.set_enum('intellihide-mode', 1); - } - maximized_windows_radio_button_toggled_cb(button) { - if (button.get_active()) - this._settings.set_enum('intellihide-mode', 2); - } - - - _bindSettings() { - // Position and size panel - - // Monitor options - - this._monitors = []; - // Build options based on the number of monitors and the current settings. - let monitors = Gdk.Display.get_default().get_monitors(); - let n_monitors = monitors.length; - let primary_monitor = 0; // Gdk.Screen.get_default().get_primary_monitor(); - - let monitor = this._settings.get_int('preferred-monitor'); - - // Add primary monitor with index 0, because in GNOME Shell the primary monitor is always 0 - this._builder.get_object('dock_monitor_combo').append_text(__('Primary monitor')); - this._monitors.push(0); - - // Add connected monitors - let ctr = 0; - for (let i = 0; i < n_monitors; i++) { - if (i !== primary_monitor) { - ctr++; - this._monitors.push(ctr); - this._builder.get_object('dock_monitor_combo').append_text(__('Secondary monitor ') + ctr); - } - } - - // If one of the external monitor is set as preferred, show it even if not attached - if ((monitor >= n_monitors) && (monitor !== primary_monitor)) { - this._monitors.push(monitor) - this._builder.get_object('dock_monitor_combo').append_text(__('Secondary monitor ') + ++ctr); - } - - this._builder.get_object('dock_monitor_combo').set_active(this._monitors.indexOf(monitor)); - - // Position option - let position = this._settings.get_enum('dock-position'); - - switch (position) { - case 0: - this._builder.get_object('position_top_button').set_active(true); - break; - case 1: - this._builder.get_object('position_right_button').set_active(true); - break; - case 2: - this._builder.get_object('position_bottom_button').set_active(true); - break; - case 3: - this._builder.get_object('position_left_button').set_active(true); - break; - } - - if (this._rtl) { - /* Left is Right in rtl as a setting */ - this._builder.get_object('position_left_button').set_label(__('Right')); - this._builder.get_object('position_right_button').set_label(__('Left')); - } - - // Intelligent autohide options - this._settings.bind('dock-fixed', - this._builder.get_object('intelligent_autohide_switch'), - 'active', - Gio.SettingsBindFlags.INVERT_BOOLEAN); - this._settings.bind('dock-fixed', - this._builder.get_object('intelligent_autohide_button'), - 'sensitive', - Gio.SettingsBindFlags.INVERT_BOOLEAN); - this._settings.bind('autohide', - this._builder.get_object('autohide_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('autohide-in-fullscreen', - this._builder.get_object('autohide_enable_in_fullscreen_checkbutton'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('require-pressure-to-show', - this._builder.get_object('require_pressure_checkbutton'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('intellihide', - this._builder.get_object('intellihide_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('animation-time', - this._builder.get_object('animation_duration_spinbutton'), - 'value', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('hide-delay', - this._builder.get_object('hide_timeout_spinbutton'), - 'value', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-delay', - this._builder.get_object('show_timeout_spinbutton'), - 'value', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('pressure-threshold', - this._builder.get_object('pressure_threshold_spinbutton'), - 'value', - Gio.SettingsBindFlags.DEFAULT); - - //this._builder.get_object('animation_duration_spinbutton').set_value(this._settings.get_double('animation-time')); - - // Create dialog for intelligent autohide advanced settings - this._builder.get_object('intelligent_autohide_button').connect('clicked', () => { - - let dialog = new Gtk.Dialog({ - title: __('Intelligent autohide customization'), - transient_for: this.widget.get_root(), - use_header_bar: true, - modal: true - }); - - // GTK+ leaves positive values for application-defined response ids. - // Use +1 for the reset action - dialog.add_button(__('Reset to defaults'), 1); - - let box = this._builder.get_object('intelligent_autohide_advanced_settings_box'); - dialog.get_content_area().append(box); - - this._settings.bind('intellihide', - this._builder.get_object('intellihide_mode_box'), - 'sensitive', - Gio.SettingsBindFlags.GET); - - // intellihide mode - - let intellihideModeRadioButtons = [ - this._builder.get_object('all_windows_radio_button'), - this._builder.get_object('focus_application_windows_radio_button'), - this._builder.get_object('maximized_windows_radio_button') - ]; - - intellihideModeRadioButtons[this._settings.get_enum('intellihide-mode')].set_active(true); - - this._settings.bind('autohide', - this._builder.get_object('require_pressure_checkbutton'), - 'sensitive', - Gio.SettingsBindFlags.GET); - - this._settings.bind('autohide', - this._builder.get_object('autohide_enable_in_fullscreen_checkbutton'), - 'sensitive', - Gio.SettingsBindFlags.GET); - - this._settings.bind('require-pressure-to-show', - this._builder.get_object('show_timeout_spinbutton'), - 'sensitive', - Gio.SettingsBindFlags.INVERT_BOOLEAN); - this._settings.bind('require-pressure-to-show', - this._builder.get_object('show_timeout_label'), - 'sensitive', - Gio.SettingsBindFlags.INVERT_BOOLEAN); - this._settings.bind('require-pressure-to-show', - this._builder.get_object('pressure_threshold_spinbutton'), - 'sensitive', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('require-pressure-to-show', - this._builder.get_object('pressure_threshold_label'), - 'sensitive', - Gio.SettingsBindFlags.DEFAULT); - - dialog.connect('response', (dialog, id) => { - if (id == 1) { - // restore default settings for the relevant keys - let keys = ['intellihide', 'autohide', 'intellihide-mode', 'autohide-in-fullscreen', 'require-pressure-to-show', - 'animation-time', 'show-delay', 'hide-delay', 'pressure-threshold']; - keys.forEach(function (val) { - this._settings.set_value(val, this._settings.get_default_value(val)); - }, this); - intellihideModeRadioButtons[this._settings.get_enum('intellihide-mode')].set_active(true); - } else { - // remove the settings box so it doesn't get destroyed; - dialog.get_content_area().remove(box); - dialog.destroy(); - } - return; - }); - - dialog.present(); - - }); - - // size options - const dock_size_scale = this._builder.get_object('dock_size_scale'); - dock_size_scale.set_value(this._settings.get_double('height-fraction')); - dock_size_scale.add_mark(0.9, Gtk.PositionType.TOP, null); - dock_size_scale.set_format_value_func((_, value) => { - return Math.round(value * 100) + ' %'; - }); - let icon_size_scale = this._builder.get_object('icon_size_scale'); - icon_size_scale.set_range(8, DEFAULT_ICONS_SIZES[0]); - icon_size_scale.set_value(this._settings.get_int('dash-max-icon-size')); - DEFAULT_ICONS_SIZES.forEach(function (val) { - icon_size_scale.add_mark(val, Gtk.PositionType.TOP, val.toString()); - }); - icon_size_scale.set_format_value_func((_, value) => { - return value + ' px'; - }); - - // Corrent for rtl languages - if (this._rtl) { - // Flip value position: this is not done automatically - dock_size_scale.set_value_pos(Gtk.PositionType.LEFT); - icon_size_scale.set_value_pos(Gtk.PositionType.LEFT); - // I suppose due to a bug, having a more than one mark and one above a value of 100 - // makes the rendering of the marks wrong in rtl. This doesn't happen setting the scale as not flippable - // and then manually inverting it - icon_size_scale.set_flippable(false); - icon_size_scale.set_inverted(true); - } - - this._settings.bind('icon-size-fixed', this._builder.get_object('icon_size_fixed_checkbutton'), 'active', Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('extend-height', this._builder.get_object('dock_size_extend_checkbutton'), 'active', Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('extend-height', this._builder.get_object('dock_size_scale'), 'sensitive', Gio.SettingsBindFlags.INVERT_BOOLEAN); - - - // Apps panel - - this._settings.bind('show-running', - this._builder.get_object('show_running_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('isolate-workspaces', - this._builder.get_object('application_button_isolation_button'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('isolate-monitors', - this._builder.get_object('application_button_monitor_isolation_button'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-windows-preview', - this._builder.get_object('windows_preview_button'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('multi-monitor', - this._builder.get_object('multi_monitor_button'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-favorites', - this._builder.get_object('show_favorite_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-trash', - this._builder.get_object('show_trash_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-mounts', - this._builder.get_object('show_mounts_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-show-apps-button', - this._builder.get_object('show_applications_button_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-apps-at-top', - this._builder.get_object('application_button_first_button'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-show-apps-button', - this._builder.get_object('application_button_first_button'), - 'sensitive', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('animate-show-apps', - this._builder.get_object('application_button_animation_button'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('show-show-apps-button', - this._builder.get_object('application_button_animation_button'), - 'sensitive', - Gio.SettingsBindFlags.DEFAULT); - - - // Behavior panel - - this._settings.bind('hot-keys', - this._builder.get_object('hot_keys_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('hot-keys', - this._builder.get_object('overlay_button'), - 'sensitive', - Gio.SettingsBindFlags.DEFAULT); - - this._builder.get_object('click_action_combo').set_active(this._settings.get_enum('click-action')); - this._builder.get_object('click_action_combo').connect('changed', (widget) => { - this._settings.set_enum('click-action', widget.get_active()); - }); - - this._builder.get_object('scroll_action_combo').set_active(this._settings.get_enum('scroll-action')); - this._builder.get_object('scroll_action_combo').connect('changed', (widget) => { - this._settings.set_enum('scroll-action', widget.get_active()); - }); - - this._builder.get_object('shift_click_action_combo').connect('changed', (widget) => { - this._settings.set_enum('shift-click-action', widget.get_active()); - }); - - this._builder.get_object('middle_click_action_combo').connect('changed', (widget) => { - this._settings.set_enum('middle-click-action', widget.get_active()); - }); - this._builder.get_object('shift_middle_click_action_combo').connect('changed', (widget) => { - this._settings.set_enum('shift-middle-click-action', widget.get_active()); - }); - - // Create dialog for number overlay options - this._builder.get_object('overlay_button').connect('clicked', () => { - - let dialog = new Gtk.Dialog({ - title: __('Show dock and application numbers'), - transient_for: this.widget.get_root(), - use_header_bar: true, - modal: true - }); - - // GTK+ leaves positive values for application-defined response ids. - // Use +1 for the reset action - dialog.add_button(__('Reset to defaults'), 1); - - let box = this._builder.get_object('box_overlay_shortcut'); - dialog.get_content_area().append(box); - - this._builder.get_object('overlay_switch').set_active(this._settings.get_boolean('hotkeys-overlay')); - this._builder.get_object('show_dock_switch').set_active(this._settings.get_boolean('hotkeys-show-dock')); - - // We need to update the shortcut 'strv' when the text is modified - this._settings.connect('changed::shortcut-text', () => { setShortcut(this._settings); }); - this._settings.bind('shortcut-text', - this._builder.get_object('shortcut_entry'), - 'text', - Gio.SettingsBindFlags.DEFAULT); - - this._settings.bind('hotkeys-overlay', - this._builder.get_object('overlay_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('hotkeys-show-dock', - this._builder.get_object('show_dock_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('shortcut-timeout', - this._builder.get_object('timeout_spinbutton'), - 'value', - Gio.SettingsBindFlags.DEFAULT); - - dialog.connect('response', (dialog, id) => { - if (id == 1) { - // restore default settings for the relevant keys - let keys = ['shortcut-text', 'hotkeys-overlay', 'hotkeys-show-dock', 'shortcut-timeout']; - keys.forEach(function (val) { - this._settings.set_value(val, this._settings.get_default_value(val)); - }, this); - } else { - // remove the settings box so it doesn't get destroyed; - dialog.get_content_area().remove(box); - dialog.destroy(); - } - return; - }); - - dialog.present(); - }); - - // Create dialog for middle-click options - this._builder.get_object('middle_click_options_button').connect('clicked', () => { - - let dialog = new Gtk.Dialog({ - title: __('Customize middle-click behavior'), - transient_for: this.widget.get_root(), - use_header_bar: true, - modal: true - }); - - // GTK+ leaves positive values for application-defined response ids. - // Use +1 for the reset action - dialog.add_button(__('Reset to defaults'), 1); - - let box = this._builder.get_object('box_middle_click_options'); - dialog.get_content_area().append(box); - - this._builder.get_object('shift_click_action_combo').set_active(this._settings.get_enum('shift-click-action')); - - this._builder.get_object('middle_click_action_combo').set_active(this._settings.get_enum('middle-click-action')); - - this._builder.get_object('shift_middle_click_action_combo').set_active(this._settings.get_enum('shift-middle-click-action')); - - this._settings.bind('shift-click-action', - this._builder.get_object('shift_click_action_combo'), - 'active-id', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('middle-click-action', - this._builder.get_object('middle_click_action_combo'), - 'active-id', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('shift-middle-click-action', - this._builder.get_object('shift_middle_click_action_combo'), - 'active-id', - Gio.SettingsBindFlags.DEFAULT); - - dialog.connect('response', (dialog, id) => { - if (id == 1) { - // restore default settings for the relevant keys - let keys = ['shift-click-action', 'middle-click-action', 'shift-middle-click-action']; - keys.forEach(function (val) { - this._settings.set_value(val, this._settings.get_default_value(val)); - }, this); - this._builder.get_object('shift_click_action_combo').set_active(this._settings.get_enum('shift-click-action')); - this._builder.get_object('middle_click_action_combo').set_active(this._settings.get_enum('middle-click-action')); - this._builder.get_object('shift_middle_click_action_combo').set_active(this._settings.get_enum('shift-middle-click-action')); - } else { - // remove the settings box so it doesn't get destroyed; - dialog.get_content_area().remove(box); - dialog.destroy(); - } - return; - }); - - dialog.present(); - - }); - - // Appearance Panel - - this._settings.bind('apply-custom-theme', this._builder.get_object('customize_theme'), 'sensitive', Gio.SettingsBindFlags.INVERT_BOOLEAN | Gio.SettingsBindFlags.GET); - this._settings.bind('apply-custom-theme', this._builder.get_object('builtin_theme_switch'), 'active', Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('custom-theme-shrink', this._builder.get_object('shrink_dash_switch'), 'active', Gio.SettingsBindFlags.DEFAULT); - - // Running indicators - this._builder.get_object('running_indicators_combo').set_active( - this._settings.get_enum('running-indicator-style') - ); - this._builder.get_object('running_indicators_combo').connect( - 'changed', - (widget) => { - this._settings.set_enum('running-indicator-style', widget.get_active()); - } - ); - - if (this._settings.get_enum('running-indicator-style') == RunningIndicatorStyle.DEFAULT) - this._builder.get_object('running_indicators_advance_settings_button').set_sensitive(false); - - this._settings.connect('changed::running-indicator-style', () => { - if (this._settings.get_enum('running-indicator-style') == RunningIndicatorStyle.DEFAULT) - this._builder.get_object('running_indicators_advance_settings_button').set_sensitive(false); - else - this._builder.get_object('running_indicators_advance_settings_button').set_sensitive(true); - }); - - // Create dialog for running indicators advanced settings - this._builder.get_object('running_indicators_advance_settings_button').connect('clicked', () => { - - let dialog = new Gtk.Dialog({ - title: __('Customize running indicators'), - transient_for: this.widget.get_root(), - use_header_bar: true, - modal: true - }); - - let box = this._builder.get_object('running_dots_advance_settings_box'); - dialog.get_content_area().append(box); - - this._settings.bind('running-indicator-dominant-color', - this._builder.get_object('dominant_color_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - - this._settings.bind('custom-theme-customize-running-dots', - this._builder.get_object('dot_style_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('custom-theme-customize-running-dots', - this._builder.get_object('dot_style_settings_box'), - 'sensitive', Gio.SettingsBindFlags.DEFAULT); - - let rgba = new Gdk.RGBA(); - rgba.parse(this._settings.get_string('custom-theme-running-dots-color')); - this._builder.get_object('dot_color_colorbutton').set_rgba(rgba); - - this._builder.get_object('dot_color_colorbutton').connect('notify::rgba', (button) => { - let css = button.rgba.to_string(); - - this._settings.set_string('custom-theme-running-dots-color', css); - }); - - rgba.parse(this._settings.get_string('custom-theme-running-dots-border-color')); - this._builder.get_object('dot_border_color_colorbutton').set_rgba(rgba); - - this._builder.get_object('dot_border_color_colorbutton').connect('notify::rgba', (button) => { - let css = button.rgba.to_string(); - - this._settings.set_string('custom-theme-running-dots-border-color', css); - }); - - this._settings.bind('custom-theme-running-dots-border-width', - this._builder.get_object('dot_border_width_spin_button'), - 'value', - Gio.SettingsBindFlags.DEFAULT); - - - dialog.connect('response', (dialog, id) => { - // remove the settings box so it doesn't get destroyed; - dialog.get_content_area().remove(box); - dialog.destroy(); - return; - }); - - dialog.present(); - - }); - - this._settings.bind('custom-background-color', this._builder.get_object('custom_background_color_switch'), 'active', Gio.SettingsBindFlags.DEFAULT); - this._settings.bind('custom-background-color', this._builder.get_object('custom_background_color'), 'sensitive', Gio.SettingsBindFlags.DEFAULT); - - let rgba = new Gdk.RGBA(); - rgba.parse(this._settings.get_string('background-color')); - this._builder.get_object('custom_background_color').set_rgba(rgba); - - this._builder.get_object('custom_background_color').connect('notify::rgba', (button) => { - let css = button.rgba.to_string(); - - this._settings.set_string('background-color', css); - }); - - // Opacity - this._builder.get_object('customize_opacity_combo').set_active_id( - this._settings.get_enum('transparency-mode').toString() - ); - this._builder.get_object('customize_opacity_combo').connect( - 'changed', - (widget) => { - this._settings.set_enum('transparency-mode', parseInt(widget.get_active_id())); - } - ); - - const custom_opacity_scale = this._builder.get_object('custom_opacity_scale'); - custom_opacity_scale.set_value(this._settings.get_double('background-opacity')); - custom_opacity_scale.set_format_value_func((_, value) => { - return Math.round(value * 100) + '%'; - }); - - if (this._settings.get_enum('transparency-mode') !== TransparencyMode.FIXED) - this._builder.get_object('custom_opacity_scale').set_sensitive(false); - - this._settings.connect('changed::transparency-mode', () => { - if (this._settings.get_enum('transparency-mode') !== TransparencyMode.FIXED) - this._builder.get_object('custom_opacity_scale').set_sensitive(false); - else - this._builder.get_object('custom_opacity_scale').set_sensitive(true); - }); - - if (this._settings.get_enum('transparency-mode') !== TransparencyMode.DYNAMIC) { - this._builder.get_object('dynamic_opacity_button').set_sensitive(false); - } - - this._settings.connect('changed::transparency-mode', () => { - if (this._settings.get_enum('transparency-mode') !== TransparencyMode.DYNAMIC) { - this._builder.get_object('dynamic_opacity_button').set_sensitive(false); - } - else { - this._builder.get_object('dynamic_opacity_button').set_sensitive(true); - } - }); - - // Create dialog for transparency advanced settings - this._builder.get_object('dynamic_opacity_button').connect('clicked', () => { - - let dialog = new Gtk.Dialog({ - title: __('Customize opacity'), - transient_for: this.widget.get_root(), - use_header_bar: true, - modal: true - }); - - let box = this._builder.get_object('advanced_transparency_dialog'); - dialog.get_content_area().append(box); - - this._settings.bind( - 'customize-alphas', - this._builder.get_object('customize_alphas_switch'), - 'active', - Gio.SettingsBindFlags.DEFAULT - ); - this._settings.bind( - 'customize-alphas', - this._builder.get_object('min_alpha_scale'), - 'sensitive', - Gio.SettingsBindFlags.DEFAULT - ); - this._settings.bind( - 'customize-alphas', - this._builder.get_object('max_alpha_scale'), - 'sensitive', - Gio.SettingsBindFlags.DEFAULT - ); - - const min_alpha_scale = this._builder.get_object('min_alpha_scale'); - const max_alpha_scale = this._builder.get_object('max_alpha_scale'); - min_alpha_scale.set_value( - this._settings.get_double('min-alpha') - ); - min_alpha_scale.set_format_value_func((_, value) => { - return Math.round(value * 100) + ' %'; - }); - max_alpha_scale.set_format_value_func((_, value) => { - return Math.round(value * 100) + ' %'; - }); - - max_alpha_scale.set_value( - this._settings.get_double('max-alpha') - ); - - dialog.connect('response', (dialog, id) => { - // remove the settings box so it doesn't get destroyed; - dialog.get_content_area().remove(box); - dialog.destroy(); - return; - }); - - dialog.present(); - }); - - - this._settings.bind('unity-backlit-items', - this._builder.get_object('unity_backlit_items_switch'), - 'active', Gio.SettingsBindFlags.DEFAULT - ); - - this._settings.bind('force-straight-corner', - this._builder.get_object('force_straight_corner_switch'), - 'active', Gio.SettingsBindFlags.DEFAULT); - - // About Panel - - this._builder.get_object('extension_version').set_label(Me.metadata.version.toString()); - } -}); - -function init() { - ExtensionUtils.initTranslations(); -} - -function buildPrefsWidget() { - let settings = new Settings(); - let widget = settings.widget; - if (widget.show_all) widget.show_all(); - return widget; -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/schemas/gschemas.compiled b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/schemas/gschemas.compiled deleted file mode 100644 index e39b067..0000000 Binary files a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/schemas/gschemas.compiled and /dev/null differ diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/schemas/org.gnome.shell.extensions.dash-to-dock.gschema.xml b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/schemas/org.gnome.shell.extensions.dash-to-dock.gschema.xml deleted file mode 100644 index 54dd9f2..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/schemas/org.gnome.shell.extensions.dash-to-dock.gschema.xml +++ /dev/null @@ -1,551 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 'BOTTOM' - Dock position - Dock is shown on the Left, Right, Top or Bottom side of the screen. - - - 0.2 - Animation time - Sets the time duration of the autohide effect. - - - 0.25 - Show delay - Sets the delay after the mouse reaches the screen border before showing the dock. - - - 0.20 - Show delay - Sets the delay after the mouse left the dock before hiding it. - - - false - Set a custom dash background background color - Sets the color for the dash background. - - - "#ffffff" - Dash background color. - Customize the background color of the dash. - - - 'DEFAULT' - Transparency mode for the dock - FIXED: constant transparency. DYNAMIC: dock takes the opaque style only when windows are close to it. - - - 'DEFAULT' - ... - DEFAULT: .... DOTS: .... - - - false - Use application icon dominant color for the indicator color - - - - false - Manually set the min and max opacity - For the dynamic mode, the min/max opacity values will be given by 'min-alpha' and 'max-alpha'. - - - 0.2 - Opacity of the dash background when free-floating - Sets the opacity of the dash background when no windows are close. - - - 0.8 - Opacity of the dash background when windows are close. - Sets the opacity of the dash background when windows are close. - - - 0.8 - Opacity of the dash background - Sets the opacity of the dash background when in autohide mode. - - - true - Dock dodges windows - Enable or disable intellihide mode - - - 'FOCUS_APPLICATION_WINDOWS' - Define which windows are considered for intellihide. - - - - true - Dock shown on mouse over - Enable or disable autohide mode - - - true - Require pressure to show dash - Enable or disable requiring pressure to show the dash - - - 100 - Pressure threshold - Sets how much pressure is needed to show the dash. - - - false - Enable autohide in fullscreen mode. - Enable autohide in fullscreen mode. - - - false - Dock always visible - Dock is always visible - - - true - Switch workspace by scrolling over the dock - Add the possibility to switch workspace by mouse scrolling over the dock. - - - 48 - Maximum dash icon size - Set the allowed maximum dash icon size. Allowed range: 16..64. - - - false - Fixed icon size - Keep the icon size fived by scrolling the dock. - - - false - Apply custom theme - Apply customization to the dash appearance - - - false - TODO - TODO - - - false - Customize the style of the running application indicators. - Customize the style of the running application indicators. - - - "#ffffff" - Running application indicators color - Customize the color of the running application indicators. - - - "#ffffff" - Running application indicators border color. - Customize the border color of the running application indicators. - - - 0 - Running application indicators border width. - Customize the border width of the running application indicators. - - - true - Show running apps - Show or hide running applications icons in the dash - - - false - Provide workspace isolation - Dash shows only windows from the currentworkspace - - - false - Provide monitor isolation - Dash shows only windows from the monitor - - - true - Show preview of the open windows - Replace open windows list with windows previews - - - true - Show favorites apps - Show or hide favorite applications icons in the dash - - - true - Show trash can - Show or hide the trash can icon in the dash - - - true - Show mounted volumes and devices - Show or hide mounted volume and device icons in the dash - - - true - Show applications button - Show applications button in the dash - - - false - Show application button on the left - Show application button on the left of the dash - - - true - Animate Show Applications from the desktop - Animate Show Applications from the desktop - - - true - Basic compatibility with bolt extensions - Make the extension work properly when bolt extensions is enabled - - - 0.90 - Dock max height (fraction of available space) - - - false - Extend the dock container to all the available height - - - -1 - Monitor on which putting the dock - Set on which monitor to put the dock, use -1 for the primary one - - - false - Enable multi-monitor docks - Show a dock on every monitor - - - true - Minimize on shift+click - - - true - Activate only one window - - - 'cycle-windows' - Action when clicking on a running app - Set the action that is executed when clicking on the icon of a running application - - - 'do-nothing' - Action when scrolling app - Set the action that is executed when scrolling on the application icon - - - 'minimize' - Action when shift+clicking on a running app - Set the action that is executed when shift+clicking on the icon of a running application - - - 'launch' - Action when clicking on a running app - Set the action that is executed when middle-clicking on the icon of a running application - - - 'launch' - Action when clicking on a running app - Set the action that is executed when shift+middle-clicking on the icon of a running application - - - true - Super Hot-Keys - Launch and switch between dash items using Super+(0-9) - - - true - Show the dock when using the hotkeys - The dock will be quickly shown so that the number-overlay is visible and app activation is easier - - - "<Super>q" - Keybinding to show the dock and the number overlay. - Behavior depends on hotkeys-show-dock and hotkeys-overlay. - - - q']]]> - Keybinding to show the dock and the number overlay. - Behavior depends on hotkeys-show-dock and hotkeys-overlay. - - - 2 - Timeout to hide the dock - Sets the time duration before the dock is hidden again. - - - true - Show the dock when using the hotkeys - The dock will be quickly shown so that the number-overlay is visible and app activation is easier - - - 1']]]> - Keybinding to launch 1st dash app - - Keybinding to launch 1st app. - - - - 2']]]> - Keybinding to launch 2nd dash app - - Keybinding to launch 2nd app. - - - - 3']]]> - Keybinding to launch 3rd dash app - - Keybinding to launch 3rd app. - - - - 4']]]> - Keybinding to launch 4th dash app - - Keybinding to launch 4th app. - - - - 5']]]> - Keybinding to launch 5th dash app - - Keybinding to launch 5th app. - - - - 6']]]> - Keybinding to launch 6th dash app - - Keybinding to launch 6th app. - - - - 7']]]> - Keybinding to launch 7th dash app - - Keybinding to launch 7th app. - - - - 8']]]> - Keybinding to launch 8th dash app - - Keybinding to launch 8th app. - - - - 9']]]> - Keybinding to launch 9th dash app - - Keybinding to launch 9th app. - - - - 0']]]> - Keybinding to launch 10th dash app - - Keybinding to launch 10th app. - - - - 1']]]> - Keybinding to trigger 1st dash app with shift behavior - - Keybinding to trigger 1st app with shift behavior. - - - - 2']]]> - Keybinding to trigger 2nd dash app with shift behavior - - Keybinding to trigger 2nd app with shift behavior. - - - - 3']]]> - Keybinding to trigger 3rd dash app with shift behavior - - Keybinding to trigger 3rd app with shift behavior. - - - - 4']]]> - Keybinding to trigger 4th dash app with shift behavior - - Keybinding to trigger 4th app with shift behavior. - - - - 5']]]> - Keybinding to trigger 5th dash app with shift behavior - - Keybinding to trigger 5th app with shift behavior. - - - - 6']]]> - Keybinding to trigger 6th dash app with shift behavior - - Keybinding to trigger 6th app with shift behavior. - - - - 7']]]> - Keybinding to trigger 7th dash app with shift behavior - - Keybinding to trigger 7th app with shift behavior. - - - - 8']]]> - Keybinding to trigger 8th dash app with shift behavior - - Keybinding to trigger 8th app with shift behavior. - - - - 9']]]> - Keybinding to trigger 9th dash app with shift behavior - - Keybinding to trigger 9th app with shift behavior. - - - - 0']]]> - Keybinding to trigger 10th dash app with shift behavior - - Keybinding to trigger 10th app with shift behavior. - - - - 1']]]> - Keybinding to trigger 1st dash app - - Keybinding to either show or launch the 1st application in the dash. - - - - 2']]]> - Keybinding to trigger 2nd dash app - - Keybinding to either show or launch the 2nd application in the dash. - - - - 3']]]> - Keybinding to trigger 3rd dash app - - Keybinding to either show or launch the 3rd application in the dash. - - - - 4']]]> - Keybinding to trigger 4th dash app - - Keybinding to either show or launch the 4th application in the dash. - - - - 5']]]> - Keybinding to trigger 5th dash app - - Keybinding to either show or launch the 5th application in the dash. - - - - 6']]]> - Keybinding to trigger 6th dash app - - Keybinding to either show or launch the 6th application in the dash. - - - - 7']]]> - Keybinding to trigger 7th dash app - - Keybinding to either show or launch the 7th application in the dash. - - - - 8']]]> - Keybinding to trigger 8th dash app - - Keybinding to either show or launch the 8th application in the dash. - - - - 9']]]> - Keybinding to trigger 9th dash app - - Keybinding to either show or launch the 9th application in the dash. - - - - 0']]]> - Keybinding to trigger 10th dash app - - Keybinding to either show or launch the 10th application in the dash. - - - - false - Force straight corners in dash - Make the borders in the dash non rounded - - - false - Enable unity7 like glossy backlit items - Emulate the unity7 backlit glossy items behaviour - - - diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/stylesheet.css b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/stylesheet.css deleted file mode 100644 index 9a427f2..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/stylesheet.css +++ /dev/null @@ -1,231 +0,0 @@ -/* Shrink the dash by reducing padding */ -#dashtodockContainer.bottom.shrink #dash .dash-background { - border: 1px; - padding: 2.5px; - border-bottom: 0px; } - -#dashtodockContainer.bottom.shrink #dash .dash-item-container .app-well-app, -#dashtodockContainer.bottom.shrink #dash .dash-item-container .show-apps { - padding: 2.5px; } - -#dashtodockContainer.bottom.extended #dash { - margin-top: 0; - margin-bottom: 0; } - -#dashtodockContainer.top.shrink #dash .dash-background { - border: 1px; - padding: 2.5px; - border-top: 0px; } - -#dashtodockContainer.top.shrink #dash .dash-item-container .app-well-app, -#dashtodockContainer.top.shrink #dash .dash-item-container .show-apps { - padding: 2.5px; } - -#dashtodockContainer.top.extended #dash { - margin-top: 0; - margin-bottom: 0; } - -#dashtodockContainer.left.shrink #dash .dash-background { - border: 1px; - padding: 2.5px; - border-left: 0px; } - -#dashtodockContainer.left.shrink #dash .dash-item-container .app-well-app, -#dashtodockContainer.left.shrink #dash .dash-item-container .show-apps { - padding: 2.5px; } - -#dashtodockContainer.left.extended #dash { - margin-top: 0; - margin-bottom: 0; } - -#dashtodockContainer.right.shrink #dash .dash-background { - border: 1px; - padding: 2.5px; - border-right: 0px; } - -#dashtodockContainer.right.shrink #dash .dash-item-container .app-well-app, -#dashtodockContainer.right.shrink #dash .dash-item-container .show-apps { - padding: 2.5px; } - -#dashtodockContainer.right.extended #dash { - margin-top: 0; - margin-bottom: 0; } - -#dashtodockContainer.bottom.shrink #dash .dash-background { - margin-top: 0; - margin-bottom: 4px; } - -#dashtodockContainer.straight-corner #dash .dash-background, -#dashtodockContainer.shrink.straight-corner #dash .dash-background { - border-radius: 0px; } - -/* Scrollview style */ -.bottom #dashtodockDashScrollview, -.top #dashtodockDashScrollview { - -st-hfade-offset: 24px; } - -.left #dashtodockDashScrollview, -.right #dashtodockDashScrollview { - -st-vfade-offset: 24px; } - -#dashtodockContainer.running-dots .dash-item-container > StButton, -#dashtodockContainer.dashtodock .dash-item-container > StButton { - transition-duration: 250; - background-size: contain; } - -#dashtodockContainer #dash .dash-separator { - margin-bottom: 0; } - -#dashtodockContainer #dash .vertical-dash-separator { - height: 1px; - margin: 6.5px 0; - background-color: rgba(238, 238, 236, 0.3); } - -#dashtodockContainer.bottom #dash { - margin-top: 0; } - #dashtodockContainer.bottom #dash .dash-background { - margin-bottom: 8px; } - #dashtodockContainer.bottom #dash .dash-item-container .app-well-app, - #dashtodockContainer.bottom #dash .dash-item-container .show-apps { - padding: 10px 1.5px 18px; } - -#dashtodockContainer.bottom.overview #dash { - margin-top: 12px; } - -#dashtodockContainer.bottom.extended #dash .dash-background, #dashtodockContainer.bottom.shrink #dash .dash-background { - margin-bottom: 0; } - -#dashtodockContainer.bottom.extended #dash .dash-item-container .app-well-app, -#dashtodockContainer.bottom.extended #dash .dash-item-container .show-apps { - padding-bottom: 10px; } - -#dashtodockContainer.bottom.shrink #dash .dash-item-container .app-well-app, -#dashtodockContainer.bottom.shrink #dash .dash-item-container .show-apps { - padding-bottom: 2.5px; } - -#dashtodockContainer.left #dash, -#dashtodockContainer.right #dash { - padding-left: 4px; - padding-right: 4px; } - #dashtodockContainer.left #dash .dash-item-container .app-well-app, - #dashtodockContainer.left #dash .dash-item-container .show-apps, - #dashtodockContainer.right #dash .dash-item-container .app-well-app, - #dashtodockContainer.right #dash .dash-item-container .show-apps { - /* In vertical we don't want to add additional padding below the button. */ - padding-bottom: 6px; - padding-top: 6px; } - -#dashtodockContainer.left.shrink #dash, -#dashtodockContainer.right.shrink #dash { - padding-left: 0; - padding-right: 0; } - -#dashtodockContainer.top #dash { - margin-bottom: 0px; } - -/* Dash height extended to the whole available vertical space */ -#dashtodockContainer.extended.left #dash, #dashtodockContainer.extended.right #dash, #dashtodockContainer.extended.top #dash, #dashtodockContainer.extended.bottom #dash { - padding-top: 0; - padding-bottom: 0; - padding-left: 0; - padding-right: 0; } - #dashtodockContainer.extended.left #dash .dash-background, #dashtodockContainer.extended.right #dash .dash-background, #dashtodockContainer.extended.top #dash .dash-background, #dashtodockContainer.extended.bottom #dash .dash-background { - border-radius: 0; } - -#dashtodockContainer.extended.top #dash, #dashtodockContainer.extended.bottom #dash { - border-left: 0px; - border-right: 0px; } - #dashtodockContainer.extended.top #dash .dash-background, #dashtodockContainer.extended.bottom #dash .dash-background { - padding-left: 0; - padding-right: 0; } - -#dashtodockContainer.extended.left #dash, #dashtodockContainer.extended.right #dash { - border-top: 0px; - border-bottom: 0px; } - -/* Running and focused application style */ -#dashtodockContainer.running-dots .app-well-app.running > .overview-icon, -#dashtodockContainer.dashtodock .app-well-app.running > .overview-icon { - background-image: none; } - -#dashtodockContainer.running-dots .app-well-app.focused .overview-icon, -#dashtodockContainer.dashtodock .app-well-app.focused .overview-icon { - background-color: rgba(238, 238, 236, 0.2); } - -#dashtodockContainer.dashtodock #dash .dash-background { - background: #2e3436; } - -#dashtodockContainer.dashtodock .progress-bar { - /* Customization of the progress bar style, e.g.: - -progress-bar-background: rgba(0.8, 0.8, 0.8, 1); - -progress-bar-border: rgba(0.9, 0.9, 0.9, 1); - */ } - -#dashtodockContainer.top #dash .placeholder, -#dashtodockContainer.bottom #dash .placeholder { - width: 32px; - height: 1px; } - -/* - * This is applied to a dummy actor. Only the alpha value for the background and border color - * and the transition-duration are used - */ -#dashtodockContainer.dummy-opaque { - background-color: rgba(0, 0, 0, 0.8); - border-color: rgba(0, 0, 0, 0.4); - transition-duration: 300ms; } - -/* - * This is applied to a dummy actor. Only the alpha value for the background and border color - * and the transition-duration are used - */ -#dashtodockContainer.dummy-transparent { - background-color: rgba(0, 0, 0, 0.2); - border-color: rgba(0, 0, 0, 0.1); - transition-duration: 500ms; } - -#dashtodockContainer .number-overlay { - color: white; - background-color: rgba(0, 0, 0, 0.8); - text-align: center; } - -#dashtodockContainer .notification-badge { - color: white; - background-color: red; - padding: 0.2em 0.5em; - border-radius: 1em; - font-weight: bold; - text-align: center; - margin: 2px; } - -#dashtodockPreviewSeparator.popup-separator-menu-item-horizontal { - width: 1px; - height: auto; - border-right-width: 1px; - margin: 32px 0px; } - -.dashtodock-app-well-preview-menu-item { - padding: 1em 1em 0.5em 1em; } - -#dashtodockContainer .metro .overview-icon { - border-radius: 0px; } - -#dashtodockContainer.bottom .metro.running2.focused, -#dashtodockContainer.bottom .metro.running3.focused, -#dashtodockContainer.bottom .metro.running4.focused, -#dashtodockContainer.top .metro.running2.focused, -#dashtodockContainer.top .metro.running3.focused, -#dashtodockContainer.top .metro.running4.focused { - background-image: url("./media/highlight_stacked_bg.svg"); - background-position: 0px 0px; - background-size: contain; } - -#dashtodockContainer.left .metro.running2.focused, -#dashtodockContainer.left .metro.running3.focused, -#dashtodockContainer.left .metro.running4.focused, -#dashtodockContainer.right .metro.running2.focused, -#dashtodockContainer.right .metro.running3.focused, -#dashtodockContainer.right .metro.running4.focused { - background-image: url("./media/highlight_stacked_bg_h.svg"); - background-position: 0px 0px; - background-size: contain; } diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/theming.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/theming.js deleted file mode 100644 index 4b9e10a..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/theming.js +++ /dev/null @@ -1,553 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const Signals = imports.signals; -const Meta = imports.gi.Meta; -const Shell = imports.gi.Shell; -const St = imports.gi.St; -const Clutter = imports.gi.Clutter; - -const AppDisplay = imports.ui.appDisplay; -const AppFavorites = imports.ui.appFavorites; -const Dash = imports.ui.dash; -const DND = imports.ui.dnd; -const IconGrid = imports.ui.iconGrid; -const Main = imports.ui.main; -const PopupMenu = imports.ui.popupMenu; -const Util = imports.misc.util; -const Workspace = imports.ui.workspace; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Docking = Me.imports.docking; -const Utils = Me.imports.utils; - -/* - * DEFAULT: transparency given by theme - * FIXED: constant transparency chosen by user - * DYNAMIC: apply 'transparent' style when no windows are close to the dock - * */ -const TransparencyMode = { - DEFAULT: 0, - FIXED: 1, - DYNAMIC: 3 -}; - -/** - * Manage theme customization and custom theme support - */ -var ThemeManager = class DashToDock_ThemeManager { - - constructor(dock) { - this._signalsHandler = new Utils.GlobalSignalsHandler(); - this._bindSettingsChanges(); - this._actor = dock; - this._dash = dock.dash; - - // initialize colors with generic values - this._customizedBackground = {red: 0, green: 0, blue: 0, alpha: 0}; - this._customizedBorder = {red: 0, green: 0, blue: 0, alpha: 0}; - this._transparency = new Transparency(dock); - - this._signalsHandler.add([ - // When theme changes re-obtain default background color - St.ThemeContext.get_for_stage (global.stage), - 'changed', - this.updateCustomTheme.bind(this) - ], [ - // update :overview pseudoclass - Main.overview, - 'showing', - this._onOverviewShowing.bind(this) - ], [ - Main.overview, - 'hiding', - this._onOverviewHiding.bind(this) - ]); - - this._updateCustomStyleClasses(); - - // destroy themeManager when the managed actor is destroyed (e.g. extension unload) - // in order to disconnect signals - this._actor.connect('destroy', this.destroy.bind(this)); - - } - - destroy() { - this._signalsHandler.destroy(); - this._transparency.destroy(); - } - - _onOverviewShowing() { - this._actor.add_style_pseudo_class('overview'); - } - - _onOverviewHiding() { - this._actor.remove_style_pseudo_class('overview'); - } - - _updateDashOpacity() { - let newAlpha = Docking.DockManager.settings.get_double('background-opacity'); - - let [backgroundColor, borderColor] = this._getDefaultColors(); - - if (backgroundColor==null) - return; - - // Get the background and border alphas. We check the background alpha - // for a minimum of .001 to prevent division by 0 errors - let backgroundAlpha = Math.max(Math.round(backgroundColor.alpha/2.55)/100, .001); - let borderAlpha = Math.round(borderColor.alpha/2.55)/100; - - // The border and background alphas should remain in sync - // We also limit the borderAlpha to a maximum of 1 (full opacity) - borderAlpha = Math.min((borderAlpha/backgroundAlpha)*newAlpha, 1); - - this._customizedBackground = 'rgba(' + - backgroundColor.red + ',' + - backgroundColor.green + ',' + - backgroundColor.blue + ',' + - newAlpha + ')'; - - this._customizedBorder = 'rgba(' + - borderColor.red + ',' + - borderColor.green + ',' + - borderColor.blue + ',' + - borderAlpha + ')'; - - } - - _getDefaultColors() { - // Prevent shell crash if the actor is not on the stage. - // It happens enabling/disabling repeatedly the extension - if (!this._dash._container.get_stage()) - return [null, null]; - - // Remove custom style - let oldStyle = this._dash._container.get_style(); - this._dash._container.set_style(null); - - let themeNode = this._dash._container.get_theme_node(); - this._dash._container.set_style(oldStyle); - - let backgroundColor = themeNode.get_background_color(); - - // Just in case the theme has different border colors .. - // We want to find the inside border-color of the dock because it is - // the side most visible to the user. We do this by finding the side - // opposite the position - let position = Utils.getPosition(); - let side = position + 2; - if (side > 3) - side = Math.abs(side - 4); - - let borderColor = themeNode.get_border_color(side); - - return [backgroundColor, borderColor]; - } - - _updateDashColor() { - // Retrieve the color. If needed we will adjust it before passing it to - // this._transparency. - let [backgroundColor, borderColor] = this._getDefaultColors(); - - if (backgroundColor==null) - return; - - let settings = Docking.DockManager.settings; - - if (settings.get_boolean('custom-background-color')) { - // When applying a custom color, we need to check the alpha value, - // if not the opacity will always be overridden by the color below. - // Note that if using 'dynamic' transparency modes, - // the opacity will be set by the opaque/transparent styles anyway. - let newAlpha = Math.round(backgroundColor.alpha/2.55)/100; - if (settings.get_enum('transparency-mode') == TransparencyMode.FIXED) - newAlpha = settings.get_double('background-opacity'); - - backgroundColor = settings.get_string('background-color'); - - this._customizedBackground = backgroundColor; - - this._customizedBorder = this._customizedBackground; - - // backgroundColor is a string like rgb(0,0,0) - const color = Clutter.Color.from_string(backgroundColor); - color.alpha = newAlpha; - - this._transparency.setColor(color); - } else { - // backgroundColor is a Clutter.Color object - this._transparency.setColor(backgroundColor); - } - } - - _updateCustomStyleClasses() { - let settings = Docking.DockManager.settings; - - if (settings.get_boolean('apply-custom-theme')) - this._actor.add_style_class_name('dashtodock'); - else - this._actor.remove_style_class_name('dashtodock'); - - if (settings.get_boolean('custom-theme-shrink')) - this._actor.add_style_class_name('shrink'); - else - this._actor.remove_style_class_name('shrink'); - - if (settings.get_enum('running-indicator-style') !== 0) - this._actor.add_style_class_name('running-dots'); - else - this._actor.remove_style_class_name('running-dots'); - - // If not the built-in theme option is not selected - if (!settings.get_boolean('apply-custom-theme')) { - if (settings.get_boolean('force-straight-corner')) - this._actor.add_style_class_name('straight-corner'); - else - this._actor.remove_style_class_name('straight-corner'); - } else { - this._actor.remove_style_class_name('straight-corner'); - } - } - - updateCustomTheme() { - this._updateCustomStyleClasses(); - this._updateDashOpacity(); - this._updateDashColor(); - this._adjustTheme(); - this._dash._redisplay(); - } - - /** - * Reimported back and adapted from atomdock - */ - _adjustTheme() { - // Prevent shell crash if the actor is not on the stage. - // It happens enabling/disabling repeatedly the extension - if (!this._dash._background.get_stage()) - return; - - let settings = Docking.DockManager.settings; - - // Remove prior style edits - this._dash._background.set_style(null); - this._transparency.disable(); - - // If built-in theme is enabled do nothing else - if (settings.get_boolean('apply-custom-theme')) - return; - - let newStyle = ''; - let position = Utils.getPosition(settings); - - // obtain theme border settings - let themeNode = this._dash._background.get_theme_node(); - let borderColor = themeNode.get_border_color(St.Side.TOP); - let borderWidth = themeNode.get_border_width(St.Side.TOP); - - // We're copying border and corner styles to left border and top-left - // corner, also removing bottom border and bottom-right corner styles - let borderInner = ''; - let borderMissingStyle = ''; - - if (this._rtl && (position != St.Side.RIGHT)) - borderMissingStyle = 'border-right: ' + borderWidth + 'px solid ' + - borderColor.to_string() + ';'; - else if (!this._rtl && (position != St.Side.LEFT)) - borderMissingStyle = 'border-left: ' + borderWidth + 'px solid ' + - borderColor.to_string() + ';'; - - newStyle = borderMissingStyle; - - // I do call set_style possibly twice so that only the background gets the transition. - // The transition-property css rules seems to be unsupported - this._dash._background.set_style(newStyle); - - // Customize background - let fixedTransparency = settings.get_enum('transparency-mode') == TransparencyMode.FIXED; - let defaultTransparency = settings.get_enum('transparency-mode') == TransparencyMode.DEFAULT; - if (!defaultTransparency && !fixedTransparency) { - this._transparency.enable(); - } - else if (!defaultTransparency || settings.get_boolean('custom-background-color')) { - newStyle = newStyle + 'background-color:'+ this._customizedBackground + '; ' + - 'border-color:'+ this._customizedBorder + '; ' + - 'transition-delay: 0s; transition-duration: 0.250s;'; - this._dash._background.set_style(newStyle); - } - } - - _bindSettingsChanges() { - let keys = ['transparency-mode', - 'customize-alphas', - 'min-alpha', - 'max-alpha', - 'background-opacity', - 'custom-background-color', - 'background-color', - 'apply-custom-theme', - 'custom-theme-shrink', - 'custom-theme-running-dots', - 'extend-height', - 'force-straight-corner']; - - keys.forEach(function(key) { - this._signalsHandler.add([ - Docking.DockManager.settings, - 'changed::' + key, - this.updateCustomTheme.bind(this) - ]); - }, this); - } -}; - -/** - * The following class is based on the following upstream commit: - * https://git.gnome.org/browse/gnome-shell/commit/?id=447bf55e45b00426ed908b1b1035f472c2466956 - * Transparency when free-floating - */ -var Transparency = class DashToDock_Transparency { - - constructor(dock) { - this._dash = dock.dash; - this._actor = this._dash._container; - this._backgroundActor = this._dash._background; - this._dockActor = dock; - this._dock = dock; - this._panel = Main.panel; - this._position = Utils.getPosition(); - - // All these properties are replaced with the ones in the .dummy-opaque and .dummy-transparent css classes - this._backgroundColor = '0,0,0'; - this._transparentAlpha = '0.2'; - this._opaqueAlpha = '1'; - this._transparentAlphaBorder = '0.1'; - this._opaqueAlphaBorder = '0.5'; - this._transparentTransition = '0ms'; - this._opaqueTransition = '0ms'; - this._base_actor_style = ""; - - this._signalsHandler = new Utils.GlobalSignalsHandler(); - this._injectionsHandler = new Utils.InjectionsHandler(); - this._trackedWindows = new Map(); - } - - enable() { - // ensure I never double-register/inject - // although it should never happen - this.disable(); - - this._base_actor_style = this._actor.get_style(); - if (this._base_actor_style == null) { - this._base_actor_style = ""; - } - - this._signalsHandler.addWithLabel('transparency', [ - global.window_group, - 'actor-added', - this._onWindowActorAdded.bind(this) - ], [ - global.window_group, - 'actor-removed', - this._onWindowActorRemoved.bind(this) - ], [ - global.window_manager, - 'switch-workspace', - this._updateSolidStyle.bind(this) - ], [ - Main.overview, - 'hiding', - this._updateSolidStyle.bind(this) - ], [ - Main.overview, - 'showing', - this._updateSolidStyle.bind(this) - ]); - - // Window signals - global.window_group.get_children().filter(function(child) { - // An irrelevant window actor ('Gnome-shell') produces an error when the signals are - // disconnected, therefore do not add signals to it. - return child instanceof Meta.WindowActor && - child.get_meta_window().get_wm_class() !== 'Gnome-shell'; - }).forEach(function(win) { - this._onWindowActorAdded(null, win); - }, this); - - if (this._actor.get_stage()) - this._updateSolidStyle(); - - this._updateStyles(); - this._updateSolidStyle(); - - this.emit('transparency-enabled'); - } - - disable() { - // ensure I never double-register/inject - // although it should never happen - this._signalsHandler.removeWithLabel('transparency'); - - for (let key of this._trackedWindows.keys()) - this._trackedWindows.get(key).forEach(id => { - key.disconnect(id); - }); - this._trackedWindows.clear(); - - this.emit('transparency-disabled'); - } - - destroy() { - this.disable(); - this._signalsHandler.destroy(); - this._injectionsHandler.destroy(); - } - - _onWindowActorAdded(container, metaWindowActor) { - let signalIds = []; - ['notify::allocation', 'notify::visible'].forEach(s => { - signalIds.push(metaWindowActor.connect(s, this._updateSolidStyle.bind(this))); - }); - this._trackedWindows.set(metaWindowActor, signalIds); - } - - _onWindowActorRemoved(container, metaWindowActor) { - if (!this._trackedWindows.get(metaWindowActor)) - return; - - this._trackedWindows.get(metaWindowActor).forEach(id => { - metaWindowActor.disconnect(id); - }); - this._trackedWindows.delete(metaWindowActor); - this._updateSolidStyle(); - } - - _updateSolidStyle() { - let isNear = this._dockIsNear(); - if (isNear) { - this._backgroundActor.set_style(this._opaque_style); - this._dockActor.remove_style_class_name('transparent'); - this._dockActor.add_style_class_name('opaque'); - } - else { - this._backgroundActor.set_style(this._transparent_style); - this._dockActor.remove_style_class_name('opaque'); - this._dockActor.add_style_class_name('transparent'); - } - - this.emit('solid-style-updated', isNear); - } - - _dockIsNear() { - if (this._dockActor.has_style_pseudo_class('overview')) - return false; - /* Get all the windows in the active workspace that are in the primary monitor and visible */ - let activeWorkspace = global.workspace_manager.get_active_workspace(); - let dash = this._dash; - let windows = activeWorkspace.list_windows().filter(function(metaWindow) { - return metaWindow.get_monitor() === dash._monitorIndex && - metaWindow.showing_on_its_workspace() && - metaWindow.get_window_type() != Meta.WindowType.DESKTOP; - }); - - /* Check if at least one window is near enough to the panel. - * If the dock is hidden, we need to account for the space it would take - * up when it slides out. This is avoid an ugly transition. - * */ - let factor = 0; - if (!Docking.DockManager.settings.get_boolean('dock-fixed') && - this._dock.getDockState() == Docking.State.HIDDEN) - factor = 1; - let [leftCoord, topCoord] = this._actor.get_transformed_position(); - let threshold; - if (this._position === St.Side.LEFT) - threshold = leftCoord + this._actor.get_width() * (factor + 1); - else if (this._position === St.Side.RIGHT) - threshold = leftCoord - this._actor.get_width() * factor; - else if (this._position === St.Side.TOP) - threshold = topCoord + this._actor.get_height() * (factor + 1); - else - threshold = topCoord - this._actor.get_height() * factor; - - let scale = St.ThemeContext.get_for_stage(global.stage).scale_factor; - let isNearEnough = windows.some((metaWindow) => { - let coord; - if (this._position === St.Side.LEFT) { - coord = metaWindow.get_frame_rect().x; - return coord < threshold + 5 * scale; - } - else if (this._position === St.Side.RIGHT) { - coord = metaWindow.get_frame_rect().x + metaWindow.get_frame_rect().width; - return coord > threshold - 5 * scale; - } - else if (this._position === St.Side.TOP) { - coord = metaWindow.get_frame_rect().y; - return coord < threshold + 5 * scale; - } - else { - coord = metaWindow.get_frame_rect().y + metaWindow.get_frame_rect().height; - return coord > threshold - 5 * scale; - } - }); - - return isNearEnough; - } - - _updateStyles() { - this._getAlphas(); - - this._transparent_style = this._base_actor_style + - 'background-color: rgba(' + - this._backgroundColor + ', ' + this._transparentAlpha + ');' + - 'border-color: rgba(' + - this._backgroundColor + ', ' + this._transparentAlphaBorder + ');' + - 'transition-duration: ' + this._transparentTransition + 'ms;'; - - this._opaque_style = this._base_actor_style + - 'background-color: rgba(' + - this._backgroundColor + ', ' + this._opaqueAlpha + ');' + - 'border-color: rgba(' + - this._backgroundColor + ',' + this._opaqueAlphaBorder + ');' + - 'transition-duration: ' + this._opaqueTransition + 'ms;'; - - this.emit('styles-updated'); - } - - setColor(color) { - this._backgroundColor = color.red + ',' + color.green + ',' + color.blue; - this._updateStyles(); - } - - _getAlphas() { - // Create dummy object and add to the uiGroup to get it to the stage - let dummyObject = new St.Bin({ - name: 'dashtodockContainer', - }); - Main.uiGroup.add_child(dummyObject); - - dummyObject.add_style_class_name('dummy-opaque'); - let themeNode = dummyObject.get_theme_node(); - this._opaqueAlpha = themeNode.get_background_color().alpha / 255; - this._opaqueAlphaBorder = themeNode.get_border_color(0).alpha / 255; - this._opaqueTransition = themeNode.get_transition_duration(); - - dummyObject.add_style_class_name('dummy-transparent'); - themeNode = dummyObject.get_theme_node(); - this._transparentAlpha = themeNode.get_background_color().alpha / 255; - this._transparentAlphaBorder = themeNode.get_border_color(0).alpha / 255; - this._transparentTransition = themeNode.get_transition_duration(); - - Main.uiGroup.remove_child(dummyObject); - - let settings = Docking.DockManager.settings; - - if (settings.get_boolean('customize-alphas')) { - this._opaqueAlpha = settings.get_double('max-alpha'); - this._opaqueAlphaBorder = this._opaqueAlpha / 2; - this._transparentAlpha = settings.get_double('min-alpha'); - this._transparentAlphaBorder = this._transparentAlpha / 2; - } - } -}; -Signals.addSignalMethods(Transparency.prototype); diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/utils.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/utils.js deleted file mode 100644 index 3dd8029..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/utils.js +++ /dev/null @@ -1,308 +0,0 @@ -const Clutter = imports.gi.Clutter; -const Meta = imports.gi.Meta; -const St = imports.gi.St; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Docking = Me.imports.docking; - -var SignalsHandlerFlags = { - NONE: 0, - CONNECT_AFTER: 1 -}; - -/** - * Simplify global signals and function injections handling - * abstract class - */ -const BasicHandler = class DashToDock_BasicHandler { - - constructor() { - this._storage = new Object(); - } - - add(/* unlimited 3-long array arguments */) { - // Convert arguments object to array, concatenate with generic - // Call addWithLabel with ags as if they were passed arguments - this.addWithLabel('generic', ...arguments); - } - - destroy() { - for( let label in this._storage ) - this.removeWithLabel(label); - } - - addWithLabel(label /* plus unlimited 3-long array arguments*/) { - if (this._storage[label] == undefined) - this._storage[label] = new Array(); - - // Skip first element of the arguments - for (let i = 1; i < arguments.length; i++) { - let item = this._storage[label]; - try { - item.push(this._create(arguments[i])); - } catch (e) { - logError(e); - } - } - } - - removeWithLabel(label) { - if (this._storage[label]) { - for (let i = 0; i < this._storage[label].length; i++) - this._remove(this._storage[label][i]); - - delete this._storage[label]; - } - } - - // Virtual methods to be implemented by subclass - - /** - * Create single element to be stored in the storage structure - */ - _create(item) { - throw new GObject.NotImplementedError(`_create in ${this.constructor.name}`); - } - - /** - * Correctly delete single element - */ - _remove(item) { - throw new GObject.NotImplementedError(`_remove in ${this.constructor.name}`); - } -}; - -/** - * Manage global signals - */ -var GlobalSignalsHandler = class DashToDock_GlobalSignalHandler extends BasicHandler { - - _create(item) { - let object = item[0]; - let event = item[1]; - let callback = item[2] - let flags = item.length > 3 ? item[3] : SignalsHandlerFlags.NONE; - - if (!object) - throw new Error('Impossible to connect to an invalid object'); - - let after = flags == SignalsHandlerFlags.CONNECT_AFTER; - let connector = after ? object.connect_after : object.connect; - - if (!connector) { - throw new Error(`Requested to connect to signal '${event}', ` + - `but no implementation for 'connect${after ? '_after' : ''}' `+ - `found in ${object.constructor.name}`); - } - - let id = connector.call(object, event, callback); - - return [object, id]; - } - - _remove(item) { - item[0].disconnect(item[1]); - } -}; - -/** - * Color manipulation utilities - */ -var ColorUtils = class DashToDock_ColorUtils { - - // Darken or brigthen color by a fraction dlum - // Each rgb value is modified by the same fraction. - // Return "#rrggbb" string - static ColorLuminance(r, g, b, dlum) { - let rgbString = '#'; - - rgbString += ColorUtils._decimalToHex(Math.round(Math.min(Math.max(r*(1+dlum), 0), 255)), 2); - rgbString += ColorUtils._decimalToHex(Math.round(Math.min(Math.max(g*(1+dlum), 0), 255)), 2); - rgbString += ColorUtils._decimalToHex(Math.round(Math.min(Math.max(b*(1+dlum), 0), 255)), 2); - - return rgbString; - } - - // Convert decimal to an hexadecimal string adding the desired padding - static _decimalToHex(d, padding) { - let hex = d.toString(16); - while (hex.length < padding) - hex = '0'+ hex; - return hex; - } - - // Convert hsv ([0-1, 0-1, 0-1]) to rgb ([0-255, 0-255, 0-255]). - // Following algorithm in https://en.wikipedia.org/wiki/HSL_and_HSV - // here with h = [0,1] instead of [0, 360] - // Accept either (h,s,v) independently or {h:h, s:s, v:v} object. - // Return {r:r, g:g, b:b} object. - static HSVtoRGB(h, s, v) { - if (arguments.length === 1) { - s = h.s; - v = h.v; - h = h.h; - } - - let r,g,b; - let c = v*s; - let h1 = h*6; - let x = c*(1 - Math.abs(h1 % 2 - 1)); - let m = v - c; - - if (h1 <=1) - r = c + m, g = x + m, b = m; - else if (h1 <=2) - r = x + m, g = c + m, b = m; - else if (h1 <=3) - r = m, g = c + m, b = x + m; - else if (h1 <=4) - r = m, g = x + m, b = c + m; - else if (h1 <=5) - r = x + m, g = m, b = c + m; - else - r = c + m, g = m, b = x + m; - - return { - r: Math.round(r * 255), - g: Math.round(g * 255), - b: Math.round(b * 255) - }; - } - - // Convert rgb ([0-255, 0-255, 0-255]) to hsv ([0-1, 0-1, 0-1]). - // Following algorithm in https://en.wikipedia.org/wiki/HSL_and_HSV - // here with h = [0,1] instead of [0, 360] - // Accept either (r,g,b) independently or {r:r, g:g, b:b} object. - // Return {h:h, s:s, v:v} object. - static RGBtoHSV(r, g, b) { - if (arguments.length === 1) { - r = r.r; - g = r.g; - b = r.b; - } - - let h,s,v; - - let M = Math.max(r, g, b); - let m = Math.min(r, g, b); - let c = M - m; - - if (c == 0) - h = 0; - else if (M == r) - h = ((g-b)/c) % 6; - else if (M == g) - h = (b-r)/c + 2; - else - h = (r-g)/c + 4; - - h = h/6; - v = M/255; - if (M !== 0) - s = c/M; - else - s = 0; - - return { - h: h, - s: s, - v: v - }; - } -}; - -/** - * Manage function injection: both instances and prototype can be overridden - * and restored - */ -var InjectionsHandler = class DashToDock_InjectionsHandler extends BasicHandler { - - _create(item) { - let object = item[0]; - let name = item[1]; - let injectedFunction = item[2]; - let original = object[name]; - - object[name] = injectedFunction; - return [object, name, injectedFunction, original]; - } - - _remove(item) { - let object = item[0]; - let name = item[1]; - let original = item[3]; - object[name] = original; - } -}; - -/** - * Return the actual position reverseing left and right in rtl - */ -function getPosition() { - let position = Docking.DockManager.settings.get_enum('dock-position'); - if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL) { - if (position == St.Side.LEFT) - position = St.Side.RIGHT; - else if (position == St.Side.RIGHT) - position = St.Side.LEFT; - } - return position; -} - -function drawRoundedLine(cr, x, y, width, height, isRoundLeft, isRoundRight, stroke, fill) { - if (height > width) { - y += Math.floor((height - width) / 2.0); - height = width; - } - - height = 2.0 * Math.floor(height / 2.0); - - var leftRadius = isRoundLeft ? height / 2.0 : 0.0; - var rightRadius = isRoundRight ? height / 2.0 : 0.0; - - cr.moveTo(x + width - rightRadius, y); - cr.lineTo(x + leftRadius, y); - if (isRoundLeft) - cr.arcNegative(x + leftRadius, y + leftRadius, leftRadius, -Math.PI/2, Math.PI/2); - else - cr.lineTo(x, y + height); - cr.lineTo(x + width - rightRadius, y + height); - if (isRoundRight) - cr.arcNegative(x + width - rightRadius, y + rightRadius, rightRadius, Math.PI/2, -Math.PI/2); - else - cr.lineTo(x + width, y); - cr.closePath(); - - if (fill != null) { - cr.setSource(fill); - cr.fillPreserve(); - } - if (stroke != null) - cr.setSource(stroke); - cr.stroke(); -} - -/** - * Convert a signal handler with n value parameters (that is, excluding the - * signal source parameter) to an array of n handlers that are each responsible - * for receiving one of the n values and calling the original handler with the - * most up-to-date arguments. - */ -function splitHandler(handler) { - if (handler.length > 30) { - throw new Error("too many parameters"); - } - const count = handler.length - 1; - let missingValueBits = (1 << count) - 1; - const values = Array.from({ length: count }); - return values.map((_ignored, i) => { - const mask = ~(1 << i); - return (obj, value) => { - values[i] = value; - missingValueBits &= mask; - if (missingValueBits === 0) { - handler(obj, ...values); - } - }; - }); -} diff --git a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/windowPreview.js b/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/windowPreview.js deleted file mode 100644 index 8cb14b8..0000000 --- a/src/other/dash-to-dock/dash-to-dock@micxgx.gmail.com/windowPreview.js +++ /dev/null @@ -1,598 +0,0 @@ -/* - * Credits: - * This file is based on code from the Dash to Panel extension by Jason DeRose - * and code from the Taskbar extension by Zorin OS - * Some code was also adapted from the upstream Gnome Shell source code. - */ -const Clutter = imports.gi.Clutter; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const St = imports.gi.St; -const Main = imports.ui.main; - -const Params = imports.misc.params; -const PopupMenu = imports.ui.popupMenu; -const Workspace = imports.ui.workspace; - -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const Utils = Me.imports.utils; - -const PREVIEW_MAX_WIDTH = 250; -const PREVIEW_MAX_HEIGHT = 150; - -const PREVIEW_ANIMATION_DURATION = 250; - -var WindowPreviewMenu = class DashToDock_WindowPreviewMenu extends PopupMenu.PopupMenu { - - constructor(source) { - let side = Utils.getPosition(); - super(source, 0.5, side); - - // We want to keep the item hovered while the menu is up - this.blockSourceEvents = true; - - this._source = source; - this._app = this._source.app; - let monitorIndex = this._source.monitorIndex; - - this.actor.add_style_class_name('app-well-menu'); - this.actor.set_style('max-width: ' + (Main.layoutManager.monitors[monitorIndex].width - 22) + 'px; ' + - 'max-height: ' + (Main.layoutManager.monitors[monitorIndex].height - 22) + 'px;'); - this.actor.hide(); - - // Chain our visibility and lifecycle to that of the source - this._mappedId = this._source.connect('notify::mapped', () => { - if (!this._source.mapped) - this.close(); - }); - this._destroyId = this._source.connect('destroy', this.destroy.bind(this)); - - Main.uiGroup.add_actor(this.actor); - - // Change the initialized side where required. - this._arrowSide = side; - this._boxPointer._arrowSide = side; - this._boxPointer._userArrowSide = side; - - this.connect('destroy', this._onDestroy.bind(this)); - } - - _redisplay() { - if (this._previewBox) - this._previewBox.destroy(); - this._previewBox = new WindowPreviewList(this._source); - this.addMenuItem(this._previewBox); - this._previewBox._redisplay(); - } - - popup() { - let windows = this._source.getInterestingWindows(); - if (windows.length > 0) { - this._redisplay(); - this.open(); - this.actor.navigate_focus(null, St.DirectionType.TAB_FORWARD, false); - this._source.emit('sync-tooltip'); - } - } - - _onDestroy() { - if (this._mappedId) - this._source.disconnect(this._mappedId); - - if (this._destroyId) - this._source.disconnect(this._destroyId); - } -}; - -var WindowPreviewList = class DashToDock_WindowPreviewList extends PopupMenu.PopupMenuSection { - - constructor(source) { - super(); - this.actor = new St.ScrollView({ - name: 'dashtodockWindowScrollview', - hscrollbar_policy: St.PolicyType.NEVER, - vscrollbar_policy: St.PolicyType.NEVER, - enable_mouse_scrolling: true - }); - - this.actor.connect('scroll-event', this._onScrollEvent.bind(this)); - - let position = Utils.getPosition(); - this.isHorizontal = position == St.Side.BOTTOM || position == St.Side.TOP; - this.box.set_vertical(!this.isHorizontal); - this.box.set_name('dashtodockWindowList'); - this.actor.add_actor(this.box); - this.actor._delegate = this; - - this._shownInitially = false; - - this._source = source; - this.app = source.app; - - this._redisplayId = Main.initializeDeferredWork(this.actor, this._redisplay.bind(this)); - - this.actor.connect('destroy', this._onDestroy.bind(this)); - this._stateChangedId = this.app.connect('windows-changed', - this._queueRedisplay.bind(this)); - } - - _queueRedisplay () { - Main.queueDeferredWork(this._redisplayId); - } - - _onScrollEvent(actor, event) { - // Event coordinates are relative to the stage but can be transformed - // as the actor will only receive events within his bounds. - let stage_x, stage_y, ok, event_x, event_y, actor_w, actor_h; - [stage_x, stage_y] = event.get_coords(); - [ok, event_x, event_y] = actor.transform_stage_point(stage_x, stage_y); - [actor_w, actor_h] = actor.get_size(); - - // If the scroll event is within a 1px margin from - // the relevant edge of the actor, let the event propagate. - if (event_y >= actor_h - 2) - return Clutter.EVENT_PROPAGATE; - - // Skip to avoid double events mouse - if (event.is_pointer_emulated()) - return Clutter.EVENT_STOP; - - let adjustment, delta; - - if (this.isHorizontal) - adjustment = this.actor.get_hscroll_bar().get_adjustment(); - else - adjustment = this.actor.get_vscroll_bar().get_adjustment(); - - let increment = adjustment.step_increment; - - switch ( event.get_scroll_direction() ) { - case Clutter.ScrollDirection.UP: - delta = -increment; - break; - case Clutter.ScrollDirection.DOWN: - delta = +increment; - break; - case Clutter.ScrollDirection.SMOOTH: - let [dx, dy] = event.get_scroll_delta(); - delta = dy*increment; - delta += dx*increment; - break; - - } - - adjustment.set_value(adjustment.get_value() + delta); - - return Clutter.EVENT_STOP; - } - - _onDestroy() { - this.app.disconnect(this._stateChangedId); - this._stateChangedId = 0; - } - - _createPreviewItem(window) { - let preview = new WindowPreviewMenuItem(window); - return preview; - } - - _redisplay () { - let children = this._getMenuItems().filter(function(actor) { - return actor._window; - }); - - // Windows currently on the menu - let oldWin = children.map(function(actor) { - return actor._window; - }); - - // All app windows with a static order - let newWin = this._source.getInterestingWindows().sort(function(a, b) { - return a.get_stable_sequence() > b.get_stable_sequence(); - }); - - let addedItems = []; - let removedActors = []; - - let newIndex = 0; - let oldIndex = 0; - - while (newIndex < newWin.length || oldIndex < oldWin.length) { - // No change at oldIndex/newIndex - if (oldWin[oldIndex] && - oldWin[oldIndex] == newWin[newIndex]) { - oldIndex++; - newIndex++; - continue; - } - - // Window removed at oldIndex - if (oldWin[oldIndex] && - newWin.indexOf(oldWin[oldIndex]) == -1) { - removedActors.push(children[oldIndex]); - oldIndex++; - continue; - } - - // Window added at newIndex - if (newWin[newIndex] && - oldWin.indexOf(newWin[newIndex]) == -1) { - addedItems.push({ item: this._createPreviewItem(newWin[newIndex]), - pos: newIndex }); - newIndex++; - continue; - } - - // Window moved - let insertHere = newWin[newIndex + 1] && - newWin[newIndex + 1] == oldWin[oldIndex]; - let alreadyRemoved = removedActors.reduce(function(result, actor) { - let removedWin = actor._window; - return result || removedWin == newWin[newIndex]; - }, false); - - if (insertHere || alreadyRemoved) { - addedItems.push({ item: this._createPreviewItem(newWin[newIndex]), - pos: newIndex + removedActors.length }); - newIndex++; - } else { - removedActors.push(children[oldIndex]); - oldIndex++; - } - } - - for (let i = 0; i < addedItems.length; i++) - this.addMenuItem(addedItems[i].item, - addedItems[i].pos); - - for (let i = 0; i < removedActors.length; i++) { - let item = removedActors[i]; - if (this._shownInitially) - item._animateOutAndDestroy(); - else - item.actor.destroy(); - } - - // Skip animations on first run when adding the initial set - // of items, to avoid all items zooming in at once - let animate = this._shownInitially; - - if (!this._shownInitially) - this._shownInitially = true; - - for (let i = 0; i < addedItems.length; i++) - addedItems[i].item.show(animate); - - // Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=692744 - // Without it, StBoxLayout may use a stale size cache - this.box.queue_relayout(); - - if (newWin.length < 1) - this._getTopMenu().close(~0); - - // As for upstream: - // St.ScrollView always requests space horizontally for a possible vertical - // scrollbar if in AUTOMATIC mode. Doing better would require implementation - // of width-for-height in St.BoxLayout and St.ScrollView. This looks bad - // when we *don't* need it, so turn off the scrollbar when that's true. - // Dynamic changes in whether we need it aren't handled properly. - let needsScrollbar = this._needsScrollbar(); - let scrollbar_policy = needsScrollbar ? - St.PolicyType.AUTOMATIC : St.PolicyType.NEVER; - if (this.isHorizontal) - this.actor.hscrollbar_policy = scrollbar_policy; - else - this.actor.vscrollbar_policy = scrollbar_policy; - - if (needsScrollbar) - this.actor.add_style_pseudo_class('scrolled'); - else - this.actor.remove_style_pseudo_class('scrolled'); - } - - _needsScrollbar() { - let topMenu = this._getTopMenu(); - let topThemeNode = topMenu.actor.get_theme_node(); - if (this.isHorizontal) { - let [topMinWidth, topNaturalWidth] = topMenu.actor.get_preferred_width(-1); - let topMaxWidth = topThemeNode.get_max_width(); - return topMaxWidth >= 0 && topNaturalWidth >= topMaxWidth; - } else { - let [topMinHeight, topNaturalHeight] = topMenu.actor.get_preferred_height(-1); - let topMaxHeight = topThemeNode.get_max_height(); - return topMaxHeight >= 0 && topNaturalHeight >= topMaxHeight; - } - - } - - isAnimatingOut() { - return this.actor.get_children().reduce(function(result, actor) { - return result || actor.animatingOut; - }, false); - } -}; - -var WindowPreviewMenuItem = GObject.registerClass( -class DashToDock_WindowPreviewMenuItem extends PopupMenu.PopupBaseMenuItem { - _init(window, params) { - super._init(params); - - this._window = window; - this._destroyId = 0; - this._windowAddedId = 0; - [this._width, this._height, this._scale] = this._getWindowPreviewSize(); // This gets the actual windows size for the preview - - // We don't want this: it adds spacing on the left of the item. - this.remove_child(this._ornamentLabel); - this.add_style_class_name('dashtodock-app-well-preview-menu-item'); - - // Now we don't have to set PREVIEW_MAX_WIDTH and PREVIEW_MAX_HEIGHT as preview size - that made all kinds of windows either stretched or squished (aspect ratio problem) - this._cloneBin = new St.Bin(); - this._cloneBin.set_size(this._width*this._scale, this._height*this._scale); - - // TODO: improve the way the closebutton is layout. Just use some padding - // for the moment. - this._cloneBin.set_style('padding-bottom: 0.5em'); - - this.closeButton = new St.Button({ style_class: 'window-close', - x_expand: true, - y_expand: true}); - this.closeButton.add_actor(new St.Icon({ icon_name: 'window-close-symbolic' })); - this.closeButton.set_x_align(Clutter.ActorAlign.END); - this.closeButton.set_y_align(Clutter.ActorAlign.START); - - - this.closeButton.opacity = 0; - this.closeButton.connect('clicked', this._closeWindow.bind(this)); - - let overlayGroup = new Clutter.Actor({layout_manager: new Clutter.BinLayout(), y_expand: true }); - - overlayGroup.add_actor(this._cloneBin); - overlayGroup.add_actor(this.closeButton); - - let label = new St.Label({ text: window.get_title()}); - label.set_style('max-width: '+PREVIEW_MAX_WIDTH +'px'); - let labelBin = new St.Bin({ child: label, - x_align: Clutter.ActorAlign.CENTER, - }); - - this._windowTitleId = this._window.connect('notify::title', () => { - label.set_text(this._window.get_title()); - }); - - let box = new St.BoxLayout({ vertical: true, - reactive:true, - x_expand:true }); - box.add(overlayGroup); - box.add(labelBin); - this.add_actor(box); - - this._cloneTexture(window); - - this.connect('destroy', this._onDestroy.bind(this)); - } - - _getWindowPreviewSize() { - let mutterWindow = this._window.get_compositor_private(); - let [width, height] = mutterWindow.get_size(); - let scale = Math.min(1.0, PREVIEW_MAX_WIDTH/width, PREVIEW_MAX_HEIGHT/height); - return [width, height, scale]; - } - - _cloneTexture(metaWin){ - - let mutterWindow = metaWin.get_compositor_private(); - - // Newly-created windows are added to a workspace before - // the compositor finds out about them... - // Moreover sometimes they return an empty texture, thus as a workarounf also check for it size - if (!mutterWindow || !mutterWindow.get_texture() || !mutterWindow.get_size()[0]) { - this._cloneTextureId = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { - // Check if there's still a point in getting the texture, - // otherwise this could go on indefinitely - if (metaWin.get_workspace()) - this._cloneTexture(metaWin); - this._cloneTextureId = 0; - return GLib.SOURCE_REMOVE; - }); - GLib.Source.set_name_by_id(this._cloneTextureId, '[dash-to-dock] this._cloneTexture'); - return; - } - - let clone = new Clutter.Clone ({ source: mutterWindow, - reactive: true, - width: this._width * this._scale, - height: this._height * this._scale }); - - // when the source actor is destroyed, i.e. the window closed, first destroy the clone - // and then destroy the menu item (do this animating out) - this._destroyId = mutterWindow.connect('destroy', () => { - clone.destroy(); - this._destroyId = 0; // avoid to try to disconnect this signal from mutterWindow in _onDestroy(), - // as the object was just destroyed - this._animateOutAndDestroy(); - }); - - this._clone = clone; - this._mutterWindow = mutterWindow; - this._cloneBin.set_child(this._clone); - - this._clone.connect('destroy', () => { - if (this._destroyId) { - mutterWindow.disconnect(this._destroyId); - this._destroyId = 0; - } - this._clone = null; - }) - } - - _windowCanClose() { - return this._window.can_close() && - !this._hasAttachedDialogs(); - } - - _closeWindow(actor) { - this._workspace = this._window.get_workspace(); - - // This mechanism is copied from the workspace.js upstream code - // It forces window activation if the windows don't get closed, - // for instance because asking user confirmation, by monitoring the opening of - // such additional confirmation window - this._windowAddedId = this._workspace.connect('window-added', - this._onWindowAdded.bind(this)); - - this.deleteAllWindows(); - } - - deleteAllWindows() { - // Delete all windows, starting from the bottom-most (most-modal) one - //let windows = this._window.get_compositor_private().get_children(); - let windows = this._clone.get_children(); - for (let i = windows.length - 1; i >= 1; i--) { - let realWindow = windows[i].source; - let metaWindow = realWindow.meta_window; - - metaWindow.delete(global.get_current_time()); - } - - this._window.delete(global.get_current_time()); - } - - _onWindowAdded(workspace, win) { - let metaWindow = this._window; - - if (win.get_transient_for() == metaWindow) { - workspace.disconnect(this._windowAddedId); - this._windowAddedId = 0; - - // use an idle handler to avoid mapping problems - - // see comment in Workspace._windowAdded - let activationEvent = Clutter.get_current_event(); - let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, () => { - this.emit('activate', activationEvent); - return GLib.SOURCE_REMOVE; - }); - GLib.Source.set_name_by_id(id, '[dash-to-dock] this.emit'); - } - } - - _hasAttachedDialogs() { - // count trasient windows - let n=0; - this._window.foreach_transient(function(){n++;}); - return n>0; - } - - vfunc_key_focus_in() { - super.vfunc_key_focus_in(); - this._showCloseButton(); - } - - vfunc_key_focus_out() { - super.vfunc_key_focus_out(); - this._hideCloseButton(); - } - - vfunc_enter_event(crossingEvent) { - this._showCloseButton(); - return super.vfunc_enter_event(crossingEvent); - } - - vfunc_leave_event(crossingEvent) { - this._hideCloseButton(); - return super.vfunc_leave_event(crossingEvent); - } - - _idleToggleCloseButton() { - this._idleToggleCloseId = 0; - - this._hideCloseButton(); - - return GLib.SOURCE_REMOVE; - } - - _showCloseButton() { - - if (this._windowCanClose()) { - this.closeButton.show(); - this.closeButton.remove_all_transitions(); - this.closeButton.ease({ - opacity: 255, - duration: Workspace.WINDOW_OVERLAY_FADE_TIME, - mode: Clutter.AnimationMode.EASE_OUT_QUAD - }); - } - } - - _hideCloseButton() { - if (this.closeButton.has_pointer || - this.get_children().some(a => a.has_pointer)) - return; - - this.closeButton.remove_all_transitions(); - this.closeButton.ease({ - opacity: 0, - duration: Workspace.WINDOW_OVERLAY_FADE_TIME, - mode: Clutter.AnimationMode.EASE_IN_QUAD - }); - } - - show(animate) { - let fullWidth = this.get_width(); - - this.opacity = 0; - this.set_width(0); - - let time = animate ? PREVIEW_ANIMATION_DURATION : 0; - this.remove_all_transitions(); - this.ease({ - opacity: 255, - width: fullWidth, - duration: time, - mode: Clutter.AnimationMode.EASE_IN_OUT_QUAD, - }); - } - - _animateOutAndDestroy() { - this.remove_all_transitions(); - this.ease({ - opacity: 0, - duration: PREVIEW_ANIMATION_DURATION, - }); - - this.ease({ - width: 0, - height: 0, - duration: PREVIEW_ANIMATION_DURATION, - delay: PREVIEW_ANIMATION_DURATION, - onComplete: () => this.destroy() - }); - } - - activate() { - this._getTopMenu().close(); - Main.activateWindow(this._window); - } - - _onDestroy() { - if (this._cloneTextureId) { - GLib.source_remove(this._cloneTextureId); - this._cloneTextureId = 0; - } - - if (this._windowAddedId > 0) { - this._workspace.disconnect(this._windowAddedId); - this._windowAddedId = 0; - } - - if (this._destroyId > 0) { - this._mutterWindow.disconnect(this._destroyId); - this._destroyId = 0; - } - - if (this._windowTitleId > 0) { - this._window.disconnect(this._windowTitleId); - this._windowTitleId = 0; - } - } -}); \ No newline at end of file diff --git a/src/other/dash-to-dock/stylesheet-40.scss b/src/other/dash-to-dock/stylesheet-40.scss new file mode 100644 index 0000000..885c846 --- /dev/null +++ b/src/other/dash-to-dock/stylesheet-40.scss @@ -0,0 +1,9 @@ +$variant: 'dark'; +$laptop: 'false'; +$trans: 'true'; +$black: 'false'; +$theme: 'default'; + +@import '../../sass/colors'; +@import '../../sass/variables'; +@import '_dash-to-dock-4.scss'; diff --git a/src/other/dash-to-dock/stylesheet-dark.scss b/src/other/dash-to-dock/stylesheet-dark.scss index 9a44f49..c582978 100644 --- a/src/other/dash-to-dock/stylesheet-dark.scss +++ b/src/other/dash-to-dock/stylesheet-dark.scss @@ -6,4 +6,4 @@ $theme: 'default'; @import '../../sass/colors'; @import '../../sass/variables'; -@import '_dash-to-dock.scss'; +@import '_dash-to-dock-3.scss'; diff --git a/src/other/dash-to-dock/stylesheet-light.scss b/src/other/dash-to-dock/stylesheet-light.scss index 0fab594..7b107a2 100644 --- a/src/other/dash-to-dock/stylesheet-light.scss +++ b/src/other/dash-to-dock/stylesheet-light.scss @@ -6,4 +6,4 @@ $theme: 'default'; @import '../../sass/colors'; @import '../../sass/variables'; -@import '_dash-to-dock.scss'; +@import '_dash-to-dock-3.scss'; diff --git a/src/sass/gnome-shell/extensions-40-0/_dash-to-dock.scss b/src/sass/gnome-shell/extensions-40-0/_dash-to-dock.scss index 4ac6990..0f4b05b 100644 --- a/src/sass/gnome-shell/extensions-40-0/_dash-to-dock.scss +++ b/src/sass/gnome-shell/extensions-40-0/_dash-to-dock.scss @@ -26,7 +26,7 @@ background-color: $primary_color; box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.25); border-radius: $circular_radius; - margin: 2px; + margin: 2px 3px 5px; padding: 0.2em 0.6em; font-weight: bold; text-align: center; @@ -36,12 +36,9 @@ (bottom, top, 0 1px), (left, right, -1px 0), (right, left, 1px 0) { - &.#{$_pos}.shrink #dash, - &.#{$_pos}.shrink:overview #dash, &.#{$_pos}.straight-corner #dash, &.#{$_pos}.shrink.straight-corner #dash, - &.#{$_pos}.extended #dash, - &.#{$_pos}.extended:overview #dash { + &.#{$_pos}.extended #dash { margin: 0 !important; padding: 0 !important; diff --git a/tweaks.sh b/tweaks.sh index 0c279a1..0bd9f02 100755 --- a/tweaks.sh +++ b/tweaks.sh @@ -137,9 +137,7 @@ while [[ $# -gt 0 ]]; do has_any_error="true" fi; shift ;; -d|--dash-to-dock) - if [[ "${GNOME_VERSION}" == 'new' ]]; then - dash_to_dock="new" - elif [[ ! -d "${DASH_TO_DOCK_DIR_HOME}" && ! -d "${DASH_TO_DOCK_DIR_ROOT}" ]]; then + if [[ ! -d "${DASH_TO_DOCK_DIR_HOME}" && ! -d "${DASH_TO_DOCK_DIR_ROOT}" ]]; then prompt -e "'${1}' ERROR: There's no Dash to Dock installed in your system" has_any_error="true" else @@ -201,12 +199,6 @@ if [[ "${uninstall}" == 'true' ]]; then prompt -s "Done! '${name}' Dash to Dock theme has been removed."; echo fi - if [[ "${dash_to_dock}" == 'new' ]]; then - prompt -i "Removing '${name}' Dash to Dock extension... \n" - revert_dash_to_dock - prompt -s "Done! '${name}' Dash to Dock extension has been removed."; echo - fi - if [[ "${firefox}" == 'true' ]]; then prompt -i "Removing '${name}' Firefox theme... \n" remove_firefox_theme @@ -222,14 +214,9 @@ else fi if [[ "${flatpak}" == 'true' ]]; then - if [[ -d "${THEME_DIR}/${name}${color}${opacity}" ]]; then - prompt -i "Connecting '${name}' themes to your Flatpak... \n" - connect_flatpak - prompt -s "Done! '${name}' theme has been connected to your Flatpak."; echo - else - prompt -e "ERROR: Befaore you run '-F' you need install this theme first... \n" - exit 0 - fi + prompt -i "Connecting '${name}' themes to your Flatpak... \n" + connect_flatpak + prompt -s "Done! '${name}' theme has been connected to your Flatpak."; echo fi if [[ "${gdm}" == 'true' ]]; then @@ -245,13 +232,6 @@ else prompt -w "DASH TO DOCK: You may need to logout to take effect."; echo fi - if [[ "${dash_to_dock}" == 'new' ]]; then - prompt -i "Installing fixed Dash to Dock... \n" - install_dash_to_dock - prompt -s "Done! '${name}' Dash to Dock extension has been installed." - prompt -w "DASH TO DOCK: You may need to logout to take effect."; echo - fi - if [[ "${firefox}" == 'true' || "${edit_firefox}" == 'true' ]]; then if [[ "${firefox}" == 'true' ]]; then prompt -i "Installing '${name}' Firefox theme... \n"