From 7a4d6f5ffa594603ef83bc8b0e9945d12e082490 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 7 Sep 2013 12:06:42 +0200 Subject: [PATCH 001/546] first commit --- LICENSE | 339 ++++++++++++++ README.md | 419 ++++++++++++++++++ helpers.lua | 90 ++++ icons/cal/white/1.png | Bin 0 -> 888 bytes icons/cal/white/10.png | Bin 0 -> 3476 bytes icons/cal/white/11.png | Bin 0 -> 2109 bytes icons/cal/white/12.png | Bin 0 -> 2349 bytes icons/cal/white/13.png | Bin 0 -> 2442 bytes icons/cal/white/14.png | Bin 0 -> 1378 bytes icons/cal/white/15.png | Bin 0 -> 1711 bytes icons/cal/white/16.png | Bin 0 -> 2056 bytes icons/cal/white/17.png | Bin 0 -> 1435 bytes icons/cal/white/18.png | Bin 0 -> 2207 bytes icons/cal/white/19.png | Bin 0 -> 2062 bytes icons/cal/white/2.png | Bin 0 -> 1553 bytes icons/cal/white/20.png | Bin 0 -> 2754 bytes icons/cal/white/21.png | Bin 0 -> 2092 bytes icons/cal/white/22.png | Bin 0 -> 2060 bytes icons/cal/white/23.png | Bin 0 -> 2495 bytes icons/cal/white/24.png | Bin 0 -> 2280 bytes icons/cal/white/25.png | Bin 0 -> 2325 bytes icons/cal/white/26.png | Bin 0 -> 2645 bytes icons/cal/white/27.png | Bin 0 -> 2044 bytes icons/cal/white/28.png | Bin 0 -> 2744 bytes icons/cal/white/29.png | Bin 0 -> 2597 bytes icons/cal/white/3.png | Bin 0 -> 1808 bytes icons/cal/white/30.png | Bin 0 -> 2912 bytes icons/cal/white/31.png | Bin 0 -> 2232 bytes icons/cal/white/4.png | Bin 0 -> 1140 bytes icons/cal/white/5.png | Bin 0 -> 1437 bytes icons/cal/white/6.png | Bin 0 -> 1776 bytes icons/cal/white/7.png | Bin 0 -> 1147 bytes icons/cal/white/8.png | Bin 0 -> 1930 bytes icons/cal/white/9.png | Bin 0 -> 1786 bytes icons/layout/default/browse.png | Bin 0 -> 190 bytes icons/layout/default/browsew.png | Bin 0 -> 190 bytes icons/layout/default/cascade.png | Bin 0 -> 233 bytes icons/layout/default/cascadebrowse.png | Bin 0 -> 235 bytes icons/layout/default/cascadebrowsew.png | Bin 0 -> 235 bytes icons/layout/default/cascadew.png | Bin 0 -> 233 bytes icons/layout/default/centerwork.png | Bin 0 -> 258 bytes icons/layout/default/centerworkw.png | Bin 0 -> 277 bytes icons/layout/default/gimp.png | Bin 0 -> 289 bytes icons/layout/default/gimpw.png | Bin 0 -> 289 bytes icons/layout/default/termfair.png | Bin 0 -> 191 bytes icons/layout/default/termfairw.png | Bin 0 -> 191 bytes icons/layout/zenburn/browse.png | Bin 0 -> 269 bytes icons/layout/zenburn/cascade.png | Bin 0 -> 299 bytes icons/layout/zenburn/cascadebrowse.png | Bin 0 -> 290 bytes icons/layout/zenburn/centerwork.png | Bin 0 -> 252 bytes icons/layout/zenburn/gimp.png | Bin 0 -> 3424 bytes icons/layout/zenburn/termfair.png | Bin 0 -> 289 bytes icons/mail.png | Bin 0 -> 634 bytes icons/no_net.png | Bin 0 -> 1697 bytes init.lua | 20 + layout/cascade.lua | 65 +++ layout/cascadetile.lua | 159 +++++++ layout/centerwork.lua | 122 +++++ layout/init.lua | 20 + layout/termfair.lua | 160 +++++++ layout/uselessfair.lua | 122 +++++ layout/uselesspiral.lua | 112 +++++ layout/uselesstile.lua | 232 ++++++++++ scripts/checkmail | 104 +++++ scripts/dfs | 385 ++++++++++++++++ scripts/mpdcover | 64 +++ util/init.lua | 174 ++++++++ util/markup.lua | 102 +++++ widgets/alsa.lua | 103 +++++ widgets/alsabar.lua | 164 +++++++ widgets/bat.lua | 147 ++++++ widgets/borderbox.lua | 61 +++ widgets/calendar.lua | 124 ++++++ widgets/cpu.lua | 80 ++++ widgets/fs.lua | 134 ++++++ widgets/imap.lua | 166 +++++++ widgets/init.lua | 24 + widgets/maildir.lua | 129 ++++++ widgets/mem.lua | 87 ++++ widgets/mpd.lua | 138 ++++++ widgets/net.lua | 153 +++++++ widgets/sysload.lua | 70 +++ widgets/temp.lua | 52 +++ widgets/yawn/README.rst | 133 ++++++ widgets/yawn/icons/BlowingSnow.png | Bin 0 -> 11454 bytes widgets/yawn/icons/Cloudy.png | Bin 0 -> 7469 bytes widgets/yawn/icons/DayClear.png | Bin 0 -> 6147 bytes widgets/yawn/icons/DayMostlyCloudy.png | Bin 0 -> 8016 bytes widgets/yawn/icons/DayPartlyCloudy.png | Bin 0 -> 7478 bytes widgets/yawn/icons/Foggy.png | Bin 0 -> 7325 bytes widgets/yawn/icons/FreezingDrizzle.png | Bin 0 -> 13166 bytes widgets/yawn/icons/FreezingRain.png | Bin 0 -> 13979 bytes widgets/yawn/icons/Hail.png | Bin 0 -> 7325 bytes widgets/yawn/icons/HeavySnow.png | Bin 0 -> 12733 bytes widgets/yawn/icons/LightSnowShowers.png | Bin 0 -> 8779 bytes widgets/yawn/icons/MixedRainAndHail.png | Bin 0 -> 9060 bytes widgets/yawn/icons/MixedRainAndSleet.png | Bin 0 -> 10978 bytes widgets/yawn/icons/MixedRainAndSnow.png | Bin 0 -> 10808 bytes widgets/yawn/icons/NightClear.png | Bin 0 -> 5198 bytes widgets/yawn/icons/NightMostlyCloudy.png | Bin 0 -> 7058 bytes widgets/yawn/icons/NightPartlyCloudy.png | Bin 0 -> 6583 bytes widgets/yawn/icons/README.md | 6 + widgets/yawn/icons/Rain.png | Bin 0 -> 8052 bytes widgets/yawn/icons/RainThunder.png | Bin 0 -> 9879 bytes widgets/yawn/icons/Showers.png | Bin 0 -> 9694 bytes widgets/yawn/icons/SnowShowers.png | Bin 0 -> 9961 bytes widgets/yawn/icons/Sunny.png | Bin 0 -> 14018 bytes widgets/yawn/icons/Wind.png | Bin 0 -> 8726 bytes widgets/yawn/icons/na.png | Bin 0 -> 11160 bytes widgets/yawn/init.lua | 227 ++++++++++ widgets/yawn/localizations/it_IT | 57 +++ .../yawn/localizations/localization_template | 57 +++ 112 files changed, 4801 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 helpers.lua create mode 100644 icons/cal/white/1.png create mode 100644 icons/cal/white/10.png create mode 100644 icons/cal/white/11.png create mode 100644 icons/cal/white/12.png create mode 100644 icons/cal/white/13.png create mode 100644 icons/cal/white/14.png create mode 100644 icons/cal/white/15.png create mode 100644 icons/cal/white/16.png create mode 100644 icons/cal/white/17.png create mode 100644 icons/cal/white/18.png create mode 100644 icons/cal/white/19.png create mode 100644 icons/cal/white/2.png create mode 100644 icons/cal/white/20.png create mode 100644 icons/cal/white/21.png create mode 100644 icons/cal/white/22.png create mode 100644 icons/cal/white/23.png create mode 100644 icons/cal/white/24.png create mode 100644 icons/cal/white/25.png create mode 100644 icons/cal/white/26.png create mode 100644 icons/cal/white/27.png create mode 100644 icons/cal/white/28.png create mode 100644 icons/cal/white/29.png create mode 100644 icons/cal/white/3.png create mode 100644 icons/cal/white/30.png create mode 100644 icons/cal/white/31.png create mode 100644 icons/cal/white/4.png create mode 100644 icons/cal/white/5.png create mode 100644 icons/cal/white/6.png create mode 100644 icons/cal/white/7.png create mode 100644 icons/cal/white/8.png create mode 100644 icons/cal/white/9.png create mode 100644 icons/layout/default/browse.png create mode 100644 icons/layout/default/browsew.png create mode 100644 icons/layout/default/cascade.png create mode 100644 icons/layout/default/cascadebrowse.png create mode 100644 icons/layout/default/cascadebrowsew.png create mode 100644 icons/layout/default/cascadew.png create mode 100644 icons/layout/default/centerwork.png create mode 100644 icons/layout/default/centerworkw.png create mode 100644 icons/layout/default/gimp.png create mode 100644 icons/layout/default/gimpw.png create mode 100644 icons/layout/default/termfair.png create mode 100644 icons/layout/default/termfairw.png create mode 100644 icons/layout/zenburn/browse.png create mode 100644 icons/layout/zenburn/cascade.png create mode 100644 icons/layout/zenburn/cascadebrowse.png create mode 100644 icons/layout/zenburn/centerwork.png create mode 100644 icons/layout/zenburn/gimp.png create mode 100644 icons/layout/zenburn/termfair.png create mode 100644 icons/mail.png create mode 100755 icons/no_net.png create mode 100644 init.lua create mode 100644 layout/cascade.lua create mode 100644 layout/cascadetile.lua create mode 100644 layout/centerwork.lua create mode 100644 layout/init.lua create mode 100644 layout/termfair.lua create mode 100644 layout/uselessfair.lua create mode 100644 layout/uselesspiral.lua create mode 100644 layout/uselesstile.lua create mode 100755 scripts/checkmail create mode 100755 scripts/dfs create mode 100755 scripts/mpdcover create mode 100644 util/init.lua create mode 100644 util/markup.lua create mode 100644 widgets/alsa.lua create mode 100644 widgets/alsabar.lua create mode 100644 widgets/bat.lua create mode 100644 widgets/borderbox.lua create mode 100644 widgets/calendar.lua create mode 100644 widgets/cpu.lua create mode 100644 widgets/fs.lua create mode 100644 widgets/imap.lua create mode 100644 widgets/init.lua create mode 100644 widgets/maildir.lua create mode 100644 widgets/mem.lua create mode 100644 widgets/mpd.lua create mode 100644 widgets/net.lua create mode 100644 widgets/sysload.lua create mode 100644 widgets/temp.lua create mode 100644 widgets/yawn/README.rst create mode 100755 widgets/yawn/icons/BlowingSnow.png create mode 100755 widgets/yawn/icons/Cloudy.png create mode 100755 widgets/yawn/icons/DayClear.png create mode 100755 widgets/yawn/icons/DayMostlyCloudy.png create mode 100755 widgets/yawn/icons/DayPartlyCloudy.png create mode 100755 widgets/yawn/icons/Foggy.png create mode 100755 widgets/yawn/icons/FreezingDrizzle.png create mode 100755 widgets/yawn/icons/FreezingRain.png create mode 100755 widgets/yawn/icons/Hail.png create mode 100755 widgets/yawn/icons/HeavySnow.png create mode 100755 widgets/yawn/icons/LightSnowShowers.png create mode 100755 widgets/yawn/icons/MixedRainAndHail.png create mode 100755 widgets/yawn/icons/MixedRainAndSleet.png create mode 100755 widgets/yawn/icons/MixedRainAndSnow.png create mode 100755 widgets/yawn/icons/NightClear.png create mode 100755 widgets/yawn/icons/NightMostlyCloudy.png create mode 100755 widgets/yawn/icons/NightPartlyCloudy.png create mode 100644 widgets/yawn/icons/README.md create mode 100755 widgets/yawn/icons/Rain.png create mode 100755 widgets/yawn/icons/RainThunder.png create mode 100755 widgets/yawn/icons/Showers.png create mode 100755 widgets/yawn/icons/SnowShowers.png create mode 100755 widgets/yawn/icons/Sunny.png create mode 100755 widgets/yawn/icons/Wind.png create mode 100755 widgets/yawn/icons/na.png create mode 100644 widgets/yawn/init.lua create mode 100644 widgets/yawn/localizations/it_IT create mode 100644 widgets/yawn/localizations/localization_template diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + 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/README.md b/README.md new file mode 100644 index 0000000..8aa9449 --- /dev/null +++ b/README.md @@ -0,0 +1,419 @@ +VAin agaIN +========== + +Author: Luke Bonham + +Source: https://github.com/copycat-killer/vain + +Version: 1.9.9 + +Release version: 2.0 + +**Please note**: until release version, this documentation will be not updated. + +Foreword +-------- + +Based on a port of [awesome-vain](https://github.com/vain/awesome-vain), this +costantly evolving module provides new layouts, a set of widgets and +utility functions in order to improve Awesome usability and configurability. + +This work is licensed under [GNU GPLv2 License](http://www.gnu.org/licenses/gpl-2.0.html). +Installation +============ + +Simply clone this repository into your Awesome directory. + +Widgets +======= + +systemload +---------- + +Show the current system load in a textbox. Read it directly from +`/proc/loadavg`. + + mysysload = vain.widgets.systemload() + +A click on the widget will call `htop` in your `terminal`. + +The function takes a table as an optional argument. That table may +contain: + +* `.refresh_timeout`: Default to 10 seconds. +* `.show_all`: Show all three values (`true`) or only the first one (`false`). Default to `false`. +* `.color`: Default to beautiful.bg_normal or "#FFFFFF". + +cpu +-------- + +Shows the average CPU usage percent for a given amount of time. + + mycpuusage = vain.widgets.cpu() + +A click on the widget will call `htop` in your `terminal`. + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`refresh_timeout` | Refresh timeout seconds | int | 10 +`header` | Text to show before value | string | " Vol " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to show after value | string | "%" + +**Note**: `footer` color is `color`. + +memusage +-------- + +Show used memory and total memory in MiB. + + mymem = vain.widgets.mem() + + +The function takes a table as an optional argument. That table may +contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`refresh_timeout` | Refresh timeout seconds | int | 10 +`show_swap` | Show amount of used swap space? | boolean | false +`show_total` | Show amout of total memory? | boolean | false +`header` | Text to show before value | string | " Vol " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to show after value | string | "MB" + +**Note**: `footer` color is `color`. + +mailcheck +--------- +Checks maildirs and shows the result in a textbox. +Maildirs are structured as follows: + + ~/Mail + . + |-- arch + | |-- cur + | |-- new + | `-- tmp + |-- gmail + | |-- cur + | |-- new + | `-- tmp + . + . + . + +therefore `mailcheck` checks whether there are files in the `new` +directories. To do so, it calls `find`. If there's new mail, the textbox +will say something like "mail: bugs(3), system(1)", otherwise it says +"no mail". + + mymailcheck = vain.widgets.mailcheck("/path/to/my/maildir") + +The function takes a table as an optional argument. That table may +contain: + +* `.mailprogram`: Your favourite mail program. Clicking on the widget will + spawn it. Default is `mutt`. +* `.refresh_timeout`: Default to 60 seconds. +* `.mailpath`: Path to your maildir, default is `~/Mail`. +* `.ignore_boxes`: Another table which lists boxes (just the last part, + like `lists`) to ignore. Default to an empty table. +* `.initial_update`: Check for mail when starting Awesome (`true`) or + wait for the first refresh timeout (`false`)? Default to `false`. +* `.header_text`: Text to show along with output, default is "Mail". +* `.header_text_color`: Default to "#9E9E9E". +* `.color_newmail`: Default to "#D4D4D4". +* `.color_nomail`: Default to "#9E9E9E". +* `.shadow`: Hides widget when there are no mails. Default is `false`. + +imapcheck +--------- + +Check new mails over imap protocol. + +Dependencies: + +* Python3 + +Since [luasec](https://github.com/brunoos/luasec/) is still not officially +supported in lua 5.2, writing a pure lua solution would have meant too many +hacks and dependencies, resulting in a very big and not efficient-proven submodule. + +That's why I chose Python. + +Python offers [imaplib](http://docs.python.org/2/library/imaplib.html), a simple yet powerful IMAP4 client library which provides encrypted communication over SSL sockets. + +Basically, `imapcheck` calls ``vain/scripts/checkmail`` and parse its output in a widget. New mails are also notified through Naughty, with a popup like this: + + +---------------------------------------------------+ + | +---+ | + | |\ /| donald@disney.org has 3 new messages | + | +---+ | + | Latest From: Mickey Mouse | + | Subject: Re: Vacation Day | + | | + | Not after what you did yesterday. | + | Daisy told me everything [...] | + | | + +---------------------------------------------------+ + +Text will be cut if the mail is too long. + + myimapcheck = vain.widgets.mailcheck(args) + +The function takes a table as argument. Required table parameters are: + +* `.server`: You email server. Example: `imap.gmail.com`. +* `.mail`: Your email. +* `.password`: Your email password. + +while the optional are: + +* `.port`: Imap port. Default is `993`. +* `.refresh_timeout`: Default to 60 seconds. +* `.notify_timeout`: Notification timeout. Default to 8 seconds. +* `.notify_position`: Notification position. Default is "top_left". Check + [Naughty position parameter](http://awesome.naquadah.org/doc/api/modules/naughty.html) for a list of other possible values. +* `.mailprogram`: Your favourite mail program. Clicking on the widget will + spawn it. Default is `mutt`. +* `.mail_encoding`: If you wish to set an encoding. Default is `nil`. +* `.initial_update`: Check for mail when starting Awesome (`true`) or + wait for the first refresh timeout (`false`)? Default to `false`. +* `.header_text`: Text to show along with output, default is "Mail". +* `.header_text_color`: Default to "#9E9E9E". +* `.color_newmail`: Default to "#D4D4D4". +* `.color_nomail`: Default to "#9E9E9E". +* `.shadow`: Hides widget when there are no mails. Default is `false`. +* `.maxlen`: Maximum mail length. If mail is longer, it will be cut. Default is + `100`. +* `.is_plain`: Define whether `.password` field is a plain password (`true`) or a function that retrieves it (`false`). Default to `false`. + +Let's focus better on `.is_plain` parameter. + +You can just easily set your password like this: + + args.is_plain = false + args.password = "mypassword" + +and you'll have the same security provided by `~/.netrc`. (In this case, it's +better to set your `rc.lua` permissions to 700 or 600) + +**Or**, you can use a keyring, like gnome's: + + args.password = "gnome-keyring-query get password" + +(`gnome-keyring-query` is not in gnome-keyring pkg, you have to download it +separately) + +or the very light [python keyring](https://pypi.python.org/pypi/keyring). + +When `.is_plain` is `false`, it *executes* `.password` before using it, so you can also use whatever password fetching solution you want. + +You can also define your icon for the naughty notification. Just set `vain_mail_notify` into your ``theme.lua``. + + + +mpd +--- + +Provides a `table` with 2 elements: + +* `table["widget"]` is a textbox displaying current song in play. + +* `table["force"]` is a function to *force* the widget to update, exactly + like `vicious.force()`. + +Also, a notification is shown when a new song is playing. + +Dependencies: + +* libnotify +* imagemagick + + + mpdwidget = vain.widgets.mpd() + ... + right_layout:add(mpdwidget["widget"]) + +The function takes a table as an optional argument. That table may +contain: + +* `.password`: Mpd password. Default is unset. +* `.host`: Mpd host. Default is "127.0.0.1" (localhost). +* `.port`: Mpd port. Default is "6600". +* `.music_dir`: Your music directory. Default is "~/Music". If you have to + change this, be sure to write the absolute path. +* `.refresh_timeout`: Widget refresh timeout. Default is `1`. +* `.notify_timeout`: Notification timeout. Default is `5`. +* `.color_artist`: Artist name color. Default is `#9E9E9E`. +* `.color_song`: Song name color. Default is `#EBEBFF`. +* `.musicplr`: Your favourite music player. Clicking on the widget will spawn + it. Default is `ncmpcpp`. +* `.shadow`: Hides widget when no song is playing. Default is `false`. + +You can use `table["force"]` to make your mpd keybindings immediate. +Example usage: + + globalkeys = awful.util.table.join( + ... + -- Music control + awful.key({ altkey, "Control" }, "Up", function () + awful.util.spawn_with_shell( "mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle", false ) + mpdwidget["force"]() + end), + awful.key({ altkey, "Control" }, "Down", function () + awful.util.spawn_with_shell( "mpc stop || ncmpcpp stop || ncmpc stop || pms stop", false ) + mpdwidget["force"]() + end ), + awful.key({ altkey, "Control" }, "Left", function () + awful.util.spawn_with_shell( "mpc prev || ncmpcpp prev || ncmpc prev || pms prev", false ) + mpdwidget["force"]() + end ), + awful.key({ altkey, "Control" }, "Right", function () + awful.util.spawn_with_shell( "mpc next || ncmpcpp next || ncmpc next || pms next", false ) + mpdwidget["force"]() + end ), + +net +--- + +Monitors network interfaces and shows current traffic in a textbox. If +the interface is not present or if there's not enough data yet, you'll +see `wlan0: -` or similar. Otherwise, the current traffic is shown in +kilobytes per second as `eth0: ↑(00,010.2), ↓(01,037.8)` or similar. + + neteth0 = vain.widgets.net() + +The function takes a table as an optional argument. That table may +contain: + +* `.iface`: Default to `eth0`. +* `.refresh_timeout`: Default to 2 seconds. +* `.color`: Default to beautiful.bg_normal or "#FFFFFF". + +gitodo +------ + +This is an integration of [gitodo](https://github.com/vain/gitodo) into +Awesome. + + todolist = vain.widgets.gitodo() + +The function takes a table as an optional argument. That table may +contain: + +* `.refresh_timeout`: Default to 120 seconds. +* `.initial_update`: Check for todo items when starting Awesome (`true`) + or wait for the first refresh timeout (`false`)? Default to `true`. + +`beautiful.gitodo_normal` is used as the color for non-outdated items, +`beautiful.gitodo_warning` for those items close to their deadline and +`beautiful.gitodo_outdated` is the color of outdated items. + + + +Utility functions +================= + +I'll only explain the more complex functions. See the source code for +the others. + +menu\_clients\_current\_tags +---------------------------- + +Similar to `awful.menu.clients()`, but this menu only shows the clients +of currently visible tags. Use it like this: + + globalkeys = awful.util.table.join( + ... + awful.key({ "Mod1" }, "Tab", function() + awful.menu.menu_keys.down = { "Down", "Alt_L", "Tab", "j" } + awful.menu.menu_keys.up = { "Up", "k" } + vain.util.menu_clients_current_tags({ width = 350 }, { keygrabber = true }) + end), + ... + ) + +magnify\_client +--------------- + +Set a client to floating and resize it in the same way the "magnifier" +layout does it. Place it on the "current" screen (derived from the mouse +position). This allows you to magnify any client you wish, regardless of +the currently used layout. Use it with a client keybinding like this: + + clientkeys = awful.util.table.join( + ... + awful.key({ modkey, "Control" }, "m", vain.util.magnify_client), + ... + ) + +If you want to "de-magnify" it, just reset the clients floating state to +`false` (hit `Mod4`+`CTRL`+`Space`, for example). + +niceborder\_{focus, unfocus} +---------------------------- + +By default, your `rc.lua` contains something like this: + + client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) + client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) + +You can change it to this: + + client.connect_signal("focus", vain.util.niceborder_focus(c)) + client.connect_signal("unfocus", vain.util.niceborder_unfocus(c)) + +Now, when a client is focused or unfocused, Awesome will look up its +nice value in `/proc//stat`. If it's less than 0, the client is +classified as "high priority"; if it's greater than 0, the client is +classified as "low priority". If it's equal to 0, nothing special +happens. + +This requires to define additional colors in your `theme.lua`. For example: + + theme.border_focus_highprio = "#FF0000" + theme.border_normal_highprio = "#A03333" + + theme.border_focus_lowprio = "#3333FF" + theme.border_normal_lowprio = "#333366" + +tag\_view\_nonempty +------------------------------ + +This function lets you jump to the next/previous non-empty tag. +It takes two arguments: + +* `direction`: `1` for next non-empty tag, `-1` for previous. +* `sc`: Screen in which the taglist is. Default is `mouse.screen` or `1`. This + argument is optional. + +Usage example: + + globalkeys = awful.util.table.join( + ... + -- Non-empty tag browsing + awful.key({ altkey }, "Left", function () vain.util.tag_view_nonempty(-1) + end), + awful.key({ altkey }, "Right", function () vain.util.tag_view_nonempty(1) end), + ... + +prompt\_rename\_tag +------------------- + +This function enables you to dynamically rename the current tag you have +focused. +Usage example: + + globalkeys = awful.util.table.join( + .. + -- Dynamic tag renaming + awful.key({ modkey, "Shift" }, "r", function () vain.util.prompt_rename_tag(mypromptbox) end), + ... + +Credits goes to [minism](https://bbs.archlinux.org/viewtopic.php?pid=1315135#p1315135). diff --git a/helpers.lua b/helpers.lua new file mode 100644 index 0000000..7677768 --- /dev/null +++ b/helpers.lua @@ -0,0 +1,90 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + * (c) 2010, Adrian C. + +--]] + +local awful = require("awful") +local debug = require("debug") +local pairs = pairs +local rawget = rawget + +-- Lain helper functions for internal use +-- lain.helpers +local helpers = {} + +helpers.lain_dir = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]] +helpers.icons_dir = helpers.lain_dir .. 'icons/' +helpers.scripts_dir = helpers.lain_dir .. 'scripts/' + +-- {{{ Modules loader + +function helpers.wrequire(table, key) + local module = rawget(table, key) + return module or require(table._NAME .. '.' .. key) +end + +-- }}} + +-- {{{ +-- If lain.terminal is a string, e.g. "xterm", then "xterm -e " .. cmd is +-- run. But if lain.terminal is a function, then terminal(cmd) is run. + +function helpers.run_in_terminal(cmd) + if type(terminal) == "function" + then + terminal(cmd) + elseif type(terminal) == "string" + then + awful.util.spawn(terminal .. ' -e ' .. cmd) + end +end + +-- }}} + +-- {{{ Format units to one decimal point + +function helpers.uformat(array, key, value, unit) + for u, v in pairs(unit) do + array["{"..key.."_"..u.."}"] = string.format("%.1f", value/v) + end + return array +end + +-- }}} + +-- {{{ Read the first line of a file or return nil. + +function helpers.first_line(f) + local fp = io.open(f) + if not fp + then + return nil + end + + local content = fp:read("*l") + fp:close() + return content +end + +-- }}} + +-- {{{ A map utility + +helpers.map_table = {} + +function helpers.set_map(element, value) + helpers.map_table[element] = value +end + +function helpers.get_map(element) + return helpers.map_table[element] +end + +-- }}} + +return helpers diff --git a/icons/cal/white/1.png b/icons/cal/white/1.png new file mode 100644 index 0000000000000000000000000000000000000000..90b696ca0820164118bea3af0df0f41b0b2ba4bb GIT binary patch literal 888 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 literal 0 HcmV?d00001 diff --git a/icons/cal/white/11.png b/icons/cal/white/11.png new file mode 100644 index 0000000000000000000000000000000000000000..cf43296120793006ccdeb2b08da06fba5bc629a2 GIT binary patch literal 2109 zcmZuz3pCUH8~<&LxlK$iE7yOGXrWwl8!=NGQmfn=ja)*CMdf8mWb{UQLyA{4ml(;V z*qE0HMH%(lTvoZZWTj@_n0NI*=l}ly=lnnCJkRGj&-0w~J>T!UyO>%( zRI1>YU*JrywnUuk(aj9A7c#C-D_o2k;_n%{6F0f%eVp16tlyhDAR~)0gAHKQ^%5JB zqrc1nM%@-J2OCihz|a}?hgp%1<4C4B(5m)RL}uzEPt=*@B&pBC<@qazW%jKd4O7Fm&+TxYiEFlBL{x&oeTR!e8+G=#Q*W?ezy59{UshHo{v=H!Gyg1XR>p#ehrM3{!93&r7l6W>G#5i8mdrFu zkgmonLHCfrBNnvgW~*Oyonpo^&s86quLRE2&g16J2aWu!&CZ^*iWv_t^04$%0+ukZ z7#KW>)0SXb;d!?Kr*v0yM@}d(zg$zx46fd7e-^jYs~Bw251*B z1;VUtV$Z%PLJBjR)IgSjb)l@I64`u6?TJfjzS`?sb23zwOC4!4xGW8jKDf%pI>niPq^rB zfD7VJbYxt-h_drN5NnBS%VsIL#Atu~qmnm_)Tc*OHPTa*6CpTT?W|zUn!q-7HHdr_ zp%f#UT2`Yi_~DL(Tj9f+*qvyl!NdpA#2(A&YS)y~R7;CDP zwY5J?9z@Vq`!W&zmU^!~xJzcJR|}RA&F;kTrCT{m^Yiod_(u$k1%k}b68r|BP^hS} zhWj5JA}X#vJ>esD_*<_GxW@MpE#_TdOU%Ss_AwRKuh?xq)(<(OhYeW!zf5|suWfcA z5Ei5k!`T*c8C_&}T?hzPA318Qf|jlvmnHLQ z&9p3fK?Rc4S=TuI3E=6owvvT%kgR;L5%omTk@LBQg<9MxeXs~k85{Gh0#)~o4mnkH zbW91Ke?i2>#TlTR%<*|)L&fJE2a_C6+rji!q-v&RWx<3k81jvUg@|3p8R1WAZ$HZV z>uhtZp*Yk(`fKQ5lri`wnn2iHm^~+(Mx)VO0Yg!jVMz`SSy)gYh!-y%*)ubMWLe;m zhK3GXrnLotnpI zM}BiA)**z#MSmUpL|#9k<*cTb*2Bd$+cU!N$0=K?)YjM6v$L~D>~9%*6~``3Ivl+q zrYqDZGAZ|!O{d56^73$AUT+$a2wmN|*R}pr_GnO;a_&<8wJnIP<#xG}&9=6-2CRCC zePSjVeODATc6x2C(8#+%mP-BOLttl6PI0l$QE}c%6J_7NJ5DK+R{x4cs05{+I$Ae8 zI)S&@N(*zAv9?M0bZ3T7B9Z7dA;#dH2ITd<6PeQK!SyK{$*=2(OBWQW_sp!UW;tS4 zAZwPluI#8+^rC^(3p=;SndwhfIPkocNeN-f2}(kfXz#Z0#iE4@AfB8MC;aFO)3%>a z#63Kg-P!5xio;`~KjY{j`(~OrCcSr_+QQ!GB#F(4O?-fEC8GpNjE*Rq4@>FIZDoQ<7q*{#PT zEoOfR(1=lV(!2Kf0 B!w3KX literal 0 HcmV?d00001 diff --git a/icons/cal/white/12.png b/icons/cal/white/12.png new file mode 100644 index 0000000000000000000000000000000000000000..42cf092c707630612ecda89455794e1cecd2579f GIT binary patch literal 2349 zcmZ9Oc{J4h7stOdgPAa)!6>Fs%CU}=HL{GQu~bxQq_Om5Uxq|k8cVh;Wf{wiog!06 zh9~4(luEV~m1PFm!kALortwVA?~mW}JfCy!=Y7xpoO{nb_ngn?^+`TqZ-o@zB@6%n z@|ZQwfv@D>h7jWK9ma0md=YZDvBL3{zt+uLuJdJEkoCC`01!d_HV9Bali>&9myg+5 zz{e1h!e}8sM2b29ARZsXnVt&&v{V@3CufD}IvT#vcCx$YfVThQ;|YY$zYYY zqnV46sieYb@mus;l>Ve# zqE{$sH`1n}wINP5cy~kT=^NOeEm1t)EdXI;vlmf{wLaeUznG!Xa z(g;_$y-v+k3-HGQih!wrd=elaLGF)zWXNdK`fNm3nH|<+sOuN@b5E!H`@Zt@^r=Xhv#`qoh&GwCY|Jmv2y}Brb1<&g zOzqyD(5lEh^$jz^hFOy1AgLLiw3>xX@yZ7#)yvo1Hy|7~`NgV-6i11L;GA@ zblCO=KI)D3%O0(nSJYNdBGX!;^IIKZVI|RXO_ux%tc~&A<+V0k{tgAk6*;1HT|g}7 zwq>$BW0&h|QeH3(2|9wBZH&f&NSN36Sju)+#GHRTLJ>_K{_zEF8DmtGSSXk#V@35$!O@BJLwziJo}Br@$w%X9Lrp-S&~CBYWj5qh zoh&gRNFHqTjLCJUJQa(IX2R$~0r16xlcWqM-j!WzWGBaL(ZL4BM}eTK1m9lB>Q$w= z<60uFGU24BTbeBUNk1s>Le>QF>V@(j7_cy5{!fOt0BarM2r^Y4WtsY0l2_kKBo&i&Ua=(j^l#ORTG!hH0Uoi;z-8ILxhg+SolkM188Is+{h;O%rW zd;NeraP24|&}1QE;2Q6AWgDSdlZdjNO#dcWiEMt9UjUG;js&(KxB_SM8|cS@u1WfW zuHWcOin{Y;>Nm1mb0z7A;odIiG;Qd4!8iQ-Fc}+Cf3EzL%D~td65n>dY>T*8jY}L} zawc>kJ3Tv-PpP zy}f$nE*|2STD@ODGI1(7Wi>UbPY^kHi0;mKu0Jb)jwsPNm~TrPaEUWal!saiFD)&R zD7-+~c&;W}@f@)ej>Y-fSy@?~9~cvE9h4tMk*8*X6fyBki<{EVPj0BQoD)iylizFZ zfZ(2u<)uw;y|4Y1QTDy50(d)r`Ca9f0joTrwEf(|jT)y~X~;f%0PiBSh!y<>XVnvI zuIo^xAbAF{5<9PJu^sAigi39|yKw?~p#^%^dU6Eum|InTdJT=M?b2$`&IY;*XeGB@d$a^*Cr@Y*Dl4A zo1EucGbC+Nf0my6Rd+(;(&1^HdvprFq0<2V{_0~te}%||r#@&YVL=I#D5|f8aj{rL z*6LLHFjYfk&4?|1=yZNj(a)&u5+-{EO5XK=eUQO{3KGk_S+%?-c;?N{YRH#Y;}dQP z2?>!lXQZaYSOJr+2E~ywt2wm=%*DLILMg~Q+53kN*wYX`+!1ndg4as%YAP|Lb7f`a zO;69daU25t9^+VD(oxkEVNdn$*py?pL}!^o?dseg zMj7gT!0`H+O)30C%wYFHb$!{qzFFU$;*U{lgrq8-==luh22bVvT4yJJ5W>;*5xQ}4 zaj9u(>x?z94MdyaLJ(nDiMh6^L}ke@IwJ?598y_2Ms?HP$B^CYHex;+eUyEr>8@R> z7*@$Ktg zdno}WrcTQmqo%hAaI>QQYZUrOj5C%vBXxKSjAC*o(I(=p_dSZAjfJ$6TiWYh6y9}e zRt=uLH`bA{VtCuf=+U8ES;CsuJbnV$*x2~cdR2S=a=~Q-J5SF8`L+qR`#ZSYBMl7= zlEQ*BGc(H4H~Eeb9DWjCnq9_!6o!T@b*O(ZpF}0U44nROrP2G|Z`N97-Rd{3whr=h zJ~>@3H7SsSQvMs~f1}i_W+2$+S;7691Bd?&@KW9wIGyevm`V3}8$d!1K8-yD`7hl2 b<+x&FhIMceqNd*OU(YcMd)xyv*Vw-R5;Zc~ literal 0 HcmV?d00001 diff --git a/icons/cal/white/13.png b/icons/cal/white/13.png new file mode 100644 index 0000000000000000000000000000000000000000..37db670cb71fecb2f2932981b09dae765adee205 GIT binary patch literal 2442 zcmZ8jdo+}L8-3r`%osGTky}EE3h7Kr3ga@aDI}Lnj5y@lsD=^7%uyspLiniA#S99$ zWFkx5ZFW}Xu9SiKyD_1v?(#{^o`Vs0FywrSJ546SStrb|(D6JCH!OXo zKIl#+EA0bDlUe4T{JFQ4>|H|-d@c?{(mGZ z;1@Jb8boUX=Kr7kr|F0fp@l5GnOLc##OZv8lpRdgXFohcX0?j^n{R>P0!^Qm*Qsw_ zzkc_5LtaY#^bZODEc$!q28;$c&ZjS(r>H7S)5R(=GYY|Ha;+_*u zAS(SQ@1;a#g2uF2Xyi|AxWIeIo5Ptg)M zJennkeQM%kM2hAcHR8_22v`oRC=l@$y@U2A@U8%b+tv&gz2Q}j_al;o5}!Iqf6<7< zRA{xhAe*mvM$Th-6pWRioMiaCE5=0KpG?~Kpcz`*x+nv8%4{B!V4F9m0d-*WD(g(D zxJD+TC4}oEGAEj7p=kEdQ@8T58(hsnliWp8o73x{@3g^2@j~t?M?;1vOJ|AKr`6PT z9&#=5k=y{;2NM^*_0v0XW~8b-^l=KbQ;kC&UU$bQH><5R>SN*#OfL>7ruw|u4foe~ zN~dTWxFJ)Io_LOIa_mn?FcumA>#3$m8(+Wq>O3>x=^R1q&?l~@oPnd)$hBC=47f3V+?1I$Hm|-%9fkE zX)U;1(x6=L86J6AP`nI0--vy=0HqWu!PrRu9*)GGOHkhcqCbOsv?}b%3;P9o~C+u+9ev`ym)53}d1=37qdvWm+ zaGDV26rcio^FO%z*4V+4XSL&%6jxW(Z+Cah@TqVd>v^)l<-=vbJ#kW}5*$v{Tda8* zT!;=ecLY`epB23}2~6|acgY~0OrpEtZD8*J$mNX2ZrQ|!t#!!+STIrIUUgR(VjC`p z7hW*tP^QEQ;;*0hU3DSbBaU*u`2X=LlA}u6AN+O|%aPbE>r9?F`4R3Nx>CF8lUKO^HbT>iMzRWRQdm+e-8F1+FeSC|$U61J>Btb-fR>x=&UPCB>day=$d z%s{8sw*{4^W^#oproP7`yKSboOl5WA=l=Mkf}-IUYfq;)YW#E3p3g!( zhwO6A=N0NDEiFeiY5rocH_T*dM2ze5OSa--Vq%8u*z&azHRTgNvwctGz&lI`Fr4R0 z2gkR*Hh5%~-+2RgbqFEXYTdK@U1#lx(SZXR5V~bpz z12`$NU)kPGp*CVNxO@Fp{VfhQ5RziwMR+@`{yeY^s+b%iE$$|U++F_F zd7LQ?u3b`4EUQu@Zc+3$uvxT+A8^{y&0M3KH%^n>86)Qa=c#b&)G5Y6s@5o~Nojdc0m6tplQqSY z23s{~16YCNMx;V?wStG~kt2K5)a}(`zBorN3{87hX&y3VP4JFd4oqZBPY221df4S1 zpFgw2xH(Fa(W4VsEcRZrIYRoYXy8w`Fb`0><_^_$M9vSKUQJ+SUu6nyjCr!)&^r5G z`Zu!T9_b(~H74e$P)V&My4UgpCv#H)JV;B5;sp?iw6QT?xtrDK9U@Ct(S>x(OKv-3 z&V~=|C0_Q2u2%_8l2wSIp^rDF!dOl#QBa6x>~F?!j0W$nb=y9VgK08`CC3cL-?Suk zoNbVBwtV)4lkcQryaS|K+&({IxV1FDcBw_*Y`{xrs{+F#nk<0_#ypL#4gNClFd|c* zE>)-*cdVmB#Pak5q+!9P<;>`wFE9)j@{rERj1vt&_?Pv^+t$jdK0TTgur_Ycyv>A= zAb#A4E4^eG*|% zXjj#GBmG{bnq52jn79PIt2Xg{&1;|P!3K#~d2N21vG$V9wVIb!yTKg`S_R5vGt!)e zH&(=!O?LygfX&HE>-r?AU~u}D5mqw}a*{D~V0FI@2L$JhknK)hFT+8BTvX&PPhb<{ zSPnoO;R9sF79>~^pEzLg-o2h{`R8i1 z>x<1!79;bgV6Q zmrMVneK|27ecwNi73j_wHJER|eKcWU;*wTyqhK$r$>;6u3EHWBBr5hdJJ(-xm|y2U za<``7Q7BZUu0%(b&Tadenws>^fFmTBhE}J6%(5)E9OLn6vRI!4(%Bc=$BbghZQoIFvP3TxA= z!WA8t7zyVZh2}=9MJbPt9B;`KzxzP@<<6_NcWd9j{U3eyLg}vj`JY3t?%lpBzg6s` z#PP;n-dQ=@1da*rJd-~^=+12q22KT)h6xN#OdWD52a@kxc~sqE85jT7Q0ubg+5Dr) zYqXBfVrpR#5OVNfP-Mixn9|kAlY303B{#h)a6fm3{@N$klh-h8mO@jna)&*mqjiI4 zW{&*ZbL-t0d>NgXIAGR88H>avPP}fc?5RCqd0?%i^S%uN`(EGrxNAMrG?g}A#@}ai z!kGTdH$A|7pjq)iFpjGw=Y6m0clnyvlk?bk!` z@kfsA{Jr&nUM%Yp@w()_AF{hd4H@cj`<#g*tF0Fzx$jv95Mg;|EI6G8z{X|pzg%O zJNrc=<_mnXEYRE#p?u(FrTB_#-2bgM+;OU~SblUrONE``8_!RBk1yJ-+|X+9&@hhE zCz9iM(Y)D)5B{`#0|xY=yX>kC$(;N24y4}SdqB1`ardsNmz8`OU3Wa&&rxA$_{P@w z_m+R(7qDoURX4hFzO8?L|2NYw6^Fv=|920>0+pYA)A5d3WdD!u#_7U``AiIBJsReG z5=!8F>(3OuYv=NKrZe&H_Y3b(H_TZ+Q&#s^`TO9Hf1Ms&J+h&{A^g;bzotwFxDOl! zs%H2;J2I3>WdHYkhIigP)pyS9)A#24Rkh>CbH?97htddmJOp2g<5w11;hu4Q>+>xbEFA1ptIGp2Q0 zF(oL@`E&k%Xx8f|TKoK%T9JK%S{59MNr~i*d1aUvw(6AUw7(2a!KhB{DEc72Qp9db TyViOQP*LgW>gTe~DWM4fJyKGN literal 0 HcmV?d00001 diff --git a/icons/cal/white/15.png b/icons/cal/white/15.png new file mode 100644 index 0000000000000000000000000000000000000000..64418a6f659edbd1e1976f646525cb8b96491828 GIT binary patch literal 1711 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 literal 0 HcmV?d00001 diff --git a/icons/cal/white/17.png b/icons/cal/white/17.png new file mode 100644 index 0000000000000000000000000000000000000000..033b5ff1b827df2f072642522c44e4612ae74553 GIT binary patch literal 1435 zcmZ`(dr*=I5dS_vKsYQgE7J~BNT(=Gd?e)yAu;oHSL34;d(oNC4n0i^Q0p|y%rX>F zvxnK4ikF)CNV#dcN`u%^on0;OeZ4MkM4 zUjP#|ie81WF^|}kY!3iNc76=+y=gDh<@@iL?X%43s+&H-G4j?Ay7y4fB)g|MS(o2e z(i7cN29@`|ZD&`|eD}z$uq*m;ZC+t3$aF?9L1K z>hPED8FJZ&?75`jx$z8n#CRfSUKT~g(MV}sV2S55YplE#mrGhq&1-uw#sZA3NPhvE?*#50H0urr921TPk_0sKm`H?Px0Xzn;Igoe(S zu2DqNRO1t;;U$XIUk))Y&H+~r^==7v{iz^9E4dH6Fhc*g{{JMGrYJuCC`QDU&=*XMZ!`BbZpaIwECPxpVU`f?3+oV{rc2pKtDhAwEd@ zkdPzJC*LsI*N5cQw{M(3ATnK5gX>1W0|{Vmpn- z>PrDJm$CzM0kBO8&my*^&sxxl4IVd=TSWn@w%IYGOrYBQqb9IEcw=VY=A@OW)TF51 z(sHQ<)49O`l(in5X!k?%);qi`+b?{b7j^H5ich(bd{&enIDP3HY(#TJ2^mNyI0 zqa|)F;+Y>~8M>Uz>o+VSK0UVLCitF3Rjj1*kLZRlEwtjc+a8niCPY!rVK9xyk`Kp)0(SSQrLr>To6?#nmk5~ULyadPM0Z)F z76Mb#7jrcQ@SuO%CJB{u8ltHP8j{CVBkt_d_4S5RK}yi|kAzBB6+4l$!@wSnC^HLj zE$POv1ieaq5<`{2xgP*4y7stGMP$X0NnQtZ)y&&^AL>hMu%-~A+RRk!iD#0$PN>G? zI7C0e-(1_IT_f5hLglcAAH%UA8xF>9f4E6i3@j-5l!fXv@D#km2AmN?-qhILg7n*Z z+X(K4OTZMzI4OcLilOcxf!*bhN}7$Y>Vipbb@B+687g)R2SxUBe@^^CewqO*5?4uo z!KVai50w@pST;+1W!p0&LglMhxH3YBwpOIR3QPs+Pe|eTs>QdHPWHx%MU8~o=t(j# z=v^Dy;@)irA-TKY{GE(`8LxP``NC68L7~*pnv|?e#HUC^BU_DwA zTrU)zwg+cK&_?5cxy!)ESJ*Pk5N!fJNLzasShPM4<$bOlwk^gLjeag7u5Tx7-?kW= zQ}?Ewyfj&hGKLF?t5v- zBBe1v>WqJ4f{Q+0n5wORz8c^ryvfyzM>2;pNiT+Wr^cYzs7yNStHNPcU4A!{nytkS n?i;*???|k%Xu^IeG$B|B3_=D%{Uec8%Npy)3}n>PqqF`6n@M)6 literal 0 HcmV?d00001 diff --git a/icons/cal/white/18.png b/icons/cal/white/18.png new file mode 100644 index 0000000000000000000000000000000000000000..817c4267d2d8d6fe36ae370c388aeae0f79c86d2 GIT binary patch literal 2207 zcmaKudoa+i0&kz$) z8q?nBT{bQePs)BV;q=xcAR{Sz)$ZzbcikvUhQ{s$!lCesbn@eCf8r&bo`-MNzT=A+ z@E&a5AIA)~=0?6W4gCDkw0oGdHTRVJp}J{&eW_{uL_$qd$7w0#>`C$`qjJvi9B%rt zfep;8_w-~dU;xfRP5uQ;zZTN(WNP1RF!tQ=Q+!VYTrYxj+s~-Q?S7Yhy?&oIs;$#x?@z9yq$Emvw@dsxFs!HBTSm z)z?R=%7X+OH%wwQ!89Yb6+v=Zva=hizaC27$sb55QASi7H$)z=0+4>SX-rXpb1?q+ z9kcy9uU9C}p{A-1Min6m5OfbcxegZS$z(56cy}3NM#==YZ_dVdi+hTMH!82Bg;4{6 zqB{GtPcu*>%?UzLk~p$EbvE{KsCR6t#metY<+uvbfp+a?yH^e%8$7qOdVTn+{<7?O z<=)Jk-)%;JU^Czv?2D(~gU_{D)y>kD-Z8u48dIRe9I1IAyrwjbvCsb1rp36<=8;h@ zE01L;GuFh!BtR5(y*5=4iRP+{8H^m|WAX1EPcWV2e-@2rLWBRDo9@y$=t7^GchJ~*CqJRR04lo>&b2HI~YOT1*1SYkEx|BkN(_dv2!XldL6@7aR{c5 z_v$di45}Ubw(W96q1(cmOG|(u*)^qH$5nuh8KxFYP9NwfP=WM4mmgM{@&d({#|2uI zxn`W;#Ei5VRHCkG<~;+;D%#ydp)gOY5%GyrRNPfJfm*=fu9~MaGde*Jkgno0c=7$B zaU-12%q&}9lAtdAEa^IbYQ|s>?7#^CuL$a+-f#oK1x|2Np1u(-Z&EG*hNGDOjAcot zb6~!^ppGCNpQJvG(z|4*W)9P1Jpa7c@_rM`melsU;c#DjW>;5zDAtE`F$^I0#P*)zCS3y)neslbcjq2RV$o38aZn*0YL64=QP z1g5|>b&Y^Md>T%14l3&-I5tooceTp$Y#F3#sG1GeD&w;mF5J*l>U;=K(%I>y6Hh{} zcqJ`KiI4l@tjIVI73lE2@M8m-_2)AZk6gC(K1B`e0BYXqjON~}gOu5?U%{qx+1>bd z)k9C@fQ+N@ZLi^{xm*i@hGCiyn2!CZ=&y9gcT|B_XsI^i*g3&D8Vxzon?j(BKheP# z)x6CpEIo<;np_|~W+E-fMvf>P%9ScJynmuA`J0WwLK`qtx5dU%mqHltZ{zje?fjB= z_?&3O_Ky7FH;=*x(tXqqLN@lPE-schn?^zu0v!BXLr{G`2>z{OMDUCVvjGd~6h6I2 z26;Y8{L5MYRyiU#U$1FA{SMWaK=p53*lro^?_=Uqm&?RIN&p?d`U7y<*4~ z?)qM1LYD--k6 z8|CmtRXixxeE6sPoo`E!`JHX{jbq;ti}3l8zh+-5Od=9JM%8R=-#_X78oSXTA20Ld zZsq156g}ycG}ShtsebyI+#6DxhF}omWlqFL1J(}FRfl#Zg7quql$B8=QT1H_Bj!dl z*Aq<+^H-~M+u?Q1rKeR~a12>XL#}-n(R5gMo6IA=jR3;{&At+}^1Uwocl0dYPO>R; znnS(b-JgfwGM$QViLkKmTAn*Vj=t{0dQb*;%?YWOLNg2>D7faJ2qL66RY3{alpjbu z{o4pHE;$b)*_oSIKi^77U4@kllt+Btstb@@qh?R3f2=!m=y*KV)qC~x@y&ylTbZ5N z;y0qe4P-g3M2ciA`Ga18*U1Qz8NVr&YF5-uT|Q|^pM(BSnEfZ)8V@#giszqF<$SL` qj2>@?%)VkJ+obpd&A@=wH literal 0 HcmV?d00001 diff --git a/icons/cal/white/19.png b/icons/cal/white/19.png new file mode 100644 index 0000000000000000000000000000000000000000..0e6dafcc9ff661f86836c6746265b9d2bb34f20e GIT binary patch literal 2062 zcmZ8ic{tPy7yivKVt&**?M*buBZ6nL*mnO$)}BTavb+ zBs;&jrH5fGr7Xj*WXUpwn3&<4o^N@+`<>@`&wI{!&U4=L-+RTCLX_R2vIPJDSx1un zQ86=r0)-UkR;$1cF(HG0N&r*a#E938G(=CNLIIVd9e_~lIRCx%K&J-OIuGU@6Y z!y9GqgCZ6rE??2k#gp!3E(RU#expstWFFt;fzjVddRq0gq#b9!JwW!0g_2WNcE^3H z=*;29sm3|}0E_o^b~7h(urwjQi?fu!M3@XYzI?f@MhS1(?sd!u<%_9mXwsQdkTX{} z1V^E_Yca0_K`7;Kc&`L>i>X8a#+UUj7(s>h99#$|dU{=H)RpWXj2!W4I@Cr%Dw zTgLlD5Bd=vWWx_1f+Jzu^k5exrrWXuD>*W+>1C1w#@h$)bZuKtkMkBT*SV=0;szSjV(QqHNk)hjU zjF&K{vqp(x~Pto?9Wma$9ZrCNmCfOE0Fj=m*fhDI=oJuKIzi z$@!hL4pp$y<|XbbeqJ&@7L&+ifu9NKRI0y(g-qnsPJw%m-i0O@t(!;mgbNvvA;5-N zxu({M3c*#TgOX5a8}PV(6m~)^D-(x?jOg9L4LE_bbIK+f8o8Qc%}Qs^@teZ-AQtdB z2^mAlr@{3Ic>#vHiLIzDYh8c!6-?sO`Q0eU=-T;=gUSBzdA8e9u<=4IOwAlvty#Zu zSQ;{7FW^@J-*lu~;o6cH?y1nm2q&=V84D`{G{%A;9C)s3CawhgV@>5B?=&;&UeK=!KqUvbW}$PIS-{52TYgSN_*u*&nfz0bTdc%qZ@CYkIgVat2o z!o!(3Ge@Zlg}CHQ&}s#HSS1i>{3?_ z$JVdwI&XuH75hoj-7$hHtgSWiuaSZQbzWbqQFTZO%SN*(cO`EBN86gdU<;}JVLN0Z zE^=lFy+?pXj@h8B8bFyN@CeWcXFXVjyoO4^!j8_-ne3!cv+SgQ*t!tBc(F*Q?2JdOHyI!q--w~9E)c2K<*g7S&*agMY0j9X-*--N zpr3j}nn|$EsUrcHidLTa^`dXq0ij&VmbGw@NUF@pS;^&!JpC{KsR(k0dC`(hw|;EX zf%_X+)vVtufwB8^sUyMTaG50}M%5`YpwR7>Oo+?*+kjFwT#8x#&LUr-I0zjDr+bg- z*GZNYxxg8Z!bes}%xQA6U5Vq}gx|8O(0WBOJ7F7pUs*wk&;!%AMbq$> zP0VT_zV7SMjur;`T6g)v8&0IWWF<9D_4DlW*hL-q1;5_y-DApM8M|Rfoff+By2Tmo za8^Gz*-l+cUFWo3ocb@LoPHo080ibaZtdYYJ&Jtc_T||SQZ+gA_4$+-$I7ez+5;elT9uSE#9R8($5yer(~PAZrQny0@fR+VB1|wc${WyTb0^`+!w!3ngvW2YmA#61Ed2V zw9(Mv)Tb}gx>xYNC0BAQ^)IyU*5HRirX}ONN|Jk>9QM1w2GRum(~GTF=G_ibH@UwB zYHx}{Cf#C;B6!FO`K=;u^H50|_7d6hnvW#=?U50^#n@qle(979-2;eXd+ z{>^Ou>pCVy6lCf|LdN6Rhk1@2!I3kBvMvAXN+iHYQ7C-{t2M8Aa);JWTX%Gz*t2Z| GQvL}B_QKWx literal 0 HcmV?d00001 diff --git a/icons/cal/white/2.png b/icons/cal/white/2.png new file mode 100644 index 0000000000000000000000000000000000000000..b93789a59ad776ad87b50024d765abfe4b9258ee GIT binary patch literal 1553 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 RROQfZ0+wcW*k`6V@;{z-^c4UA literal 0 HcmV?d00001 diff --git a/icons/cal/white/21.png b/icons/cal/white/21.png new file mode 100644 index 0000000000000000000000000000000000000000..79a74f3d2ba82322a3ae7fb7be95ac6805f77747 GIT binary patch literal 2092 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 b$FI6mP9E&~mrMu9*8yMe0I%Ae^z?rND^aSB literal 0 HcmV?d00001 diff --git a/icons/cal/white/22.png b/icons/cal/white/22.png new file mode 100644 index 0000000000000000000000000000000000000000..e8845ce2e8950e7a773d7fd9dad893f3f490882c GIT binary patch literal 2060 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 literal 0 HcmV?d00001 diff --git a/icons/cal/white/23.png b/icons/cal/white/23.png new file mode 100644 index 0000000000000000000000000000000000000000..a8d4dfb6dc75657f4b5b9cd07704bafc0b779340 GIT binary patch literal 2495 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 literal 0 HcmV?d00001 diff --git a/icons/cal/white/24.png b/icons/cal/white/24.png new file mode 100644 index 0000000000000000000000000000000000000000..1a3b38ad29f89a08702f67ddb9cc2d37126673f4 GIT binary patch literal 2280 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 skY#85i2>&$&h_-vzcflVR{#J2 literal 0 HcmV?d00001 diff --git a/icons/cal/white/26.png b/icons/cal/white/26.png new file mode 100644 index 0000000000000000000000000000000000000000..f26731bbf41bb4fcebae8d075310abc25128c299 GIT binary patch literal 2645 zcmZuzdpOgJ8~<)Lvl&7*avye(+%M&RGPjdN$CpI4#3*;ATvoQjVeXf1GTPLsvD}^{ z$?e;9bV!}fP=;lygJ`78{pbAkyPV(qJfHXTJn!>)-{<}7eLuN=zMgWJ9T)%rh(wjg~ljpLO^y5*?#CnyXGJPVI%~B;c+eq$(=PfTRB747kg<-^w0R+$RN1glvEpuzb_m}W58+Vp>OeRhhw=lBb zJAQwc&Pvzn9_Xt||8%``a4dSgE4_YvrJh%-N37^Km2xiqRHj(gYx2bK_m%oq~pk4I&0Uwt>d4$HW*(;Y39`x)ytau0NH5B9H#nj{c-sJ z77MsHsu|HA_YtiuhH~zk=^UB(vysxA?3&;5k7h+(`4W6@c*EUOKE?NDh7JQW@U0d8 z&&b2<>PjsSaE2b|s;9Ft?m$06SYRDCXK?SM?DKkNz+C`1i=e8i!m-jTu*i?6E(d(m zX_6g=*8zcyp5Il%hi#!YsQr9!@#Y-t4BUQo{M*I~hZG(FqFq4;DG_~!Mt2>N=^c@B zS|3n>V!%<1Bf4)}sZ&JM;!(&3;?VNxXBEqe>ndcX3aR>l-K8I_H)SCA_Qagn;3F6QEY`b=nYp*LYqec#W?>f zh8>tXsloJ&FabR{n>3MhG|V}l`LI(hC8K8kKo~B;T<1te_ZYjpwHt4)`)4G= z6jz%2A#Uwn2tb-dF0kU2%RZTcM*yFK@_TZxT6%P+t#9lHwK-^2Qvx%3kGvmd5P3V= zWMcLUsz7e>vst~qh%*NNt*0CQCfRhNVydf!@mM~7Eof&wVP^|ca*q7a2|2d$HSx`m zf13eo9&GUi4>aR+_E^%VDrBh}$v05c!2F)D_`lMGdJpz6x}f&8FV3zga5OVy@}aVX zsjbwAD{b`wUdyO4wdd!vsG^M;`Dj`5XX+QQ3HXGg*Js*SSWA-QQ{m)BZUdrAkI>y} z%HAz4{oC6>QYG8%siQV>Y-ar9ugC({fSDR{%@<_(@tujZwe>SjagQPb0`ZcyJes2? zP`qqsZ<^et^7aPT?i!GE+DQC;J3>59b8Nrm*L5Fq1grdGgj@E{b?}G&Z^-P>MS$PyrZDY*r$n73$R4YgK z;Y&YiM5txSYJ9_X@PZ#0iPdagBPF`ydqZQKvQh~P90GG_cMMEAujhPQfr1Vpnx+7_ z6el)DNB5%2_Z@nwK+e?m#Jg2)Yz{yMgu9(J>baj4OJ74~@Go|*-~cxbRx^EsbZq`~ zC6OGSb&FpO-;EV)OEG^Iz;b?i)a}k;fSaZ#?uRCGI_8;#@AbNlIt1okrMwj3=J>#U%H&i2<}e+*Zz6>v+C%N_hBqt z=@a@C)9t7*D^HsMcqe5ybzLrW(Q0KAtaVycR71(P%?fesd@fPZ2^;J#IHh4Y3m8ikp(4lYf5v5WiIs~5 zpQ6%!S%|j~`HUm zU&$G%xrho~bUbWP>mheTZ7gy!Q0CtPE@Uw@{P}I9W2pk5&W}Ih9_~v|YtxXZ&AsB5 zL~fpZE9(lT!v~ZyZpEf2u`F>p`=JgE);iGo$ZEQl9GiHIY@ubxT;3_PQ9S9-Z{9QC zZ>TJzKs~QlC=%^ZvfW4>lSKa9RaweYiwWe{ZXfe3$(N<)tdD!HofSVvTu zPeGh=O})EZ@sWn$QJ{B6sJH5-YQml3LsvQhQ?|WCV@{U)f_{>);B)xe$ddH+hbldA zkxWSIRsDSL<$^F}*EmJTnVhE8!&8d36SyiZE7-m3GJ)@j=PUM6XWSw7L2B@AG`mUW zC_*~*fMaYC>|9}s5S+Pm~x*joTo=6Lo{ zcFq+*5zyBS@@!zWZ}Z!|M?X?~!--*&Byi;Y<4z~~+yl^oBO1hhMxI@5IAPbM8THdh zJL*-;{UUh2mwF#HS0a-m=}t}S_F!8CeYpBqQqM=K{(!B!EUvS~)Fl3=CHgNvaua7r tF=cZo&3biQ?!~a%nR5U1EH~{XW(uV%>sKyYFZ}Hez1@9D4SUJI{0p5+sm}la literal 0 HcmV?d00001 diff --git a/icons/cal/white/27.png b/icons/cal/white/27.png new file mode 100644 index 0000000000000000000000000000000000000000..e4dde7700dd2c86fed2c94ec070f3fb751ced45b GIT binary patch literal 2044 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 Ie1H)54|_xGTmS$7 literal 0 HcmV?d00001 diff --git a/icons/cal/white/29.png b/icons/cal/white/29.png new file mode 100644 index 0000000000000000000000000000000000000000..e9a74f8be9e55a8e7db753e3689354dea3f9028f GIT binary patch literal 2597 zcmaJ@XHb)g7X1~aC)iDYEwqE(oC50`{ z3P>|2A5>qdJ5pgim=PwlYcHCE7e)!yspwCb@~+=xL||*kO}Xy7)+0!FAxO#MXWA)7 z!-z~#PZ&c3>zvIMQhcjLtd2uhtF8P3q?X)KZOvV9&etrr0{lkop{Yyi<&T8diH{V3 zCpzow#34tVb1#+?2vNjBu)))*4`lsJ0KH%#Kt%~7U`B=!=yVuu{!4>ctp2u3^{gY7 z0&c(3V_%g78#rUtVir|w?XgcluO~jaJm4OH5?^qC7Pkp=E?XqH2SZlx|1lNRFPT*g ziWmJh>B$IoDzOl$w043IX9B&wA3Msm)}x$O^43``>f2w-FlVuNnTSCWAlvonCyPX^ zIdndqvxr$ByVeEDxFOgkm3fz&D*G1HX{);BRn!&kICQdJoIsWV@YxCwB;n~XR@f@fiy{xZk<1rH2XncWmXb?e%rl2D>~*C6DMGOz(E@ul;0 z%Jjgwt7!NA(RVu7U621@ZxGuufR5tdMM~X^aAifwsd+8dtSKxc%qSUYtvL#eq?1D!0)E$z{faGV~PG|(AieicSFsn4IdoNq?c zr6)Pmr;;x()r-?Ku}kNU@Gyy!^3O4Tzdmyc6na=ni}t;hOpTqee13H`HBJ5P#Uogl z_TF;xIIl4}n|QW;E=U+hBp;l-TfWA@FVUZS%?BQoy1_c4yfarNXj7dF#M}Y2ABCKX zdtL;O0frLsn)t#aU-sM$sh zldE~>@9!#XsS*C7utwv9dQr2V`I@K&8hsFIkJ_CjH=vO{t`&X4EN=`mi%oJF6`~7A z)hE2kgZ=4u>H8WVXU2!-*3jhhYZW&jo7yk*WadROH-+rbwaCTS?HNTbhP>E}lRa}t zFCnFAPjO?|J>T6vsmuzMDXA`t*!Z#_#~ZG5+6`qvkK;lh8amBouZ02HzR2*$(fgaA zDx|geC?)xY1;OYMZlWa>)2Qt|)Y})}IyU7_;HF`cqixV=8<}5Q0y`4RL45z2Meh-6 z^2^)QQKa$sGv5g@?bog6c26>tXAD=>Zyr4Z@dRA;$Lh`Tkma9-LwIolE8WamdY61P zn7WjYqOO@Tb{z$ZN*1?BJ*Z;IwORv>y3@ZqDA*sN7^)v;FLyTKy^&9^+ZGtDyEx^V zWX)VlTpqszZbL5Gk6b^PBKd!QlpM;d%{cI)DSVjiBX=Z43X{p;;vub;@_iYap!A~v z^gtLC>`7rBl>$;xs|R5ug+Z#fqZaPhjbW|+1uW)^h)1%l^3!5pUOE0s(f{RrPb!$oF}D{JH9C*Y?DjYE~AYiU#-)ld9NeJRP8xN zPje`$FvRGUGNiSDpI6reTj;pYC;v4-?7GOqT0#}=LY1v(tvPSaR*KSqim|U{PwFdaRXEXt`+>2?F_ue=1pDELk_@+oJEWfyBbYLsmS;#; z1lzo0{!2oF5sj0g@P_fER4 zIIFGl;A^_~uBC+RYf1U4m7%$js<6iU7*2X~4{~7&JK7WG3#~tyVOYXi572TtS>0#{5fYF5&O;MFA z8(a+HNN`Ox71xvyPSJ1CT32NV`-%-zBkqj367P#6J{e}}CfX)^4IbL%n3<($<9!tE z6X(>8Q$xSoWWv%s`4Y}?T`AFS&zDSzb5TkdDe@QPY|QXx+TZJK)HTt0O|;qouD|?c zGmJx#V?xBgHbXEgJ6p(j{M|lh#;H~og#Knpb7)Ziz=IfGIC1Za)4k)3?`ZAQJI(Pt zZY>DUT)7=I6DHV_QGR^Z-PNOI2$d zUD@iSZ^_K&VjCvHn;9lDHQVdM2zRq%&RGNUngSkj^FL`x$0|+5-gKc;S8s0^Hm3_F zL`FsL1zWhROv@tDj`kzAgIEFT#wiN;L3&(w6VbU@=(oqt?_e3ZIQPm#xz2gW{|PPq zzyJ1@fOl6*i@E&EC8;;AArV?Ts{aZpi%Cb2Z;p#W-&C8_{z-dQ7&~-@DK_bEgwVu3 literal 0 HcmV?d00001 diff --git a/icons/cal/white/3.png b/icons/cal/white/3.png new file mode 100644 index 0000000000000000000000000000000000000000..11242710cb04449563e2e6c56440d9f19c8afbe1 GIT binary patch literal 1808 zcmZ{lc~p~U7RJAPNm!Dh^n(!Dkr0ZsfK(9#0a+4~7-cD2uz(qYGRzPNWea;!EL$OB zaG@YYM`{WP1Vs~}C20wWMGTuDdqyh=A_hT?D9~^^bNbiZbDsD2ocEslzW+V9B+#Fv zgEB?|0H8x56TVQBvm-4H_1W$D_kJ}rVyGm7n(BJz+nKM1Hj5mQ0sv_J9l?O=ONQ!8 z%~Z-UqUMYiM*DNk$%{q3>cLtH!8?RK`J(n;#ipUgg>@9S8rid~O+v`1xa6W?E1PsP zIVwNlsMDT*vxx*KpY01Fq0{VcyZ3jW*F8KL9s#9J&@p<}M$lCllA$$AEdM2=Y#iTP z7N0+=tzUf~->|aSGP3Czc;9g*GSr{&XbZh-qr~)U}Z>0td#cuOcar+ zIlD$6L>`|0HhPz1hf}bGzrh*c{qNr?wAKhArp@Hip83)-X7!trQ z!gm3|RMQxDR?cK1xWvbTxmPDlKa7(95pr|2d86znG69==jmJnpV_-LHEb zKLg|-+}%;-bA7f_9Aypv(9SE)Bp+0oE48Kqei&PF>qOIV@d4;T*DaLk&@b}CW~#dS zRdaZ1q5RXp!u?zUms(vM`y}|#I?RMS$H^j$+Do+vG8DxEp1;Hja=5VWL--*2Ju~5` z&P#{Oh`nL;rn>c?m)r$BK9yQ7?i&T$zjNUv9a$D(RV_Uy@AQG~`KCf6)wWhr1H7M` zDUFcE(tSD-E}=|Omw?C%v*V+o-1^)cgTe0-71f23W=(U=d6I0YFepQ(s>*NX38xkJ z*i2zWiG$0*pjUN^WvDc&hm{oP)i9I?nj`0fr)O&RG+?2EFNx*eiiLI^C&IZNz5@bl zINCgB@8z0k-zIM?R%tv^c+;=dZ)KZX z#XU9V<=5BM*n53nF8NHEr1+rMsS9i$3CE|QE5f@iG$K)v#N=SX-_H2S3Qgsbu^ydl z1Z&zkdeZFRZsy&fY4kq|w?>(CSmTJQlKXbbv2XL^DicUDe>{99%Yel;dB6m!9y-2G zfMuQTk!nM$K|TG8C6}=`xiPl}U7=N?#?#k?z;844*mfeS2YS#g5ez%h(Fd+O1alVf z_LZqOkk6w0HKHq>M!?vEs(7dqK;s95z{AJ(is#O`V|ax%C2pP;6y>UK2+dL4ig6}n zt8C!?ekZdWH>K#4=P`Q9pX%>HZL?sA@7Lb+0q5xB@avNsy8Jir7DUUn52a6Xxh8vF zVZ`XZqZbZ9s~K9=9ta7b$`ojXIEUk52hM?WuRIkDn z%Y=ItfzGSHhx34UN0cT)2jb})E}31ah`zcSTRp#wTR;Q}pk#c3kIzA}@i@<*ndLVdr-bX$kQsRnc&1$tC(_EoSwsG;UN+i+W8}^)2 zV9R$qc7<&5wg`JJ-d;EemgT7|F5;v-M=mb+%R^#j_E0Z_Gv-(jb2jcg4Fhf8Z^oq< zD1ItEA7}Q!U^;9*HvKrk&MM`G{%)KzNj8CzzseR3SV+JsBWRo?(@lj<_#;U&pVEj< zBPqivb}P}+gu4yo^NO!p#n?s>##{=9Urgm)J~3R5Im54^w6WF*bP>O33&Gx><{~G` zM5(rS=5&^)_}49)5m~NGvaxU5Zwo5S;v0W>pSIM(R?lrq>qAAJKj;a}l8p|F-cB%v z^{IAVMOIQF16eBIv`#k;y%DfO+@+rs4tJhGrX%xahHmA~45}v3fj(9L=~_4}K5yvp zjRYEfLIZa4`_CjD>?9l8#OJiuio!K?2B3tm5Pv0i7m93Z7td>IJhWIDl5s$c{;P$R buA?MyJa+1G>;y)k-dzBN=uc?zp@01chCUUL literal 0 HcmV?d00001 diff --git a/icons/cal/white/30.png b/icons/cal/white/30.png new file mode 100644 index 0000000000000000000000000000000000000000..8147d78f042bc2918a7cb6b8ff0f482c91a8f363 GIT binary patch literal 2912 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 literal 0 HcmV?d00001 diff --git a/icons/cal/white/4.png b/icons/cal/white/4.png new file mode 100644 index 0000000000000000000000000000000000000000..16713bcd6729a74a11856b7199365bffe6fd3689 GIT binary patch literal 1140 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSY)RhkE5z6j+Ogmui>jeZt3s22<3V}Oe`f1qEoSGKbmzqE z{L(BazNlNSNaNa>>~&z5Mu=-`BYw2q*t`BH9vxl?dUP!oxL)tlp_l&E3OXrFvh;O)R0uqVi-;>d$Es{_Z z`DOQkrOS4l0j&kS@N8n^&$yGu~soHscl->xnb62j;RW&S$pQJYX=Xp7(=S z;te~kI1%G5Tm>9E_AK}d^oSGtd43ItpZESN6qG04*lFAx)-X@~zt)4Thc@&pJ=*;7 zKal@fY{Rw%fAjwo#~#pPeewQYy?sG^;*EbDKW@o4*orF{UuVo0X_JjURlx*K z?hm`Eb)e+?zugV(T!-g%cD(l~Jr8vK>4w9tiS9~|He|}Vv08A%L|^#F@?nLhTm!?* zO7;&Ci8t1D{J1CbJ*MGI%;7^y{mT?`^pxxj_8wlrpwB4Hee3_8o-Ck??*7haE)#3B zl@zp}b!(~NtAbDZiHVuzolDdk*3Ps%+wGWl=FESq`4^bxyBs;rwZTY+Ay1=cCsRe% zsoPr9{nia+e))Y6KoO$&24hv2ZRsk@au#4rz=SRI^ zjB3v$z`y6IizPRGC)t-6wGQ;0tz>EZSFVNNf%ztL{&fIx- pos^ny+AkH}c4$TeWw(`W_Kam!@6_TZ*%yHd4^LM=mvv4FO#nI&@%8`! literal 0 HcmV?d00001 diff --git a/icons/cal/white/5.png b/icons/cal/white/5.png new file mode 100644 index 0000000000000000000000000000000000000000..466aa7122c025b1983de187ae9d2e565380fbd6e GIT binary patch literal 1437 zcmZvcdo+}37{I@|G0ilr(ilv|Sc>Gb8n@iaOlFdy!B!L_qS?q;+I9EQ$$pK?I77LO zTP|JXQllgr-$7C#iAXUcjdD#Zxzw&5o%(C{J?D9U&v~Bbyyt!2KYr)kSWX0-1`YrK z0+T^w%L%RpRzbeE+W9?}L*cly6HQL}T6SzqkYgQ>aU>i7@Eg|x0py8D@}gn{(}k`$ zj8(;<(PIqsv?F3q9txY%aue#qHQn^)mX))V7qR)W+3C*i5v#>` zdtT0q+=hg4(UU@nRZw?>+JP!=#9b6~cVf&R%N>)@;KcRWt}ip;!~sn_2a$>~A;O0N zcgGdos!86~XZs>oe`9t}Z0V9DmsQLUYRh~6--rG$IZ*yCbkwZIsm)z2=GheTuJg9# z9aj;ea015=yaBW$N%*fxpz0XVxR3bA0)^=BlKZ#vJY^T{gvk*qr9 zLEJP1jVU4ee<=3UfRDkI@Dt%}XRnipNgepytv6oM9n6}tT7Se(!9e;stR{F?I9m%W zTtyfKDAXS6wZ^--A{h6eDq&$gAUlKj3^wQ%wVMgIhyj@iDrXS&_6EJz2JbebAmtrZ z`cs#?H$69J-l0cZ>dNWO80ZGh!Vb}7v>xi2ds-MhyIaPRa`~HDh#VXFrGyoz`EIpH znut^~Y{G@sTOb9%@9yirL_FGPh3m=K)f+MH7pk7QTSx>1D1n}pwI9>C%i`lsf3HfW zl2e-=N9lg*C~JJtetI9Li6S}=y#>!~X3ROP)QAD~lsWS`c7DFAV)ZRxS*%YreCd~t z>1ZZe5`sg+=U)(uHKuO^3*(IZmo8$Uzj&C-LCI^K!QqYmavIA2ATSMcMPE3Mnt4?{ zb8~jTe;W(8K^%zp~l0E)TgCa}j z&N)L9QNn+%M9k_hFTDl3U_NBY#B@}t@haN NvP?RQR=t;#^e^g-c-Q~{ literal 0 HcmV?d00001 diff --git a/icons/cal/white/6.png b/icons/cal/white/6.png new file mode 100644 index 0000000000000000000000000000000000000000..a1c9798bd0c4cf8f03ebdb6524f723c6f8e415ec GIT binary patch literal 1776 zcmZXVdpy(oAIHC&ZFV`T4RcG;A(sf9Vs(TvF@EMGmo}G&BBWw+X(uh;Rli))F)NpB zq)?qAYG}vOz8)N)a$VNRj58di!>oOOPW`sep~Jl^lu`|*CiKcDws@8>7)7pkuw z))Wf>fF8w<9IRFFtD#X^-{G<6kycQ91ANI^)t)(TQMOhv3_n^L0O0h$8Vo4s8*7ug z>6Abp-66CA7G)H=Cr_fi$fA(9g)j#uDkAD4cdg73r){Z^sKtD-v>UkI>T@!f5E8<( zpxXu7+Wqxk|K3FAenkDLd?6WqiGZKovC%%%UsLtW`YcDf!T|5M^x;HxXj?%}8zqWb zK@%kOs4pl>`Hwpumv2h=B5vy&IM9GA`|Zk&VW-^OTIg5N+yetjK-9B(+P$ImFMGP+ zyMb6(0n(WWrCSu|mPNikvQpzYRd@znntrAvC7c`*)s+nYxBk8H|AQvOVvl3vdni9; zW%a&=n+9whGs8zgR5{QEH^#*{fVch^BpK`WJ95{GjLm$jAIUd?yl0XR7=pZq+1#yU^{j4hk@i?L_G7+B|Pr$>!iQML)v zLgbaPZJsxK58U(5K`y$E9CKruTX~TSfMi&_u=m9_IJt8bGy&C_zR1K$QSF|H-9PX{ z2s_usCAb|#W&)v`7Pbq8>C9Sogd| zv|PHSUA#iroJUKBt!f17@t^fU8`}|}F6tAJsk<9f2X}>ufvsMJHAwqBo(O;*6hf|FhhxZN~f~ui`TSKUtammI%bB}^%a=PC&k;xOTRnDdWGuJH@)DiN?tGnYu45_uNE(;uk%())6 zw6lt^7o8QfSdFFG8jrQ&@{3foN1T9t6*lG5DZsltWPyu+@lS2s1zrWK^RGEh)8jJ8 zk+HCH$sd^grnkUY3r!4puz1$a!ApPOcE^^ywhq&J{Q*iO%A_hC%8LSn2y8*>l&2E+3ta0Of26y8-lmfXeS8a_;kU zh2g=4NZXQ2&peeWTN%q0*T(0g$!0;WjE(Ltg z;9g4G<;n9Oc5+h{b(eAo(-n!Z{4sfFy3_LuDM<;F&bVJ3%m^|y@TUADPh#O;H06bp zF2U=HnrgwjVs(y)h|{c|)jYYIb}bwzR$=yt`T%e2z+;zv#CO_l`cn?@^kruqET+!S z9E%dP98sZRRujPR#MNPDKKVeDj)5csv%kmQLTQlKM+0Bdia6u9k5)eQ?HuXs8I=>O zm|?*SmF^2b__Lzd)_JOu2=L_sOw2u`2wo=$PVQcFdHaleRhX+z3LWg?+_vjYl*PY^ zEbm_wuUEO@q{c)YJJGL$=J<0-!udiZ(Q2{F$kwD5?>jMrfd}l1F#n8Jz$Nq}NHg@H5k8!=b)04LDO%Q(YmDOWXqnO2Cn>W=f|BiC&7{^6 zykzsaWw^o8PlmDGnMj@fN+;dbbSP-y2PU5o+}eDIJE>b@XqAm`Z-A%0#|Pk~RyPsH z6N{7^f@JHg9q%8;TBv+SHps>&47&;CBHvrcexDO^u)8M6Kku`0Q0NvBT*H5q-dcN5i5iCT!8N zV@my=?{V=*=kw9=noNJq&pW^+ETfsOS0Ir!e?zK@Y+o^7cqAiZ^ZZRMzZ<{hwWxgs vEX6a)|4H51Y{S}2k_jXlU_DZJJvyVdcqC)`f*WwsN|d5V@~`7SL7+6 literal 0 HcmV?d00001 diff --git a/icons/cal/white/7.png b/icons/cal/white/7.png new file mode 100644 index 0000000000000000000000000000000000000000..e97195177c15ae97839e9c4925e9cb7d4a314acc GIT binary patch literal 1147 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSY)RhkE)9b2D$@3URf&(u zuGjXR$ui%XxXssXDwv+~_Ecq;p`Pqw>&uF>W;iUm(IITn;36({r(=OqlY)wpN*A+Z zL4)v-j)_~!%6D!!=;~Ac%FgTF-tWJ+y`OtMbosvj_f{>+pUM(?x#t(NU}3K8y{(Fhqs{%)&c! z3tV(2Z;89an!Ky?{;hvZjBUyNOMV}Vx%73LeF~RE+iK$*$FeQh8CV$3F($nH+$zd_ zeBneBt$M9 zmvw8Xzr5eZ@Nad_|3-$?CI7qTnX0SU&i(ACd?4fH{rul7Oi#}1PSSfHSsZlf-ktJ2 zs((+uoWHGBhVj$$FwfUj*Uos{3O#gg`;z#6l_~oYeyg*bn15U7lD+oJ&LF7^VRQZ! z3tj%d>TNPdfZH$q*OA8hneLvx8J_j}d^i4a0nI4$oUV4ocj~o{ZI`~-&k6X|_x3!{ z;qN?r{(lpieKBm>Khe&Y_4mIm2kZA-QN8C%+mB;U~~S$Z|s~(`ezlw{z~j>tslOw(H2Qw=%!# zPyAh*xLbAYrJMV$6Z|gKdCqrr*?dDh`$zqOH>?}}PF(U@_?)bi=V>){_5Yt=-t)a| zz%-@j?Yh^yA{qNTof#a!@PVC!>y?s~$2k~~q3t{7HQgP)TUPnZ>UfdC9E_Adt{l2w XE%ralcMpmK0OY102?9kWD1`}+CwaNT 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 literal 0 HcmV?d00001 diff --git a/icons/layout/default/browse.png b/icons/layout/default/browse.png new file mode 100644 index 0000000000000000000000000000000000000000..c063ca09de3e77e8a605ab39bef9b9c21c5bacda GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt&q zurz(=c_77D666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_B)KS0!qA}lg;YFU978nDC;#AQ<(bjL&g1Z*p|Q5W=z-pm6rLz^{?Ox({Zts_ XZ!gY%>+x_hP(6dEtDnm{r-UW|pPn$+ literal 0 HcmV?d00001 diff --git a/icons/layout/default/browsew.png b/icons/layout/default/browsew.png new file mode 100644 index 0000000000000000000000000000000000000000..9b0b2b3141a857c618202685f759ee37925e4dd1 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt)< z|NmclbN*eBbV-n3FoVOh8)+a;lDE4HLkFv@2av;A;1OBOz`!jG!i)^F=12eq*-Jcq zUD@w2%J6B5nRIWs3=~rFba4#PIG_B3pOt4u4?B;;hla-50;30dM^bpA%=tr)KlW2$ YkiWe+`>n^r$w2iCp00i_>zopr0ADUNL;wH) literal 0 HcmV?d00001 diff --git a/icons/layout/default/cascade.png b/icons/layout/default/cascade.png new file mode 100644 index 0000000000000000000000000000000000000000..292a057f017e2f26c7f1b99bdf57bb193d75158c GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt&q zurz(=c_77D666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_B)KS0;Xo}(^MjXLjImEjv*T7lYj8D^33RA=Seu=7tdyY;T8K0$r=aIf@A;L=JXt& z(Nn)evNpxof$#9a1dW7*gkuL+uxlMUn2?u{@Zj)4hE+e?=Q@7&I5^jX;l}YzZ#%xR RwE&G~@O1TaS?83{1OWU|M#KOB literal 0 HcmV?d00001 diff --git a/icons/layout/default/cascadebrowse.png b/icons/layout/default/cascadebrowse.png new file mode 100644 index 0000000000000000000000000000000000000000..2f12ada6300e54c16b5b2337824c7651c5909f29 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt&q zurz(=c_77D666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_B)KS0+tH$-|w*ig#tZY978nDC;#AQ<(bjL&cnmg!!B{7-HQ3e^m+>khtL`Ww*UNd zcL;o<%ysnGr~VFR;mOE+W47iR0`gG?(p*bmDA31(fMLUkdA!1EW(5-n7^ QfQB=8y85}Sb4q9e0OJlkmH+?% literal 0 HcmV?d00001 diff --git a/icons/layout/default/cascadebrowsew.png b/icons/layout/default/cascadebrowsew.png new file mode 100644 index 0000000000000000000000000000000000000000..c46b48be2b4132ca68f77250765f4dc7bc6bb4be GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt)< z|NmclbN*eBbV-n3FoVOh8)+a;lDE4HLkFv@2av;A;1OBOz`!jG!i)^F=12eq*-Jcq zUD@w2$_iMrD1WiK3KRi(g;OXk;vd$@?2>?IfKnnl> literal 0 HcmV?d00001 diff --git a/icons/layout/default/cascadew.png b/icons/layout/default/cascadew.png new file mode 100644 index 0000000000000000000000000000000000000000..da64bd6ceb1e6c8ed74213d2ee38d33129591cf3 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt)< z|NmclbN*eBbV-n3FoVOh8)+a;lDE4HLkFv@2av;A;1OBOz`!jG!i)^F=12eq*-Jcq zUD@w2$_ki?D_lxH0u=K1ba4#PIG_B3pOt4u4?9o70l#=Q`wOqwZ%EcSh!!0C&o-y$ z_>7+V9g?*v#twXk4<=|NBqSU=xPo2l(7}YfgoFo&4>GL!**@3tv&X@?9t<~*Z+hGD SjjaV}G=rzBpUXO@geCxv&PvPx literal 0 HcmV?d00001 diff --git a/icons/layout/default/centerwork.png b/icons/layout/default/centerwork.png new file mode 100644 index 0000000000000000000000000000000000000000..826b331b48679d671048f232a9c2c254ba5e7af4 GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPa8#@oTPIBk>g+QTxPZ!6Kid%1Q7;+sj;9$KFQS@K? z_TDK@UK*nJ?;EMSaGu_yc*&~J@_Bdl&&6`nUfb{Tcc^aIS!w%d@vh?QRnd$=QFfzC-3Gj=N=B$=}aeY5X*3;F`Wt~$( F698vdNn8K` literal 0 HcmV?d00001 diff --git a/icons/layout/default/centerworkw.png b/icons/layout/default/centerworkw.png new file mode 100644 index 0000000000000000000000000000000000000000..fcfa7e317d0c3a093c18568bf16418fc9010260c GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPa8#@mVYhKk)kdcc#T^vIyZoR!}$kkxL!+IfX&;O~f zqgtHSgiYMD-_qrga-@%@(#qi9?bo8XMXyG!zozrMp)>B+EZyHMOW1EHCkx50FFw2K z%on3o8<~K{VFHh-591%M=a(xNetVxQqERnj)+{V_S-m!@jRF%}28J29*~C-V}>VGHmHaRt&q zurz(=c_77D666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_B)KS0xB$bW`vyt3blK>IEHAPUwUaHFS8;K>xKSx1t&Soxn{>o^ae^i^x_hE{wGzb zmBV${jw(_4TIpBK`5^^Q>|A8|*SZ9}ZHZ`5+_vE625}W7#)%dUy)PUTZhhULXwuK| zyl1VR;#0Ln)8;qS9B>lfu--3&Z_h>czQ!rC;epnI)-%o-ZNC0nrgi>hu78nFe|f~M X@LS8-mC1Vu=p+VDS3j3^P6@jRF%}28J29*~C-V}>VGHmHaRt)< z|NmclbN*eBbV-n3FoVOh8)+a;lDE4HLkFv@2av;A;1OBOz`!jG!i)^F=12eq*-Jcq zUD@w2%J6Bb{E2xO3>0ejba4#PIKTALMqXw`9@Y!}>k3YCm~+jJmFNwWc<99?^88P# zQY(k+t{qjP^0m^hn)5>np4hp_@~?FXc-s=uptxA$Qs5#&yzG1yz2H&2G?0t<>WWxik1+8bCGunLpw@mB&%Uu5=pZ@ZQ YTj95svn!ML5YR~sp00i_>zopr055%EXaE2J literal 0 HcmV?d00001 diff --git a/icons/layout/default/termfair.png b/icons/layout/default/termfair.png new file mode 100644 index 0000000000000000000000000000000000000000..06226c1683ac0a42a762f2b280df9bf500cac969 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt&q zurz(=c_77D666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_B)KS0*X3QqPWU{LaLrFjv*T7lYj8D^33RA=c(awIAHfeqUFvXhGi87Ms1587w(p1 ZIC*~q>w_b_TY(xFJYD@<);T3K0RX%`F@OL7 literal 0 HcmV?d00001 diff --git a/icons/layout/default/termfairw.png b/icons/layout/default/termfairw.png new file mode 100644 index 0000000000000000000000000000000000000000..0a8b5763125fd7391a1f555d2b9d7b59c59bd724 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt)< z|NmclbN*eBbV-n3FoVOh8)+a;lDE4HLkFv@2av;A;1OBOz`!jG!i)^F=12eq*-Jcq zUD@w2$_gm*Ia+y70t%^mx;TbtoKOD2&&o5Shn=T}$Kin83yGFHe;Afk7#OuJdR(|$ alHuh24Xh82@NNZaVDNPHb6Mw<&;$T)jx?_T literal 0 HcmV?d00001 diff --git a/icons/layout/zenburn/browse.png b/icons/layout/zenburn/browse.png new file mode 100644 index 0000000000000000000000000000000000000000..f0bd177143266961916a20d295faeccc73c58ba0 GIT binary patch literal 269 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg4PHABl-j7F`rvZg}JzX3_DsH{K zxskU)LBJuQL70(Y)*K0-AbW|YuPgg)78yZao?r7mcL9Y~d%8G=RNQ)d zeIqZEArEVSd=g{X2ac61^A*b$x0xwdv`aTeKX}n(q4|Eg-kKLLy~C7J-sz;*Muh(V zQ&gW8t)!&4*&JvLDlmv&w^%&v>vWKF84j!oPe{1ue)vq;b!1h?{<5z6WtH*#?dh7! tU~!Arq7pNXUo_ZkYl^H6!ghG_{w8DQe!d+hy-ZagAx~F7mvv4FO#o0nR|xQL70(Y)*K0-AbW|YuPgg)P8m))^}89hia?=7o-U3d6}R5r z+{oLYAix@6(07P~??gk-0liz2Nwuv{?!C|9*mvhUm$#tj++B8OEZ^D3ZQ8n8ulx<; z^S$XZH`Reg-~zf!2++1 m)d%MPWAnwW1R~>6^@{D4qCjzzV;#`Z3=E#GelF{r5}E+bvOHS= literal 0 HcmV?d00001 diff --git a/icons/layout/zenburn/gimp.png b/icons/layout/zenburn/gimp.png new file mode 100644 index 0000000000000000000000000000000000000000..ded8e62a73f952493e2df9e0d5ac2f7606bcb101 GIT binary patch literal 3424 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 literal 0 HcmV?d00001 diff --git a/icons/layout/zenburn/termfair.png b/icons/layout/zenburn/termfair.png new file mode 100644 index 0000000000000000000000000000000000000000..b7d5880c64fb32af4906b58bae4a347e8f8db4f5 GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg4P6-|>dAIUKKoN$8o-U3d6}R5r z+{oK(AmVz_y=#N3R{wzpo)a7)ITKBmY`t{M!{h&*zGo+`m;x;(dYOOa|GjVSf4*(o zeD2<}dNg6J?&}k0>)r?cz##tJ$0(e&LiMLgWjL!v4HHBZg;cq_;^Fnj_OqX} lK9{L#eXoxqiONw}=@MTkCz`vrwL%Ugvd$@?2>`wVQ}6%) literal 0 HcmV?d00001 diff --git a/icons/mail.png b/icons/mail.png new file mode 100644 index 0000000000000000000000000000000000000000..60ba6e03c83096ece4c7b3e819fbf465a57c33db GIT binary patch literal 634 zcmV-=0)_pFP)!1A1KpjVT02waR7`@oYE0(=2nKc;~afuVKL0ail@gISmBxIO#2q53F6m7`dDF;Rp*ya4}MWke=f zuW~_2-y;%@Q3SFI`|SB%zq+&sRbElm4_B*vj?AbEU(1Ico^0`nZn`Wf(i8t0mEJd4Nj{FKM?PI)*vkFy!S0S(8o U)3CzePyhe`07*qoM6N<$g2BTP;Q#;t literal 0 HcmV?d00001 diff --git a/icons/no_net.png b/icons/no_net.png new file mode 100755 index 0000000000000000000000000000000000000000..1a3e8a8ab82472adbce12200207d3af55956e9c7 GIT binary patch literal 1697 zcmV;S244AzP)I6pyXtIei2`XwJ#s?$ zoT7gy!6?RnO3*2ZQRk|2s3`IfH$emh0}5jZ0pkPu+UEM$?LGd{O(%5S9QbJIN$x-W zo!j2?`Tfp0-{0?+5QnBQr)q9DfjP1R5hSxYNJKt4-h%g3R!wk^7`v}uM^yzgC&wKC zcDaoJFyzExist9E7BfO2Mc`t!?)12L0d!jeKmtGlz{PF<>o&;DaF3f*3RUH(j(R;? z4(x7@I{Psk%$yZ}Lg=^EYfS!C&$SK2H+|Fl6n6lEZ`WN303vVbOfX0MT{0R1>fx5n zaV>?-&09Z-Dr)j=i5idqkN}X_4)@@K@;lXo-@WKt`J6}V3MgXuuu66Nj^wlbycM${($gk&eRE)2*RI{WL{@g8 z=f=6`51?aN&A@$^KXIXhU!b=Bu#SkBgF(qXW89u#>)?cqTJ2t241&`lVhaVD?eG!X^*aaD|uKWe}e%Y7Fn`0013t;g0A5d$D1 z0tbV7-(yd@(i-bh+7{l|$)}x~$jHcTyXNYW;O4D+31ARWIA-FYqv25dl4@J%XluFe zl~)ae0^qN!w~*23k;Yhuu*+?Ts($QfpW_ADmWB}(4z;n%vd1^~*ZBOuj%rX&J zRmnSRuG7+bFolS|^v=Hdir{D4nu);SsYWk%;y|6_u&!*%giuTC&x0?5L`ZL}*8p_% zHSV+)^?uetTSv``Vg7Zs8_o{?FAxHOBv(OUTl>-nuM50Wzdh_r6!FQ3SZ&_5Z^*Gj zA|{GpO3kCElo{n$a5#95%$vZ0pyAKp`y|g$6jgui^sJcb0;ctAcPi7Tl`?Zw2tDZ@ zCHPR%!n?D&cJGY z15#_(?a)t~TE@)81BbxS>sh(&mK@{5)voX-3}{R-DTGqrSiem_rL=s&6;{!ADRZiF zQyzchOhhT{%(o4QWPj)L|Adht*?X?Ss{&}d^k-~FdDxS|T8VC3+iqv0qtjR&#{*ykVO zv=;qjTDv;8ZQ&B6u6e%K3Sa<=9_G(CujuEXq6X*l24axLoxZf*GcOg4x+LIuzXh5m z4>Sdc2<-FcI7g5BF?G%Jd4CRoMR$q#-l5C?NVoi=6Bcm$mq`etH?lh7^9P<_u+Ktn3b~kKkp}O)a&V zw|u-(Dze`lMJzD@NY+t{V@e8JzHVA3a&w>NbK4$62+~cyyg2o>SB`ipXBQfmE`Cin zvE=p$5SRgyiwi4BN&4JZyTKGQ0J^?C1k0YLheb}#s$LKnvP_cQc3JA1wFd!!&$!I( zixvmd8tXU6CFAG!K;Z7+CA)1_`lb&W)$hMQmUPEF5(w{{dMb#BboI)hvsV(BS&4K3 z05rZ3yWw!ZF1E|eEL-+ASBvbd7g*B(Nh00k%S+hf_5QZ<*{tvxmjGnx2mqvi=%|%T z#@)r5MqnnXaO@oOryCmp0HKf$ng$s{bV3L?3yRofEsm@K3W@+#1!ZNr0YHqkIk9(t zdcXGw0eSrRP5_`3qZ2wA&VnM2cE$in{4p-s?Jl)xC!F~I^?#}X*rN}9(mNrFPue}cEBGnLI^;J rP8|P-m+muzxW_ed^1qT+M*#c|BkP&jBU;IV00000NkvXXu0mjfn#wI2 literal 0 HcmV?d00001 diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..3abf9f6 --- /dev/null +++ b/init.lua @@ -0,0 +1,20 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local lain = +{ + layout = require("lain.layout"), + util = require("lain.util"), + widgets = require("lain.widgets") +} + +return lain diff --git a/layout/cascade.lua b/layout/cascade.lua new file mode 100644 index 0000000..cabacef --- /dev/null +++ b/layout/cascade.lua @@ -0,0 +1,65 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local tag = require("awful.tag") + +local cascade = +{ + name = "cascade", + nmaster = 0, + offset_x = 32, + offset_y = 8 +} + +function cascade.arrange(p) + + -- Cascade windows. + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Opening a new window will usually force all existing windows to + -- get resized. This wastes a lot of CPU time. So let's set a lower + -- bound to "how_many": This wastes a little screen space but you'll + -- get a much better user experience. + local t = tag.selected(p.screen) + local num_c + if cascade.nmaster > 0 + then + num_c = cascade.nmaster + else + num_c = tag.getnmaster(t) + end + + local how_many = #cls + if how_many < num_c + then + how_many = num_c + end + + local current_offset_x = cascade.offset_x * (how_many - 1) + local current_offset_y = cascade.offset_y * (how_many - 1) + + -- Iterate. + for i = 1,#cls,1 + do + local c = cls[i] + local g = {} + + g.x = wa.x + (how_many - i) * cascade.offset_x + g.y = wa.y + (i - 1) * cascade.offset_y + g.width = wa.width - current_offset_x + g.height = wa.height - current_offset_y + + c:geometry(g) + end +end + +return cascade diff --git a/layout/cascadetile.lua b/layout/cascadetile.lua new file mode 100644 index 0000000..a94bbed --- /dev/null +++ b/layout/cascadetile.lua @@ -0,0 +1,159 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") +local tonumber = tonumber + +local cascadetile = +{ + name = "cascadetile", + nmaster = 0, + ncol = 0, + mwfact = 0, + offset_x = 5, + offset_y = 32, + extra_padding = 0 +} + +function cascadetile.arrange(p) + + -- Layout with one fixed column meant for a master window. Its + -- width is calculated according to mwfact. Other clients are + -- cascaded or "tabbed" in a slave column on the right. + + -- It's a bit hard to demonstrate the behaviour with ASCII-images... + -- + -- (1) (2) (3) (4) + -- +-----+---+ +-----+---+ +-----+---+ +-----+---+ + -- | | | | | | | | | | | 4 | + -- | | | | | 2 | | | 3 | | | | + -- | 1 | | -> | 1 | | -> | 1 | | -> | 1 +---+ + -- | | | | +---+ | +---+ | | 3 | + -- | | | | | | | | 2 | | |---| + -- | | | | | | | |---| | | 2 | + -- | | | | | | | | | | |---| + -- +-----+---+ +-----+---+ +-----+---+ +-----+---+ + + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width. + local useless_gap = tonumber(beautiful.useless_gap_width) + if useless_gap == nil + then + useless_gap = 0 + end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Width of main column? + local t = tag.selected(p.screen) + local mwfact + if cascadetile.mwfact > 0 + then + mwfact = cascadetile.mwfact + else + mwfact = tag.getmwfact(t) + end + + -- Make slave windows overlap main window? Do this if ncol is 1. + local overlap_main + if cascadetile.ncol > 0 + then + overlap_main = cascadetile.ncol + else + overlap_main = tag.getncol(t) + end + + -- Minimum space for slave windows? See cascade.lua. + local num_c + if cascadetile.nmaster > 0 + then + num_c = cascadetile.nmaster + else + num_c = tag.getnmaster(t) + end + + local how_many = #cls - 1 + if how_many < num_c + then + how_many = num_c + end + local current_offset_x = cascadetile.offset_x * (how_many - 1) + local current_offset_y = cascadetile.offset_y * (how_many - 1) + + if #cls > 0 + then + -- Main column, fixed width and height. + local c = cls[#cls] + local g = {} + local mainwid = wa.width * mwfact + local slavewid = wa.width - mainwid + + if overlap_main == 1 + then + g.width = wa.width + + -- The size of the main window may be reduced a little bit. + -- This allows you to see if there are any windows below the + -- main window. + -- This only makes sense, though, if the main window is + -- overlapping everything else. + g.width = g.width - cascadetile.extra_padding + else + g.width = mainwid + end + + g.height = wa.height + g.x = wa.x + g.y = wa.y + if useless_gap > 0 + then + -- Reduce width once and move window to the right. Reduce + -- height twice, however. + g.width = g.width - useless_gap + g.height = g.height - 2 * useless_gap + g.x = g.x + useless_gap + g.y = g.y + useless_gap + + -- When there's no window to the right, add an additional + -- gap. + if overlap_main == 1 + then + g.width = g.width - useless_gap + end + end + c:geometry(g) + + -- Remaining clients stacked in slave column, new ones on top. + if #cls > 1 + then + for i = (#cls - 1),1,-1 + do + c = cls[i] + g = {} + g.width = slavewid - current_offset_x + g.height = wa.height - current_offset_y + g.x = wa.x + mainwid + (how_many - i) * cascadetile.offset_x + g.y = wa.y + (i - 1) * cascadetile.offset_y + if useless_gap > 0 + then + g.width = g.width - 2 * useless_gap + g.height = g.height - 2 * useless_gap + g.x = g.x + useless_gap + g.y = g.y + useless_gap + end + c:geometry(g) + end + end + end +end + +return cascadetile diff --git a/layout/centerwork.lua b/layout/centerwork.lua new file mode 100644 index 0000000..2035c65 --- /dev/null +++ b/layout/centerwork.lua @@ -0,0 +1,122 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local awful = require("awful") +local beautiful = require("beautiful") +local tonumber = tonumber +local math = { floor = math.floor } + +local centerwork = +{ + name = "centerwork", + top_left = 0, + top_right = 1, + bottom_left = 2, + bottom_right = 3 +} + +function centerwork.arrange(p) + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width . + local useless_gap = tonumber(beautiful.useless_gap_width) + if useless_gap == nil + then + useless_gap = 0 + end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- Width of main column? + local t = awful.tag.selected(p.screen) + local mwfact = awful.tag.getmwfact(t) + + if #cls > 0 + then + -- Main column, fixed width and height. + local c = cls[#cls] + local g = {} + local mainwid = math.floor(wa.width * mwfact) + local slavewid = wa.width - mainwid + local slaveLwid = math.floor(slavewid / 2) + local slaveRwid = slavewid - slaveLwid + local slaveThei = math.floor(wa.height / 2) + local slaveBhei = wa.height - slaveThei + + g.height = wa.height - 2 * useless_gap + g.width = mainwid + g.x = wa.x + slaveLwid + g.y = wa.y + useless_gap + + c:geometry(g) + + -- Auxiliary windows. + if #cls > 1 + then + local at = 0 + for i = (#cls - 1),1,-1 + do + -- It's all fixed. If there are more than 5 clients, + -- those additional clients will float. This is + -- intentional. + if at == 4 + then + break + end + + c = cls[i] + g = {} + + if at == centerwork.top_left + then + -- top left + g.x = wa.x + useless_gap + g.y = wa.y + useless_gap + g.width = slaveLwid - 2 * useless_gap + g.height = slaveThei - useless_gap + elseif at == centerwork.top_right + then + -- top right + g.x = wa.x + slaveLwid + mainwid + useless_gap + g.y = wa.y + useless_gap + g.width = slaveRwid - 2 * useless_gap + g.height = slaveThei - useless_gap + elseif at == centerwork.bottom_left + then + -- bottom left + g.x = wa.x + useless_gap + g.y = wa.y + slaveThei + useless_gap + g.width = slaveLwid - 2 * useless_gap + g.height = slaveBhei - 2 * useless_gap + elseif at == centerwork.bottom_right + then + -- bottom right + g.x = wa.x + slaveLwid + mainwid + useless_gap + g.y = wa.y + slaveThei + useless_gap + g.width = slaveRwid - 2 * useless_gap + g.height = slaveBhei - 2 * useless_gap + end + + c:geometry(g) + + at = at + 1 + end + + -- Set remaining clients to floating. + for i = (#cls - 1 - 4),1,-1 + do + c = cls[i] + awful.client.floating.set(c, true) + end + end + end +end + +return centerwork diff --git a/layout/init.lua b/layout/init.lua new file mode 100644 index 0000000..d79679a --- /dev/null +++ b/layout/init.lua @@ -0,0 +1,20 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Layouts section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local wrequire = require("lain.helpers").wrequire +local setmetatable = setmetatable + +local layout = { _NAME = "lain.layout" } + +return setmetatable(layout, { __index = wrequire }) diff --git a/layout/termfair.lua b/layout/termfair.lua new file mode 100644 index 0000000..62eef9a --- /dev/null +++ b/layout/termfair.lua @@ -0,0 +1,160 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") +local math = { ceil = math.ceil, + floor = math.floor, + max = math.max } +local tonumber = tonumber + +local termfair = +{ + name = "termfair", + + -- You can set the number of columns and rows, + -- -- otherwise they are read from awful.tag + nmaster = 0, -- columns + ncol = 0 -- rows +} + +function termfair.arrange(p) + -- Layout with fixed number of vertical columns (read from nmaster). + -- New windows align from left to right. When a row is full, a now + -- one above it is created. Like this: + + -- (1) (2) (3) + -- +---+---+---+ +---+---+---+ +---+---+---+ + -- | | | | | | | | | | | | + -- | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> + -- | | | | | | | | | | | | + -- +---+---+---+ +---+---+---+ +---+---+---+ + + -- (4) (5) (6) + -- +---+---+---+ +---+---+---+ +---+---+---+ + -- | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | + -- +---+---+---+ -> +---+---+---+ -> +---+---+---+ + -- | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | + -- +---+---+---+ +---+---+---+ +---+---+---+ + + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width. + local useless_gap = tonumber(beautiful.useless_gap_width) + if useless_gap == nil + then + useless_gap = 0 + end + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- How many vertical columns? + local t = tag.selected(p.screen) + local num_x + if termfair.nmaster ~= 0 + then + num_x = termfair.nmaster + else + num_x = tag.getnmaster(t) + end + + -- Do at least "desired_y" rows. + local desired_y + if termfair.ncol ~= 0 + then + desired_y = termfair.ncol + else + desired_y = tag.getncol(t) + end + + if #cls > 0 + then + local num_y = math.max(math.ceil(#cls / num_x), desired_y) + local cur_num_x = num_x + local at_x = 0 + local at_y = 0 + local remaining_clients = #cls + local width = math.floor(wa.width / num_x) + local height = math.floor(wa.height / num_y) + + -- We start the first row. Left-align by limiting the number of + -- available slots. + if remaining_clients < num_x + then + cur_num_x = remaining_clients + end + + -- Iterate in reversed order. + for i = #cls,1,-1 + do + -- Get x and y position. + local c = cls[i] + local this_x = cur_num_x - at_x - 1 + local this_y = num_y - at_y - 1 + + -- Calc geometry. + local g = {} + if this_x == (num_x - 1) + then + g.width = wa.width - (num_x - 1) * width + else + g.width = width + end + if this_y == (num_y - 1) + then + g.height = wa.height - (num_y - 1) * height + else + g.height = height + end + g.x = wa.x + this_x * width + g.y = wa.y + this_y * height + if useless_gap > 0 + then + -- Top and left clients are shrinked by two steps and + -- get moved away from the border. Other clients just + -- get shrinked in one direction. + if this_x == 0 + then + g.width = g.width - 2 * useless_gap + g.x = g.x + useless_gap + else + g.width = g.width - useless_gap + end + + if this_y == 0 + then + g.height = g.height - 2 * useless_gap + g.y = g.y + useless_gap + else + g.height = g.height - useless_gap + end + end + c:geometry(g) + remaining_clients = remaining_clients - 1 + + -- Next grid position. + at_x = at_x + 1 + if at_x == num_x + then + -- Row full, create a new one above it. + at_x = 0 + at_y = at_y + 1 + + -- We start a new row. Left-align. + if remaining_clients < num_x + then + cur_num_x = remaining_clients + end + end + end + end +end + +return termfair diff --git a/layout/uselessfair.lua b/layout/uselessfair.lua new file mode 100644 index 0000000..92e8d45 --- /dev/null +++ b/layout/uselessfair.lua @@ -0,0 +1,122 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2012, Josh Komoroske + * (c) 2010-2012, Peter Hofmann + +--]] + +local beautiful = require("beautiful") +local ipairs = ipairs +local math = { ceil = math.ceil, sqrt = math.sqrt } +local tonumber = tonumber + +local uselessfair = {} + +local function fair(p, orientation) + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width. + local useless_gap = tonumber(beautiful.useless_gap_width) + if useless_gap == nil + then + useless_gap = 0 + end + + local wa = p.workarea + local cls = p.clients + + if #cls > 0 then + local cells = math.ceil(math.sqrt(#cls)) + local strips = math.ceil(#cls / cells) + + local cell = 0 + local strip = 0 + for k, c in ipairs(cls) do + local g = {} + -- Save actual grid index for use in the useless_gap + -- routine. + local this_x = 0 + local this_y = 0 + if ( orientation == "east" and #cls > 2 ) + or ( orientation == "south" and #cls <= 2 ) then + if #cls < (strips * cells) and strip == strips - 1 then + g.width = wa.width / (cells - ((strips * cells) - #cls)) + else + g.width = wa.width / cells + end + g.height = wa.height / strips + + this_x = cell + this_y = strip + + g.x = wa.x + cell * g.width + g.y = wa.y + strip * g.height + + else + if #cls < (strips * cells) and strip == strips - 1 then + g.height = wa.height / (cells - ((strips * cells) - #cls)) + else + g.height = wa.height / cells + end + g.width = wa.width / strips + + this_x = strip + this_y = cell + + g.x = wa.x + strip * g.width + g.y = wa.y + cell * g.height + end + + -- Useless gap. + if useless_gap > 0 + then + -- Top and left clients are shrinked by two steps and + -- get moved away from the border. Other clients just + -- get shrinked in one direction. + if this_x == 0 + then + g.width = g.width - 2 * useless_gap + g.x = g.x + useless_gap + else + g.width = g.width - useless_gap + end + + if this_y == 0 + then + g.height = g.height - 2 * useless_gap + g.y = g.y + useless_gap + else + g.height = g.height - useless_gap + end + end + -- End of useless gap. + + c:geometry(g) + + cell = cell + 1 + if cell == cells then + cell = 0 + strip = strip + 1 + end + end + end +end + +--- Horizontal fair layout. +-- @param screen The screen to arrange. +uselessfair.horizontal = {} +uselessfair.horizontal.name = "uselessfairh" +function uselessfair.horizontal.arrange(p) + return fair(p, "east") +end + +-- Vertical fair layout. +-- @param screen The screen to arrange. +uselessfair.name = "uselessfair" +function uselessfair.arrange(p) + return fair(p, "south") +end + +return uselessfair diff --git a/layout/uselesspiral.lua b/layout/uselesspiral.lua new file mode 100644 index 0000000..695728c --- /dev/null +++ b/layout/uselesspiral.lua @@ -0,0 +1,112 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2009 Uli Schlachter + * (c) 2008 Julien Danjolu + +--]] + +local beautiful = require("beautiful") +local ipairs = ipairs +local tonumber = tonumber + +local uselesspiral = {} + +local function spiral(p, spiral) + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width. + local useless_gap = tonumber(beautiful.useless_gap_width) + if useless_gap == nil + then + useless_gap = 0 + end + + local wa = p.workarea + local cls = p.clients + local n = #cls + + local static_wa = wa + + for k, c in ipairs(cls) do + if k < n then + if k % 2 == 0 then + wa.height = wa.height / 2 + else + wa.width = wa.width / 2 + end + end + + if k % 4 == 0 and spiral then + wa.x = wa.x - wa.width + elseif k % 2 == 0 or + (k % 4 == 3 and k < n and spiral) then + wa.x = wa.x + wa.width + end + + if k % 4 == 1 and k ~= 1 and spiral then + wa.y = wa.y - wa.height + elseif k % 2 == 1 and k ~= 1 or + (k % 4 == 0 and k < n and spiral) then + wa.y = wa.y + wa.height + end + + local wa2 = {} + wa2.x = wa.x + wa2.y = wa.y + wa2.height = wa.height + wa2.width = wa.width + + -- Useless gap. + if useless_gap > 0 + then + -- Top and left clients are shrinked by two steps and + -- get moved away from the border. Other clients just + -- get shrinked in one direction. + + top = false + left = false + + if wa2.y == static_wa.y then + top = true + end + + if wa2.x == static_wa.x then + left = true + end + + if top then + wa2.height = wa2.height - 2 * useless_gap + wa2.y = wa2.y + useless_gap + else + wa2.height = wa2.height - useless_gap + end + + if left then + wa2.width = wa2.width - 2 * useless_gap + wa2.x = wa2.x + useless_gap + else + wa2.width = wa2.width - useless_gap + end + end + -- End of useless gap. + + c:geometry(wa2) + end +end + +--- Dwindle layout +uselesspiral.dwindle = {} +uselesspiral.dwindle.name = "uselessdwindle" +function uselesspiral.dwindle.arrange(p) + return spiral(p, false) +end + +--- Spiral layout +uselesspiral.name = "uselesspiral" +function uselesspiral.arrange(p) + return spiral(p, true) +end + +return uselesspiral diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua new file mode 100644 index 0000000..b82c97e --- /dev/null +++ b/layout/uselesstile.lua @@ -0,0 +1,232 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2009 Donald Ephraim Curtis + * (c) 2008 Julien Danjolu + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") +local ipairs = ipairs +local math = { floor = math.floor, + max = math.max, + min = math.min } +local tonumber = tonumber + +local uselesstile = {} + +local function tile_group(cls, wa, orientation, fact, group) + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width . + local useless_gap = tonumber(beautiful.useless_gap_width) + if useless_gap == nil + then + useless_gap = 0 + end + + -- get our orientation right + local height = "height" + local width = "width" + local x = "x" + local y = "y" + if orientation == "top" or orientation == "bottom" then + height = "width" + width = "height" + x = "y" + y = "x" + end + + -- make this more generic (not just width) + available = wa[width] - (group.coord - wa[x]) + + -- find our total values + local total_fact = 0 + local min_fact = 1 + local size = group.size + for c = group.first,group.last do + -- determine the width/height based on the size_hint + local i = c - group.first +1 + local size_hints = cls[c].size_hints + local size_hint = size_hints["min_"..width] or size_hints["base_"..width] or 0 + size_hint = size_hint + cls[c].border_width*2 + size = math.max(size_hint, size) + + -- calculate the height + if not fact[i] then + fact[i] = min_fact + else + min_fact = math.min(fact[i],min_fact) + end + total_fact = total_fact + fact[i] + end + size = math.min(size, available) + + local coord = wa[y] + local geom = {} + local used_size = 0 + local unused = wa[height] + local stat_coord = wa[x] + --stat_coord = size + for c = group.first,group.last do + local i = c - group.first +1 + geom[width] = size + geom[height] = math.floor(unused * fact[i] / total_fact) + geom[x] = group.coord + geom[y] = coord + + coord = coord + geom[height] + unused = unused - geom[height] + total_fact = total_fact - fact[i] + used_size = math.max(used_size, geom[width]) + + -- Useless gap + if useless_gap > 0 + then + -- Top and left clients are shrinked by two steps and + -- get moved away from the border. Other clients just + -- get shrinked in one direction. + + top = false + left = false + + if geom[y] == wa[y] then + top = true + end + + if geom[x] == 0 or geom[x] == wa[x] then + left = true + end + + if top then + geom[height] = geom[height] - 2 * useless_gap + geom[y] = geom[y] + useless_gap + else + geom[height] = geom[height] - useless_gap + end + + if left then + geom[width] = geom[width] - 2 * useless_gap + geom[x] = geom[x] + useless_gap + else + geom[width] = geom[width] - useless_gap + end + end + -- End of useless gap. + + geom = cls[c]:geometry(geom) + end + + return used_size +end + +local function tile(param, orientation) + local t = tag.selected(param.screen) + orientation = orientation or "right" + + -- this handles are different orientations + local height = "height" + local width = "width" + local x = "x" + local y = "y" + if orientation == "top" or orientation == "bottom" then + height = "width" + width = "height" + x = "y" + y = "x" + end + + local cls = param.clients + local nmaster = math.min(tag.getnmaster(t), #cls) + local nother = math.max(#cls - nmaster,0) + + local mwfact = tag.getmwfact(t) + local wa = param.workarea + local ncol = tag.getncol(t) + + local data = tag.getdata(t).windowfact + + if not data then + data = {} + tag.getdata(t).windowfact = data + end + + local coord = wa[x] + local place_master = true + if orientation == "left" or orientation == "top" then + -- if we are on the left or top we need to render the other windows first + place_master = false + end + + -- this was easier than writing functions because there is a lot of data we need + for d = 1,2 do + if place_master and nmaster > 0 then + local size = wa[width] + if nother > 0 then + size = math.min(wa[width] * mwfact, wa[width] - (coord - wa[x])) + end + if not data[0] then + data[0] = {} + end + coord = coord + tile_group(cls, wa, orientation, data[0], {first=1, last=nmaster, coord = coord, size = size}) + end + + if not place_master and nother > 0 then + local last = nmaster + + -- we have to modify the work area size to consider left and top views + local wasize = wa[width] + if nmaster > 0 and (orientation == "left" or orientation == "top") then + wasize = wa[width] - wa[width]*mwfact + end + for i = 1,ncol do + -- Try to get equal width among remaining columns + local size = math.min( (wasize - (coord - wa[x])) / (ncol - i + 1) ) + local first = last + 1 + last = last + math.floor((#cls - last)/(ncol - i + 1)) + -- tile the column and update our current x coordinate + if not data[i] then + data[i] = {} + end + coord = coord + tile_group(cls, wa, orientation, data[i], { first = first, last = last, coord = coord, size = size }) + end + end + place_master = not place_master + end + +end + +uselesstile.right = {} +uselesstile.right.name = "uselesstile" +uselesstile.right.arrange = tile + +--- The main tile algo, on left. +-- @param screen The screen number to tile. +uselesstile.left = {} +uselesstile.left.name = "uselesstileleft" +function uselesstile.left.arrange(p) + return tile(p, "left") +end + +--- The main tile algo, on bottom. +-- @param screen The screen number to tile. +uselesstile.bottom = {} +uselesstile.bottom.name = "uselesstilebottom" +function uselesstile.bottom.arrange(p) + return tile(p, "bottom") +end + +--- The main tile algo, on top. +-- @param screen The screen number to tile. +uselesstile.top = {} +uselesstile.top.name = "uselesstiletop" +function uselesstile.top.arrange(p) + return tile(p, "top") +end + +uselesstile.arrange = uselesstile.right.arrange +uselesstile.name = uselesstile.right.name + +return uselesstile diff --git a/scripts/checkmail b/scripts/checkmail new file mode 100755 index 0000000..67c5206 --- /dev/null +++ b/scripts/checkmail @@ -0,0 +1,104 @@ +#!/usr/bin/python + +# Simple email checker +# +# Wrote by copycat-killer on a rainy day of august 2013 +# to be used in Lain. +# +# https://github.com/copycat-killer/lain + +import sys, getopt, locale, imaplib + +def main(argv): + usage = "usage: checkmail -s -u -p [--port ] [--encoding ] [--cut]" + server = "" + user = "" + password = "" + port = 993 + cut = False + encoding = locale.getdefaultlocale()[1] + output = "" + + try: + opts, args = getopt.getopt(argv, "hs:u:p:", ["port=", "encoding=", "cut"]) + except getopt.GetoptError: + print(usage) + sys.exit(2) + + if len(argv) == 0: + print(usage) + sys.exit() + + for opt, arg in opts: + if opt == "-h": + print(usage) + sys.exit() + elif opt == "-s": + server = arg + elif opt == "-u": + user = arg + elif opt == "-p": + password = arg + elif opt == "--port": + port = int(arg) + elif opt == "--cut": + cut = True + elif opt == "--encoding": + encoding = arg + + try: + mail = imaplib.IMAP4_SSL(server, port) + mail.login(user, password) + except imaplib.IMAP4.error: + print("CheckMailError: invalid credentials") + sys.exit(2) + + status, counts = mail.status("Inbox","(MESSAGES UNSEEN)") + + unread = int(counts[0].split()[4][:-1]) + + if status == "OK" and unread: + mail.select("Inbox", readonly = 1) + ret, messages = mail.uid("search", None, "(UNSEEN)") + + if ret == "OK": + latest_email_uid = messages[0].split()[-1] + + ret_header, new_mail_header = mail.uid("fetch", latest_email_uid, + "(BODY.PEEK[HEADER.FIELDS (SUBJECT FROM)])") + ret_text, new_mail_text = mail.uid("fetch", latest_email_uid, "(BODY[TEXT])") + + if ret_header == "OK" and ret_text == "OK": + try: # not all the servers like this, that's why we try + mail.store(latest_email_uid, "-FLAGS", "\\Seen") + except imaplib.IMAP4.error: + # this simply means the server refused to + # toggle Seen flag from mail + print("[+Seen]\n") + + nm_header = new_mail_header[0][1].decode(encoding, "replace").strip() + nm_text = new_mail_text[0][1].decode(encoding, "replace").strip() + + if unread == 1: + print(user, "has 1 new message\n") + else: + print(user, "has", unread, "new messages\n") + nm_header.replace("From:", "Latest from:", 1) + + print(nm_header, "\n") + + if cut: + if len(nm_text) <= 100: + print(nm_text) + else: + print(nm_text[0:100]) + print("[...]") + else: + print(nm_text) + else: + print("No new messages") + + mail.logout() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/scripts/dfs b/scripts/dfs new file mode 100755 index 0000000..1730b6e --- /dev/null +++ b/scripts/dfs @@ -0,0 +1,385 @@ +#!/bin/bash +# +# Adapted from Eridan's "fs" (cleanup, enhancements and switch to bash/Linux) +# JM, 10/12/2004 +# +# Integrated into Lain in september 2013 +# https://github.com/copycat-killer/lain + +# ------------------------------------------------------------------------- +# Decoding options +# ------------------------------------------------------------------------- +USAGE="Usage: $0 [-h(elp)] | [-n(arrow mode)] | [-w(eb output)]" + +NARROW_MODE=0 +WEB_OUTPUT=0 + +while [ $# -gt 0 ]; do +case "$1" in +"-h" ) +echo $USAGE +exit +;; +"-d" ) +DEBUG=1 +;; +"-n" ) +NARROW_MODE=1 +;; +"-w" ) +WEB_OUTPUT=1 +;; +* ) +echo $USAGE +exit +;; +esac +shift +done + +# ------------------------------------------------------------------------- +# Preparations +# ------------------------------------------------------------------------- +SYSTEM=`uname -s` +PATTERN="/" + +case "$SYSTEM" in +"Linux" ) +DF_COMMAND="/usr/bin/env df -k" +SORT_COMMAND="/usr/bin/env sort -k6" +AWK_COMMAND="/usr/bin/env awk" +;; +* ) +DF_COMMAND="/bin/df -k" +SORT_COMMAND="/usr/bin/sort -k6" +AWK_COMMAND="/usr/bin/env gawk" +;; +esac + +# ------------------------------------------------------------------------- +# Grabbing "df" result +# ------------------------------------------------------------------------- +DF_RESULT=`$DF_COMMAND` +if [ ! -z $DEBUG ]; then +echo "--> DF_RESULT:" +echo "$DF_RESULT" +echo "" +fi + +# ------------------------------------------------------------------------- +# Preprocessing "df" result, to join split logical lines +# ------------------------------------------------------------------------- +PREPROCESSING_RESULT=` \ + echo "$DF_RESULT" | $AWK_COMMAND -v PATTERN=$PATTERN \ + ' + NF == 1 { + printf ("%s", $0) + } + +NF == 5 { + printf ("%s\n", $0) +} + +NF > 6 { +} + +NF == 6 { + printf ("%s\n", $0) +}' +` +if [ ! -z $DEBUG ]; then +echo "--> PREPROCESSING_RESULT:" +echo "$PREPROCESSING_RESULT" +echo "" +fi + +SORTED_FILE_SYSTEMS_INFO=`echo "$PREPROCESSING_RESULT" | $SORT_COMMAND` + +if [ ! -z $DEBUG ]; then +echo "--> SORTED_FILE_SYSTEMS_INFO:" +echo "$SORTED_FILE_SYSTEMS_INFO" +echo "" +fi + +# ------------------------------------------------------------------------- +# Computing mount point max length +# ------------------------------------------------------------------------- +MOUNT_POINT_MAX_LENGTH=` \ + echo $SORTED_FILE_SYSTEMS_INFO | $AWK_COMMAND -v PATTERN=$PATTERN \ + ' + BEGIN { + mount_point_length_max = 15; + } + +END { + printf ("%d", mount_point_length_max); +} + +$0 ~ PATTERN { +# printf ("$6 = %s\n", $6); + + mount_point = $6; +# printf ("mount_point = %s\n", mount_point); + + mount_point_length = length (mount_point); +# printf ("mount_point_length = %d\n", mount_point_length); + + if (mount_point_length > mount_point_length_max) + mount_point_length_max = mount_point_length; +}' +` +if [ ! -z $DEBUG ]; then +echo "MOUNT_POINT_MAX_LENGTH: $MOUNT_POINT_MAX_LENGTH" +fi + +# ------------------------------------------------------------------------- +# Computing mount point data max size +# ------------------------------------------------------------------------- +MOUNT_POINT_MAX_SIZE=` \ + echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v PATTERN=$PATTERN \ + ' + BEGIN { + mount_point_size_max = 0; + } + +END { + printf ("%d", mount_point_size_max); +} + +$0 ~ PATTERN { +# df -k shows k_bytes! +# printf ("$2 = %s\n", $2); + + mount_point_size = $2 * 1024; +# printf ("mount_point_size = %d\n", mount_point_size); + + if (mount_point_size > mount_point_size_max) + mount_point_size_max = mount_point_size; +}' +` +if [ ! -z $DEBUG ]; then +echo "MOUNT_POINT_MAX_SIZE: $MOUNT_POINT_MAX_SIZE" +fi + +# ------------------------------------------------------------------------- +# Let's go! +# ------------------------------------------------------------------------- +echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v DEBUG=$DEBUG -v PATTERN=$PATTERN -v NARROW_MODE=$NARROW_MODE -v LEFT_COLUMN=$MOUNT_POINT_MAX_LENGTH -v MAX_SIZE=$MOUNT_POINT_MAX_SIZE -v SCALE=$SCALE -v WEB_OUTPUT=$WEB_OUTPUT \ + ' +# {printf ("$0 = %s\n", $0);} +# {printf ("$1 = %s\n", $1);} +# {printf ("PATTERN = %s\n", PATTERN);} +# {printf ("LEFT_COLUMN = %s\n", LEFT_COLUMN);} + + BEGIN { + k_bytes = 1024.0; + m_bytes = 1024.0 * k_bytes; + g_bytes = 1024.0 * m_bytes; + t_bytes = 1024.0 * g_bytes; + + if (WEB_OUTPUT) + { + all_stars = "**************************************************"; + current_date = strftime ("%d-%m-%Y @ %H:%M:%S", localtime (systime ())); + free_threshold = 10; # % + + printf ("\n"); + + printf ( \ + "\n" \ + "

%s -- STATUS OF ALCOR FILE SYSTEMS


\n", + current_date ) + + printf ("\n"); + + printf ( \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" \ + "\n" ); + } + else + { + narrow_margin = " "; +# printf ("%-*s", LEFT_COLUMN + 2, "Mount point"); + if (NARROW_MODE) + printf ("\n%s", narrow_margin); + else + printf ("%-*s", LEFT_COLUMN + 2, ""); + print " Used Free Total "; + if (! NARROW_MODE) + print ""; + } + } + +END { + if (WEB_OUTPUT) + { + printf ("
Mount point%% Usato (*)" \ + " - %% Free (*)%% UsatoSpazio liberoSpazio totale
\n"); + + printf ("\n"); + } + else + { + if (NARROW_MODE) + printf ("%s", narrow_margin); + else + printf ("%-*s", LEFT_COLUMN + 2, ""); + print "|----|----|----|----|----|----|----|----|----|----|" + if (NARROW_MODE) + printf ("\n%s", narrow_margin); + else + printf ("%-*s", LEFT_COLUMN + 2, ""); + print "0 10 20 30 40 50 60 70 80 90 100"; + print ""; + } +} + +$0 ~ PATTERN { + + if (index ($0, "members") == 0 && index ($0, "Download") == 0 && index ($0, "admin") == 0) + { +# df -k shows k_bytes! + + total_size = $2 * k_bytes; + free_size = $4 * k_bytes; + percentage_occupied = substr($5, 0, 3); + mount_point = $6; + + percentage_free = int (100 - percentage_occupied); + +# reduction_factor: 2 + stars_number = int (percentage_occupied / 2); + + if (WEB_OUTPUT) + { + posGroup = index (mount_point, "scratch"); + if (posGroup == 0) + posGroup = index (mount_point, "u1"); + if (posGroup == 0) + posGroup = index (mount_point, "u2"); + if (posGroup == 0) + posGroup = index (mount_point, "u4"); + if (posGroup == 0) + posGroup = index (mount_point, "u5"); + + printf ("\n"); + + if (posGroup > 0 || percentage_free < free_threshold) + { + if (percentage_free < free_threshold) + { + class = "titlered"; + if (posGroup == 0) + posGroup = 1; # to display the whole mount_point in this color anyway + } + else if ((index (mount_point, "scratch") != 0) || (index (mount_point, "u1") != 0) || (index (mount_point, "u2") != 0)) + { + class = "titleorange"; + posGroup = 1; # to display the whole mount_point in this color + } + else if ((index (mount_point, "u4") != 0) || (index (mount_point, "u5") != 0)) + { + class = "titlebrown"; + posGroup = 1; # to display the whole mount_point in this color + } + + printf ( \ + "%s%s\n", + substr (mount_point, 1, posGroup - 1), + class, + substr (mount_point, posGroup) ); + } + else + { + printf ("%s\n", mount_point); + } + + printf ( \ + "%s%s\n", + substr (all_stars, 1, stars_number), substr (all_stars, stars_number + 1, 49) ); + + if (percentage_free < free_threshold) + { + color_beginning = ""; + color_end = "" + } + else + { + color_beginning = ""; + color_end = "" + } + + if (total_size > 1 * t_bytes) + printf ( \ + "%s%3d%%%s%5.1f Tb%5.1f Tb\n", \ + color_beginning, percentage_occupied, color_end, free_size / t_bytes, total_size / t_bytes \ + ); + else if (total_size > 1 * g_bytes) + printf ( \ + "%s%3d%%%s%5.1f Gb%5.1f Gb\n", \ + color_beginning, percentage_occupied, color_end, free_size / g_bytes, total_size / g_bytes \ + ); + else if (total_size > 1 * m_byptes) + printf ( \ + "%s%3d%%%s%5.1f Mb%5.1f Mb\n", \ + color_beginning, percentage_occupied, color_end, free_size / m_bytes, total_size / m_bytes \ + ); + else + printf ( \ + "%s%3d%%%s%5.1f Kb%5.1f Kb\n", \ + color_beginning, percentage_occupied, color_end, free_size / k_bytes, total_size / k_bytes \ + ); + + printf ("\n"); + } + + else + { +# printf ("percentage_occupied = %d\n", percentage_occupied); +# printf ("percentage_free = %d\n", percentage_free); + + printf ("%-*s", LEFT_COLUMN + 2, mount_point); + if (NARROW_MODE) + printf ("\n%s", narrow_margin); + +# printf ("stars_number = %d\n", stars_number); + + printf ("|"); + for (i = 1; i <= stars_number; i++) + { + printf ("%s", "*"); + } + for (i = stars_number + 1; i <= 49; i++) + { + printf ("%s", "-"); + } + + + if (total_size > 1 * t_bytes) + printf ( \ + "| %3d%% %5.1f %5.1f Tb\n", \ + percentage_occupied, free_size / t_bytes, total_size / t_bytes \ + ); + else if (total_size > 1 * g_bytes) + printf ( \ + "| %3d%% %5.1f %5.1f Gb\n", \ + percentage_occupied, free_size / g_bytes, total_size / g_bytes \ + ); + else if (total_size > 1 * m_byptes) + printf ( \ + "| %3d%% %5.1f %5.1f Mb\n", \ + percentage_occupied, free_size / m_bytes, total_size / m_bytes \ + ); + else + printf ( \ + "| %3d%% %5.1f %5.1f Kb\n", \ + percentage_occupied, free_size / k_bytes, total_size / k_bytes \ + ); + } + } # if +}' diff --git a/scripts/mpdcover b/scripts/mpdcover new file mode 100755 index 0000000..38b43e9 --- /dev/null +++ b/scripts/mpdcover @@ -0,0 +1,64 @@ +#!/bin/bash +# +# A simple cover fetcher script for current playing song on mpd. +# +# Author : Wolfgang Mueller +# +# Adapted for Lain internal use. +# https://github.com/copycat-killer/lain +# +# You can use, edit and redistribute this script in any way you like. +# +# Dependencies: imagemagick. +# +# Usage: mpdcover + +# Configuration------------------------------------------------------- + +# Music directory +MUSIC_DIR=$1 + +# Song file +file=$2 + +# The default cover to use (optional) +DEFAULT_ART=$3 + +# Regex expression used for image search +IMG_REG="(front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$" + +# Path of temporary resized cover +TEMP_PATH="/tmp/mpdcover.png" + +# Resize cover +COVER_RESIZE="100x100" + +# Thumbnail background (transparent) +COVER_BACKGROUND="none" + +#-------------------------------------------------------------------- + +# check if anything is playing at all +[[ -z $file ]] && exit 1 + +# Art directory +art="$MUSIC_DIR/${file%/*}" + +# find every file that matches IMG_REG set the first matching file to be the +# cover. +cover="$(find "$art/" -maxdepth 1 -type f | egrep -i -m1 "$IMG_REG")" + +# when no cover is found, use DEFAULT_ART as cover +cover="${cover:=$DEFAULT_ART}" + +# check if art is available +if [[ -n $cover ]]; then + if [[ -n $COVER_RESIZE ]]; then + convert "$cover" -thumbnail $COVER_RESIZE -gravity center -background "$COVER_BACKGROUND" -extent $COVER_RESIZE "$TEMP_PATH" + cover="$TEMP_PATH" + fi +else + rm $TEMP_PATH +fi + +exit 0 diff --git a/util/init.lua b/util/init.lua new file mode 100644 index 0000000..a44d52c --- /dev/null +++ b/util/init.lua @@ -0,0 +1,174 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Utilities section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local awful = require("awful") +local beautiful = require("beautiful") +local math = { sqrt = math.sqrt } +local mouse = mouse +local pairs = pairs +local string = string +local client = client +local screen = screen +local tonumber = tonumber + +local wrequire = require("lain.helpers").wrequire +local setmetatable = setmetatable + +-- Lain utilities submodule +-- lain.util +local util = { _NAME = "lain.util" } + +-- Like awful.menu.clients, but only show clients of currently selected +-- tags. +function util.menu_clients_current_tags(menu, args) + -- List of currently selected tags. + local cls_tags = awful.tag.selectedlist(mouse.screen) + + -- Final list of menu items. + local cls_t = {} + + if cls_tags == nil + then + return nil + end + + -- For each selected tag get all clients of that tag and add them to + -- the menu. A click on a menu item will raise that client. + for i = 1,#cls_tags + do + local t = cls_tags[i] + local cls = t:clients() + + for k, c in pairs(cls) + do + cls_t[#cls_t + 1] = { awful.util.escape(c.name) or "", + function () + c.minimized = false + client.focus = c + c:raise() + end, + c.icon } + end + end + + -- No clients? Then quit. + if #cls_t <= 0 + then + return nil + end + + -- menu may contain some predefined values, otherwise start with a + -- fresh menu. + if not menu + then + menu = {} + end + + -- Set the list of items and show the menu. + menu.items = cls_t + local m = awful.menu.new(menu) + m:show(args) + return m +end + +-- Magnify a client: Set it to "float" and resize it. +function util.magnify_client(c) + awful.client.floating.set(c, true) + + local mg = screen[mouse.screen].geometry + local tag = awful.tag.selected(mouse.screen) + local mwfact = awful.tag.getmwfact(tag) + local g = {} + g.width = math.sqrt(mwfact) * mg.width + g.height = math.sqrt(mwfact) * mg.height + g.x = mg.x + (mg.width - g.width) / 2 + g.y = mg.y + (mg.height - g.height) / 2 + c:geometry(g) +end + +-- Read the nice value of pid from /proc. +local function get_nice_value(pid) + local n = first_line('/proc/' .. pid .. '/stat') + if n == nil + then + -- This should not happen. But I don't want to crash, either. + return 0 + end + + -- Remove pid and tcomm. This is necessary because tcomm may contain + -- nasty stuff such as whitespace or additional parentheses... + n = string.gsub(n, '.*%) ', '') + + -- Field number 17 now is the nice value. + fields = split(n, ' ') + return tonumber(fields[17]) +end + +-- To be used as a signal handler for "focus" +-- This requires beautiful.border_focus{,_highprio,_lowprio}. +function util.niceborder_focus(c) + local n = get_nice_value(c.pid) + if n == 0 + then + c.border_color = beautiful.border_focus + elseif n < 0 + then + c.border_color = beautiful.border_focus_highprio + else + c.border_color = beautiful.border_focus_lowprio + end +end + +-- To be used as a signal handler for "unfocus" +-- This requires beautiful.border_normal{,_highprio,_lowprio}. +function util.niceborder_unfocus(c) + local n = get_nice_value(c.pid) + if n == 0 + then + c.border_color = beautiful.border_normal + elseif n < 0 + then + c.border_color = beautiful.border_normal_highprio + else + c.border_color = beautiful.border_normal_lowprio + end +end + +-- Non-empty tag browsing +-- direction in {-1, 1} <-> {previous, next} non-empty tag +function util.tag_view_nonempty(direction, sc) + local s = sc or mouse.screen or 1 + local scr = screen[s] + + for i = 1, #tags[s] do + awful.tag.viewidx(direction,s) + if #awful.client.visible(s) > 0 then + return + end + end +end + +-- Dynamically rename the current tag you have focused. +function util.prompt_rename_tag(mypromptbox) + local tag = awful.tag.selected(mouse.screen) + awful.prompt.run({prompt="Rename tag: "}, mypromptbox[mouse.screen].widget, + function(text) + if text:len() > 0 then + tag.name = text + tag:emit_signal("property::name") + end + end) +end + +return setmetatable(util, { __index = wrequire }) diff --git a/util/markup.lua b/util/markup.lua new file mode 100644 index 0000000..e7baec0 --- /dev/null +++ b/util/markup.lua @@ -0,0 +1,102 @@ + +--[[ + + Licensed under MIT License + * (c) 2013, Luke Bonham + * (c) 2009, Uli Schlachter + * (c) 2009, Majic + +--]] + +local beautiful = require("beautiful") +local tostring = tostring +local setmetatable = setmetatable + +-- Lain markup util submodule +-- lain.util.markup +local markup = {} + +local fg = {} +local bg = {} + +--[[ clean this as soon as you document it + + +-- markup + | + |`-- bold() Set bold. + |`-- italic() Set italicized text. + |`-- strike() Set strikethrough text. + |`-- underline() Set underlined text. + |`-- monospace() Set monospaced text. + |`-- big() Set bigger text. + |`-- small() Set smaller text. + |`-- font() Set the font of the text. + | + |`--+ bg + | | + | |`-- color() Set background color. + | |`-- focus() Set focus background color. + | |`-- normal() Set normal background color. + | `-- urgent() Set urgent background color. + | + |`--+ fg + | | + | |`-- color() Set foreground color. + | |`-- focus() Set focus foreground color. + | |`-- normal() Set normal foreground color. + | `-- urgent() Set urgent foreground color. + | + |`-- focus() Set both foreground and background focus colors. + |`-- normal() Set both foreground and background normal colors. + `-- urgent() Set both foreground and background urgent colors. + +]] + +-- Convenience tags. +function markup.bold(text) return '' .. tostring(text) .. '' end +function markup.italic(text) return '' .. tostring(text) .. '' end +function markup.strike(text) return '' .. tostring(text) .. '' end +function markup.underline(text) return '' .. tostring(text) .. '' end +function markup.monospace(text) return '' .. tostring(text) .. '' end +function markup.big(text) return '' .. tostring(text) .. '' end +function markup.small(text) return '' .. tostring(text) .. '' end + +-- Set the font. +function markup.font(font, text) + return '' .. tostring(text) ..'' +end + +-- Set the foreground. +function fg.color(color, text) + return '' .. tostring(text) .. '' +end + +-- Set the background. +function bg.color(color, text) + return '' .. tostring(text) .. '' +end + +-- Context: focus +function fg.focus(text) return fg.color(beautiful.fg_focus, text) end +function bg.focus(text) return bg.color(beautiful.bg_focus, text) end +function markup.focus(text) return bg.focus(fg.focus(text)) end + +-- Context: normal +function fg.normal(text) return fg.color(beautiful.fg_normal, text) end +function bg.normal(text) return bg.color(beautiful.bg_normal, text) end +function markup.normal(text) return bg.normal(fg.normal(text)) end + +-- Context: urgent +function fg.urgent(text) return fg.color(beautiful.fg_urgent, text) end +function bg.urgent(text) return bg.color(beautiful.bg_urgent, text) end +function markup.urgent(text) return bg.urgent(fg.urgent(text)) end + +markup.fg = fg +markup.bg = bg + +-- link markup.{fg,bg}(...) calls to markup.{fg,bg}.color(...) +setmetatable(markup.fg, { __call = function(_, ...) return markup.fg.color(...) end }) +setmetatable(markup.bg, { __call = function(_, ...) return markup.bg.color(...) end }) + +-- link markup(...) calls to markup.fg.color(...) +return setmetatable(markup, { __call = function(_, ...) return markup.fg.color(...) end }) diff --git a/widgets/alsa.lua b/widgets/alsa.lua new file mode 100644 index 0000000..7c26908 --- /dev/null +++ b/widgets/alsa.lua @@ -0,0 +1,103 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + * (c) 2010, Adrian C. + +--]] + +local markup = require("lain.util.markup") +local run_in_terminal = require("lain.helpers").run_in_terminal + +local awful = require("awful") +local beautiful = require("beautiful") +local wibox = require("wibox") + +local io = io +local string = { format = string.format, + match = string.match } + +local setmetatable = setmetatable + +-- ALSA volume infos +-- nain.widgets.alsa +local alsa = { + volume = 0, + mute = false, +} + +function worker(args) + local args = args or {} + local channel = args.channel or "Master" + local step = args.step or "1%" + local header = args.header or " Vol " + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or "#FFFFFF" + + local myvolume = wibox.widget.textbox() + local myvolumeupdate = function() + local f = io.popen('amixer get ' .. channel) + local mixer = f:read("*all") + f:close() + + local volume, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + + if volume == nil + then + alsa.volume = 0 + else + alsa.volume = volume + end + + if mute == nil or mute == 'on' + then + alsa.mute = true + mute = '' + else + alsa.mute = false + mute = 'M' + end + + local ret = markup(color, string.format("%d%s", volume, mute)) + myvolume:set_markup(markup(header_color, header) .. ret .. " ") + end + + local myvolumetimer = timer({ timeout = 5 }) + myvolumetimer:connect_signal("timeout", myvolumeupdate) + myvolumetimer:start() + myvolumetimer:emit_signal("timeout") + + myvolume:buttons(awful.util.table.join( + awful.button({}, 1, + function() + run_in_terminal('alsamixer') + end), + awful.button({}, 3, + function() + awful.util.spawn('amixer sset ' .. channel ' toggle') + end), + + awful.button({}, 4, + function() + awful.util.spawn('amixer sset ' .. channel .. ' ' .. step '+') + myvolumeupdate() + end), + + awful.button({}, 5, + function() + awful.util.spawn('amixer sset ' .. channel .. ' ' .. step '-') + myvolumeupdate() + end) + )) + + alsa.widget = myvolume + alsa.channel = channel + alsa.step = step + alsa.notify = myvolumeupdate + + return setmetatable(alsa, { __index = alsa.widget }) +end + +return setmetatable(alsa, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua new file mode 100644 index 0000000..0421f5c --- /dev/null +++ b/widgets/alsabar.lua @@ -0,0 +1,164 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2013, Rman +--]] + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") + +local io = io +local math = { modf = math.modf } +local string = { match = string.match, + rep = string.rep } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- ALSA volume bar +-- lain.widgets.alsabar +local alsabar = +{ + channel = "Master", + step = "5%", + + colors = + { + background = beautiful.bg_normal, + mute = "#EB8F8F", + unmute = "#A4CE8A" + }, + + mixer = terminal .. " -e alsamixer", + + notifications = + { + font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), + font_size = "11", + bar_size = 18 -- Awesome default + }, + + _current_level = 0, + _muted = false +} + +function alsabar:notify() + local preset = + { + title = "", text = "", + timeout = 3, + font = alsabar.notifications.font .. " " .. alsabar.notifications.font_size, + fg = beautiful.fg_focus + } + + if alsabar._muted then + preset.title = alsabar.channel .. " - Muted" + else + preset.title = alsabar.channel .. " - " .. alsabar._current_level * 100 .. "%" + end + + local int = math.modf(alsabar._current_level * alsabar.notifications.bar_size) + preset.text = "[" .. string.rep("|", int) + .. string.rep(" ", alsabar.notifications.bar_size - int) .. "]" + + if alsabar._notify ~= nil then + alsabar._notify = naughty.notify ({ replaces_id = alsabar._notify.id, + preset = preset }) + else + alsabar._notify = naughty.notify ({ preset = preset }) + end +end + +function worker(args) + local args = args or {} + local width = args.width or 63 + local height = args.heigth or 1 + local ticks = args.ticks or true + local ticks_size = args.ticks_size or 7 + local vertical = args.vertical or false + alsabar.channel = args.channel or alsabar.channel + alsabar.step = args.step or alsabar.step + alsabar.colors = args.colors or alsabar.colors + alsabar.notifications = args.notifications or alsabar.notifications + + alsabar.bar = awful.widget.progressbar() + alsabar.bar:set_background_color(alsabar.colors.background) + alsabar.bar:set_color(alsabar.colors.unmute) + alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } }) + alsabar.bar:set_width(width) + alsabar.bar:set_height(height) + alsabar.bar:set_ticks(ticks) + alsabar.bar:set_ticks_size(ticks_size) + + if vertical then + alsabar.bar:set_vertical(true) + end + + local myvolumebarupdate = function() + -- Get mixer control contents + local f = io.popen("amixer get " .. alsabar.channel) + local mixer = f:read("*all") + f:close() + + -- Capture mixer control state: [5%] ... ... [on] + local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + -- Handle mixers without data + if volu == nil then + volu = 0 + mute = "off" + end + + alsabar._current_level = tonumber(volu) / 100 + alsabar.bar:set_value(alsabar._current_level) + + if mute == "" and volu == "0" or mute == "off" + then + alsabar._muted = true + alsabar.tooltip:set_text (" [Muted] ") + alsabar.bar:set_color(alsabar.colors.mute) + else + alsabar._muted = false + alsabar.tooltip:set_text(" " .. alsabar.channel .. ": " .. volu .. "% ") + alsabar.bar:set_color(alsabar.colors.unmute) + end + end + + local myvolumebartimer = timer({ timeout = 5 }) + myvolumebartimer:connect_signal("timeout", myvolumebarupdate) + myvolumebartimer:start() + myvolumebartimer:emit_signal("timeout") + + alsabar.bar:buttons (awful.util.table.join ( + awful.button ({}, 1, function() + awful.util.spawn(alsabar.mixer) + end), + awful.button ({}, 3, function() + awful.util.spawn("amixer sset " .. alsabar.channel .. " toggle") + myvolumebarupdate() + end), + awful.button ({}, 4, function() + awful.util.spawn("amixer sset " .. alsabar.channel .. " " + .. alsabar.step .. "+") + myvolumebarupdate() + end), + awful.button ({}, 5, function() + awful.util.spawn("amixer sset " .. alsabar.channel .. " " + .. alsabar.step .. "-") + myvolumebarupdate() + end) + )) + + return { widget = alsabar.bar, + channel = alsabar.channel, + step = alsabar.step, + notify = function() + myvolumebarupdate() + alsabar.notify() + end + } +end + +return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/bat.lua b/widgets/bat.lua new file mode 100644 index 0000000..0461607 --- /dev/null +++ b/widgets/bat.lua @@ -0,0 +1,147 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local markup = require("lain.util.markup") +local first_line = require("lain.helpers").first_line + +local beautiful = require("beautiful") +local naughty = require("naughty") +local wibox = require("wibox") + +local math = { floor = math.floor } +local string = { format = string.format } + +local setmetatable = setmetatable + +-- Battery infos +-- lain.widgets.bat +local bat = { + status = "not present", + perc = "N/A", + time = "N/A", +} + +function worker(args) + local args = args or {} + local battery = args.battery or "BAT0" + local show_all = args.show_all or false + local refresh_timeout = args.refresh_timeout or 30 + local header = args.header or " Bat " + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or "#FFFFFF" + local shadow = args.shadow or false + + local mybattery = wibox.widget.textbox() + + local mybatteryupdate = function() + local present = first_line("/sys/class/power_supply/" + .. battery + .. "/present") + + if present == "1" + then + local rate = first_line("/sys/class/power_supply/" + .. battery .. + "/power_now") + local ratev = first_line("/sys/class/power_supply/" + .. battery .. + "/voltage_now") + local rem = first_line("/sys/class/power_supply/" + .. battery .. + "/energy_now") + local tot = first_line("/sys/class/power_supply/" + .. battery .. + "/energy_full") + bat.status = first_line("/sys/class/power_supply/" + .. battery .. + "/status") + + local time_rat = 0 + if bat.status == "Charging" + then + status = "(+)" + time_rat = (tot - rem) / rate + elseif bat.status == "Discharging" + then + status = "(-)" + time_rat = rem / rate + else + status = "(.)" + end + + local hrs = math.floor(time_rat) + local min = (time_rat - hrs) * 60 + bat.time = string.format("%02d:%02d", hrs, min) + + local amount = (rem / tot) * 100 + + if shadow + then + bat.perc = string.format("%d", amount) + else + bat.perc = string.format("%d%%", amount) + end + + local watt = string.format("%.2fW", (rate * ratev) / 1e12) + + if show_all + then + text = watt .. " " .. bat.perc .. " " .. bat.time .. " " .. bat.status + else + text = bat.perc + end + + -- notifications for low and critical states + if amount <= 5 + then + naughty.notify{ + text = "shutdown imminent", + title = "battery nearly exhausted", + position = "top_right", + timeout = 15, + fg="#000000", + bg="#ffffff", + ontop = true + } + elseif amount <= 15 + then + old_id = naughty.notify{ + text = "plug the cable", + title = "battery low", + position = "top_right", + timeout = 5, + fg="#202020", + bg="#cdcdcd", + ontop = true + } + end + else + text = "none" + end + + if shadow + then + mybattery:set_text('') + else + mybattery:set_markup(markup(header_color, header) + .. markup(color, text) .. " ") + end + end + + local mybatterytimer = timer({ timeout = refresh_timeout }) + mybatterytimer:connect_signal("timeout", mybatteryupdate) + mybatterytimer:start() + mybatterytimer:emit_signal("timeout") + + bat.widget = mybattery + + return setmetatable(bat, { __index = bat.widget }) +end + +return setmetatable(bat, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/borderbox.lua b/widgets/borderbox.lua new file mode 100644 index 0000000..150c1c3 --- /dev/null +++ b/widgets/borderbox.lua @@ -0,0 +1,61 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local wibox = require("awful.wibox") +local setmetatable = setmetatable + +-- Creates a thin wibox at a position relative to another wibox +-- lain.widgets.borderbox +local borderbox = {} + +local function worker(relbox, s, args) + local where = args.position or 'above' + local color = args.color or '#FFFFFF' + local size = args.size or 1 + local box = nil + local wiboxarg = { + position = nil, + bg = color + } + + if where == 'above' + then + wiboxarg.width = relbox.width + wiboxarg.height = size + box = wibox(wiboxarg) + box.x = relbox.x + box.y = relbox.y - size + elseif where == 'below' + then + wiboxarg.width = relbox.width + wiboxarg.height = size + box = wibox(wiboxarg) + box.x = relbox.x + box.y = relbox.y + relbox.height + elseif where == 'left' + then + wiboxarg.width = size + wiboxarg.height = relbox.height + box = wibox(wiboxarg) + box.x = relbox.x - size + box.y = relbox.y + elseif where == 'right' + then + wiboxarg.width = size + wiboxarg.height = relbox.height + box = wibox(wiboxarg) + box.x = relbox.x + relbox.width + box.y = relbox.y + end + + box.screen = s + return box +end + +return setmetatable(borderbox, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/calendar.lua b/widgets/calendar.lua new file mode 100644 index 0000000..4b6d469 --- /dev/null +++ b/widgets/calendar.lua @@ -0,0 +1,124 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +local icons_dir = require("lain.helpers").icons_dir + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") + +local io = io +local os = { date = os.date } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- Calendar notification +-- lain.widgets.calendar +local calendar = {} +local notification = nil + +local function create(background, foreground) + calendar.offset = 0 + calendar.icons_dir = icons_dir .. "cal/white/" -- default + calendar.notify_icon = nil + calendar.font_size = 12 + calendar.bg = background or beautiful.bg_normal or "#FFFFFF" + calendar.fg = foreground or beautiful.fg_normal or "#FFFFFF" +end + +function calendar:hide() + if notification ~= nil then + naughty.destroy(notification) + notification = nil + end +end + +function calendar:show(t_out, inc_offset) + calendar:hide() + + local offs = inc_offset or 0 + local tims = t_out or 0 + local f, c_text + local today = tonumber(os.date('%d')) + local init_t = '/usr/bin/cal | sed -r -e "s/(^| )( ' + -- let's take font only, font size is set in calendar table + local font = beautiful.font:sub(beautiful.font:find(""), + beautiful.font:find(" ")) + + if offs == 0 + then -- current month showing, today highlighted + if today >= 10 + then + init_t = '/usr/bin/cal | sed -r -e "s/(^| )(' + end + + calendar.offset = 0 + calendar.notify_icon = calendar.icons_dir .. today .. ".png" + + -- bg and fg inverted to highlight today + f = io.popen( init_t .. today .. + ')($| )/\\1\\2<\\/span><\\/b>\\3/"' ) + + else -- no current month showing, no day to highlight + local month = tonumber(os.date('%m')) + local year = tonumber(os.date('%Y')) + + calendar.offset = calendar.offset + offs + month = month + calendar.offset + + if month > 12 then + month = month % 12 + year = year + 1 + if month <= 0 then + month = 12 + end + elseif month < 1 then + month = month + 12 + year = year - 1 + if month <= 0 then + month = 1 + end + end + + calendar.notify_icon = nil + + f = io.popen('/usr/bin/cal ' .. month .. ' ' .. year) + end + + + c_text = "" + .. f:read() .. "\n\n" + .. f:read() .. "\n" + .. f:read("*all"):gsub("\n*$", "") + .. "" + f:close() + + notification = naughty.notify({ text = c_text, + icon = calendar.notify_icon, + fg = calendar.fg, + bg = calendar.bg, + timeout = tims }) +end + +function calendar:attach(widget, background, foreground) + create(background, foreground) + widget:connect_signal("mouse::enter", function () calendar:show() end) + widget:connect_signal("mouse::leave", function () calendar:hide() end) + widget:buttons(awful.util.table.join( awful.button({ }, 1, function () + calendar:show(0, -1) end), + awful.button({ }, 3, function () + calendar:show(0, 1) end) )) +end + +return setmetatable(calendar, { __call = function(_, ...) return create(...) end }) diff --git a/widgets/cpu.lua b/widgets/cpu.lua new file mode 100644 index 0000000..cf0b76c --- /dev/null +++ b/widgets/cpu.lua @@ -0,0 +1,80 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local markup = require("lain.util.markup") +local first_line = require("lain.helpers").first_line + +local beautiful = require("beautiful") +local wibox = require("wibox") + +local math = { ceil = math.ceil } +local string = { format = string.format, + gmatch = string.gmatch } + +local setmetatable = setmetatable + +-- CPU usage +-- lain.widgets.cpu +local cpu = { + last_total = 0, + last_active = 0 +} + +function worker(args) + local args = args or {} + local refresh_timeout = args.refresh_timeout or 5 + local header = args.header or " Cpu " + local header_color = args.header or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or "#FFFFFF" + local footer = args.footer or "%" + + local w = wibox.widget.textbox() + + local cpuusageupdate = function() + -- Read the amount of time the CPUs have spent performing + -- different kinds of work. Read the first line of /proc/stat + -- which is the sum of all CPUs. + local times = first_line("/proc/stat") + local at = 1 + local idle = 0 + local total = 0 + for field in string.gmatch(times, "[%s]+([^%s]+)") + do + -- 3 = idle, 4 = ioWait. Essentially, the CPUs have done + -- nothing during these times. + if at == 3 or at == 4 + then + idle = idle + field + end + total = total + field + at = at + 1 + end + local active = total - idle + + -- Read current data and calculate relative values. + local dactive = active - cpu.last_active + local dtotal = total - cpu.last_total + local dta = math.ceil((dactive / dtotal) * 100) + + w:set_markup(markup(header_color, header) .. markup(color, dta .. footer) .. " ") + + -- Save current data for the next run. + cpu.last_active = active + cpu.last_total = total + end + + local cpuusagetimer = timer({ timeout = refresh_timeout }) + cpuusagetimer:connect_signal("timeout", cpuusageupdate) + cpuusagetimer:start() + cpuusagetimer:emit_signal("timeout") + + return w +end + +return setmetatable(cpu, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/fs.lua b/widgets/fs.lua new file mode 100644 index 0000000..9611617 --- /dev/null +++ b/widgets/fs.lua @@ -0,0 +1,134 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010, Adrian C. + * (c) 2009, Lucas de Vries + +--]] + +local markup = require("lain.util.markup") +local helpers = require("lain.helpers") + +local beautiful = require("beautiful") +local wibox = require("wibox") +local naughty = require("naughty") + +local io = io +local string = { match = string.match } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- File system disk space usage +-- lain.widgets.fs +local fs = {} +local notification = nil + +function fs:hide() + if notification ~= nil then + naughty.destroy(notification) + notification = nil + end +end + +function fs:show(t_out) + fs:hide() + + local f = io.popen(helpers.scripts_dir .. "dfs") + ws = f:read("*all"):gsub("\n*$", "") + f:close() + + notification = naughty.notify({ + text = ws, + timeout = t_out, + fg = beautiful.fg_focus, + }) +end + +-- Variable definitions +local unit = { ["mb"] = 1024, ["gb"] = 1024^2 } + +local function worker(args) + local args = args or {} + local partition = args.partition or "/" + local refresh_timeout = args.refresh_timeout or 600 + local header = args.header or " Hdd " + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or "#FFFFFF" + local footer = args.header or "" + local shadow = args.shadow or false + + local myfs = wibox.widget.textbox() + + helpers.set_map("fs", false) + + local fsupdate = function() + local fs_info = {} -- Get data from df + local f = io.popen("LC_ALL=C df -kP") + + local function set_text() + local info = fs_info['{' .. partition .. ' used_p}'] + myfs:set_markup(markup(header_color, header) + .. markup(color, info .. footer) .. " ") + end + + for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount) + local s = string.match(line, "^.-[%s]([%d]+)") + local u,a,p = string.match(line, "([%d]+)[%D]+([%d]+)[%D]+([%d]+)%%") + local m = string.match(line, "%%[%s]([%p%w]+)") + + if u and m then -- Handle 1st line and broken regexp + helpers.uformat(fs_info, m .. " used", u, unit) + fs_info["{" .. m .. " used_p}"] = tonumber(p) + end + end + + f:close() + + if shadow + then + myfs:set_text('') + else + set_text() + end + + local part = fs_info['{' .. partition .. ' used_p}'] + + if part >= 90 then + if part >= 99 and not helpers.get_map("fs") then + naughty.notify({ title = "warning", + text = partition .. " ran out!\n" + .. "make some room", + timeout = 8, + position = "top_right", + fg = beautiful.fg_urgent, + bg = beautiful.bg_urgent }) + helpers.set_map("fs", true) + end + if shadow then set_text() end + end + end + + local fstimer = timer({ timeout = refresh_timeout }) + fstimer:connect_signal("timeout", fsupdate) + fstimer:start() + fstimer:emit_signal("timeout") + + myfs:connect_signal('mouse::enter', function () fs:show(0) end) + myfs:connect_signal('mouse::leave', function () fs:hide() end) + + local fs_out = + { + widget = myfs, + show = function(t_out) + fsupdate() + fs:show(t_out) + end + } + + return setmetatable(fs_out, { __index = fs_out.widget }) +end + +return setmetatable(fs, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/imap.lua b/widgets/imap.lua new file mode 100644 index 0000000..94652b6 --- /dev/null +++ b/widgets/imap.lua @@ -0,0 +1,166 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +local markup = require("lain.util.markup") +local helpers = require("lain.helpers") + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") +local wibox = require("wibox") + +local io = io +local tonumber = tonumber +local string = string + +local setmetatable = setmetatable + +-- Mail imap check +-- lain.widgets.imap +local imap = {} + +function worker(args) + local args = args or {} + + local server = args.server + local mail = args.mail + local password = args.password + + local port = args.port or "993" + local refresh_timeout = args.refresh_timeout or 60 + local header = args.header or " Mail " + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color_newmail = args.color_newmail or beautiful.fg_focus or "#FFFFFF" + local color_nomail = args.color_nomail or beautiful.fg_normal or "#FFFFFF" + local mail_encoding = args.mail_encoding or nil + local maxlen = args.maxlen or 200 + local app = args.app or "mutt" + local is_plain = args.is_plain or false + local shadow = args.shadow or false + + helpers.set_map(mail, true) + helpers.set_map(mail .. " count", "0") + + local checkmail = helpers.scripts_dir .. "checkmail" + + if not is_plain + then + local f = io.popen(password) + password = f:read("*all"):gsub("\n", ""):gsub("\r", "") + f:close() + end + + local myimapcheck = wibox.widget.textbox() + + local myimapcheckupdate = function() + function set_nomail() + if shadow + then + myimapcheck:set_text('') + else + myimapcheck:set_markup(markup(color_nomail, " no mail ")) + end + end + + conn = io.popen("ip link show") + check_conn = conn:read("*all") + conn:close() + + if not check_conn:find("state UP") then + set_nomail() + return + end + + to_execute = checkmail .. ' -s ' .. server .. + ' -u ' .. mail .. ' -p ' .. password + .. ' --port ' .. port + + if mail_encoding ~= nil + then + to_execute = to_execute .. ' --encoding ' + .. mail_encoding + end + + f = io.popen(to_execute) + ws = f:read("*all") + f:close() + + if ws:find("No new messages") ~= nil + then + helpers.set_map(mail, true) + set_nomail() + elseif ws:find("CheckMailError: invalid credentials") ~= nil + then + helpers.set_map(mail, true) + myimapcheck.set_markup(markup(header_color, header) .. + markup(color_newmail, "invalid credentials ")) + else + mailcount = ws:match("%d") or "?" + + if helpers.get_map(mail .. " count") ~= mailcount and mailcount ~= "?" + then + helpers.set_map(mail, true) + helpers.set_map(mail .. " count", mailcount) + end + + myimapcheck:set_markup(markup(header_color, header) .. + markup(color_newmail, mailcount) .. " ") + + if helpers.get_map(mail) + then + if mailcount == "?" + -- May happens sometimes using keyrings or other password fetchers. + -- Since this should be automatically fixed in short times, we threat + -- this exception delaying the update to the next timeout. + then + set_nomail() + return + elseif tonumber(mailcount) >= 1 + then + notify_title = ws:match(mail .. " has %d new message.?") + ws = ws:gsub(notify_title, "", 1):gsub("\n", "", 2) + + ws = ws:gsub("--Content.%S+.-\n", "") + ws = ws:gsub("--%d+.-\n", "") + + if string.len(ws) > maxlen + then + ws = ws:sub(1, maxlen) .. "[...]" + end + + notify_title = notify_title:gsub("\n", "") + end + + naughty.notify({ title = notify_title, + fg = color_newmail, + text = ws, + icon = beautiful.lain_mail_notify or + helpers.icons_dir .. "mail.png", + timeout = 8, + position = "top_left" }) + + helpers.set_map(mail, false) + end + end + end + + local myimapchecktimer = timer({ timeout = refresh_timeout }) + myimapchecktimer:connect_signal("timeout", myimapcheckupdate) + myimapchecktimer:start() + myimapcheck:buttons(awful.util.table.join( + awful.button({}, 0, + + function() + helpers.run_in_terminal(app) + end) + )) + + return myimapcheck +end + +return setmetatable(imap, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/init.lua b/widgets/init.lua new file mode 100644 index 0000000..78cac9b --- /dev/null +++ b/widgets/init.lua @@ -0,0 +1,24 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + Widgets section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local wrequire = require("lain.helpers").wrequire +local setmetatable = setmetatable + +local widgets = +{ + _NAME = "lain.widgets", + terminal = "xterm" -- X default +} + +return setmetatable(widgets, { __index = wrequire }) diff --git a/widgets/maildir.lua b/widgets/maildir.lua new file mode 100644 index 0000000..b5437bd --- /dev/null +++ b/widgets/maildir.lua @@ -0,0 +1,129 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local markup = require("lain.util.markup") +local run_in_terminal = require("lain.helpers").run_in_terminal + +local awful = require("awful") +local beautiful = require("beautiful") +local wibox = require("wibox") + +local io = io +local os = { getenv = os.getenv } +local pairs = pairs +local string = { len = string.len, + match = string.match } +local table = { sort = table.sort } + +local setmetatable = setmetatable + +-- Maildir check +-- lain.widgets.maildir +local maildir = {} + +function worker(args) + local args = args or {} + local mailpath = args.mailpath or os.getenv("HOME") .. "/Mail" + local ignore_boxes = args.ignore_boxes or {} + local refresh_timeout = args.refresh_timeout or 60 + local header = args.header or " Mail " + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color_newmail = args.color_newmail or beautiful.fg_focus or "#FFFFFF" + local color_nomail = args.color_nomail or beautiful.fg_normal or "#FFFFFF" + local app = args.app or "mutt" + local shadow = args.shadow or false + + local mymailcheck = wibox.widget.textbox() + local mymailcheckupdate = function() + -- Find pathes to mailboxes. + local p = io.popen("find " .. mailpath .. + " -mindepth 1 -maxdepth 1 -type d" .. + " -not -name .git") + local boxes = {} + local line = "" + repeat + line = p:read("*l") + if line ~= nil + then + -- Find all files in the "new" subdirectory. For each + -- file, print a single character (no newline). Don't + -- match files that begin with a dot. + -- Afterwards the length of this string is the number of + -- new mails in that box. + local np = io.popen("find " .. line .. + "/new -mindepth 1 -type f " .. + "-not -name '.*' -printf a") + local mailstring = np:read("*all") + + -- Strip off leading mailpath. + local box = string.match(line, mailpath .. "/*([^/]+)") + local nummails = string.len(mailstring) + if nummails > 0 + then + boxes[box] = nummails + end + end + until line == nil + + table.sort(boxes) + + local newmail = "" + local count = 0 + for box, number in pairs(boxes) + do + count = count + 1 + -- Add this box only if it's not to be ignored. + if not util.element_in_table(box, ignore_boxes) + then + if newmail == "" + then + newmail = box .. "(" .. number .. ")" + else + newmail = newmail .. ", " .. + box .. "(" .. number .. ")" + end + end + end + + if count == 1 then + -- it will be only executed once + for box, number in pairs(boxes) + do -- it's useless to show only INBOX(x) + if box == "INBOX" then newmail = number end + end + end + + if newmail == "" + then + if shadow + then + mymailcheck:set_text('') + else + myimapcheck:set_markup(markup(color_nomail, " no mail ")) + end + else + myimapcheck:set_markup(markup(header_color, header) .. + markup(color_newmail, newmail) .. " ") + end + end + + local mymailchecktimer = timer({ timeout = refresh_timeout }) + mymailchecktimer:connect_signal("timeout", mymailcheckupdate) + mymailchecktimer:start() + mymailcheck:buttons(awful.util.table.join( + awful.button({}, 0, + function() + run_in_terminal(app) + end) + )) + + return mymailcheck +end + +return setmetatable(maildir, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/mem.lua b/widgets/mem.lua new file mode 100644 index 0000000..09be00f --- /dev/null +++ b/widgets/mem.lua @@ -0,0 +1,87 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + * (c) 2010, Adrian C. + * (c) 2009, Lucas de Vries + +--]] + +local markup = require("lain.util.markup") +local run_in_terminal = require("lain.helpers").run_in_terminal + +local beautiful = require("beautiful") +local wibox = require("wibox") + +local io = { lines = io.lines } +local math = { floor = math.floor } +local string = { format = string.format, + gmatch = string.gmatch, + len = string.len } + +local setmetatable = setmetatable + +-- Memory usage (ignoring caches) +-- lain.widgets.mem +local mem = {} + +function worker(args) + local args = args or {} + local refresh_timeout = args.refresh_timeout or 10 + local show_swap = args.show_swap or false + local show_total = args.show_total or false + local header = args.header or " Mem " + local header_color = args.header or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or "#FFFFFF" + local footer = args.footer or "MB" + + local widg = wibox.widget.textbox() + + local upd = function() + local mem = {} + for line in io.lines("/proc/meminfo") + do + for k, v in string.gmatch(line, "([%a]+):[%s]+([%d]+).+") + do + if k == "MemTotal" then mem.total = math.floor(v / 1024) + elseif k == "MemFree" then mem.free = math.floor(v / 1024) + elseif k == "Buffers" then mem.buf = math.floor(v / 1024) + elseif k == "Cached" then mem.cache = math.floor(v / 1024) + elseif k == "SwapTotal" then mem.swap = math.floor(v / 1024) + elseif k == "SwapFree" then mem.swapf = math.floor(v / 1024) + end + end + end + + used = mem.total - (mem.free + mem.buf + mem.cache) + swapused = mem.swap - mem.swapf + + if show_total + then + local fmt = "%" .. string.len(mem.total) .. ".0f/%.0f" + widg:set_markup(markup(header_color, header) .. + markup(color, string.format(fmt, used, mem.total) .. footer .. " ")) + else + widg:set_markup(markup(header_color, header) .. + markup(color, used .. footer .. " ")) + end + + if show_swap + then + widg:set_markup(widg._layout.text .. ' (' + .. string.format('%.0f '.. footer, swapused) + .. ') ') + end + end + + local tmr = timer({ timeout = refresh_timeout }) + tmr:connect_signal("timeout", upd) + tmr:start() + tmr:emit_signal("timeout") + + return widg +end + +return setmetatable(mem, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/mpd.lua b/widgets/mpd.lua new file mode 100644 index 0000000..dcb7101 --- /dev/null +++ b/widgets/mpd.lua @@ -0,0 +1,138 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010, Adrian C. + +--]] + +local markup = require("lain.util.markup") +local helpers = require("lain.helpers") + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") +local wibox = require("wibox") + +local io = io +local os = { execute = os.execute, + getenv = os.getenv } +local string = { gmatch = string.gmatch } + +local setmetatable = setmetatable + +-- MPD infos +-- lain.widgets.mpd +local mpd = { id = nil } + +function worker(args) + local args = args or {} + local password = args.password or "" + local host = args.host or "127.0.0.1" + local port = args.port or "6600" + local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" + local refresh_timeout = args.refresh_timeout or 1 + local notify_timeout = args.notify_timeout or 5 + local color_artist = args.color_artist or beautiful.fg_normal or "#FFFFFF" + local color_song = args.color_song or beautiful.fg_focus or "#FFFFFF" + local spr = args.spr or "" + local musicplr = args.musicplr or "ncmpcpp" + local shadow = args.shadow or false + + local mpdcover = helpers.scripts_dir .. "mpdcover" + local mpdh = "telnet://"..host..":"..port + local echo = "echo 'password "..password.."\nstatus\ncurrentsong\nclose'" + + local mympd = wibox.widget.textbox() + + helpers.set_map("current mpd track", nil) + + local mympdupdate = function() + local function set_nompd() + if shadow + then + mympd:set_text('') + else + mympd:set_markup(markup(color_artist, " mpd "), markup(color_song , "off ")) + end + end + + local mpd_state = { + ["{state}"] = "N/A", + ["{file}"] = "N/A", + ["{Artist}"] = "N/A", + ["{Title}"] = "N/A", + ["{Album}"] = "N/A", + ["{Date}"] = "N/A" + } + + -- Get data from MPD server + local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh) + + for line in f:lines() do + for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do + if k == "state" then mpd_state["{"..k.."}"] = v + elseif k == "file" then mpd_state["{"..k.."}"] = v + elseif k == "Artist" then mpd_state["{"..k.."}"] = awful.util.escape(v) + elseif k == "Title" then mpd_state["{"..k.."}"] = awful.util.escape(v) + elseif k == "Album" then mpd_state["{"..k.."}"] = awful.util.escape(v) + elseif k == "Date" then mpd_state["{"..k.."}"] = awful.util.escape(v) + end + end + end + + f:close() + + if mpd_state["{state}"] == "play" + then + if mpd_state["{Title}"] ~= helpers.get_map("current mpd track") + then + helpers.set_map("current mpd track", mpd_state["{Title}"]) + os.execute(mpdcover .. " '" .. music_dir .. "' '" + .. mpd_state["{file}"] .. "'") + mpd.id = naughty.notify({ + title = "Now playing", + text = mpd_state["{Artist}"] .. " (" .. + mpd_state["{Album}"] .. ") - " .. + mpd_state["{Date}"] .. "\n" .. + mpd_state["{Title}"], + icon = "/tmp/mpdcover.png", + fg = beautiful.fg_focus or "#FFFFFF", + bg = beautiful.bg_normal or "#000000" , + timeout = notify_timeout, + replaces_id = mpd.id + }).id + end + mympd:set_markup(markup(color_artist, " " .. mpd_state["{Artist}"]) + .. spr .. + markup(color_song, " " .. mpd_state["{Title}"] .. " ")) + elseif mpd_state["{state}"] == "pause" + then + mympd:set_markup(markup(color_artist, " mpd") + .. spr .. + markup(color_song, " paused ")) + else + helpers.set_map("current mpd track", nil) + set_nompd() + end + end + + local mympdtimer = timer({ timeout = refresh_timeout }) + mympdtimer:connect_signal("timeout", mympdupdate) + mympdtimer:start() + mympdtimer:emit_signal("timeout") + + mympd:buttons(awful.util.table.join( + awful.button({}, 0, + function() + helpers.run_in_terminal(musicplr) + end) + )) + + local mpd_out = { widget = mympd, notify = mympdupdate } + + return setmetatable(mpd_out, { __index = mpd_out.widget }) +end + +return setmetatable(mpd, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/net.lua b/widgets/net.lua new file mode 100644 index 0000000..f361146 --- /dev/null +++ b/widgets/net.lua @@ -0,0 +1,153 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local markup = require("lain.util.markup") +local helpers = require("lain.helpers") + +local awful = require("awful") +local beautiful = require("beautiful") +local wibox = require("wibox") + +local io = io +local tostring = tostring +local string = { format = string.format } + +local setmetatable = setmetatable + +-- Network infos +-- lain.widgets.net +local net = { + send = "0", + recv = "0", + last_t = {}, + last_r = {} +} + +local unit = { + ["b"] = 1, + ["kb"] = 1024, + ["mb"] = 1024^2, + ["gb"] = 1024^3 +} + +function net.get_device() + f = io.popen("ip link show | cut -d' ' -f2,9") + ws = f:read("*all") + f:close() + ws = ws:match("%w+: UP") + if ws ~= nil then + return ws:gsub(": UP", "") + else + return "" + end +end + +function worker(args) + local args = args or {} + local iface = args.iface or net.get_device() + local delta = args.refresh_timeout or 2 + local unit = args.unit or unit["kb"] + local spr = args.spr or " " + local header = args.header or iface + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color_up = args.color_up or beautiful.fg_focus or header_color + local color_down = args.color_down or beautiful.fg_focus or header_color + local app = args.app or "sudo wifi-menu" + + helpers.set_map(iface, true) + helpers.set_map("carrier", 0) + + local mynet = wibox.widget.textbox() + + local mynetupdate = function() + if iface == "" then + iface = net.get_device() + header = iface + end + + local carrier = helpers.first_line('/sys/class/net/' .. iface .. + '/carrier') or "" + local state = helpers.first_line('/sys/class/net/' .. iface .. + '/operstate') + local now_t = helpers.first_line('/sys/class/net/' .. iface .. + '/statistics/tx_bytes') + local now_r = helpers.first_line('/sys/class/net/' .. iface .. + '/statistics/rx_bytes') + local text = '' .. header .. ' ' + + if carrier ~= "1" + then + if helpers.get_map(iface) + then + n_title = iface + if n_title == "" then + n_title = "network" + header = "Net" + end + naughty.notify({ title = n_title, text = "no carrier", + timeout = 7, + position = "top_left", + icon = beautiful.lain_no_net_notify or + helpers.icons_dir .. "no_net.png", + fg = beautiful.fg_focus or "#FFFFFF" }) + + mynet:set_markup(markup(header_color, header) .. markup(color_up, " Off")) + helpers.set_map(iface, false) + end + return + else + helpers.set_map(iface, true) + end + + if state == 'down' or not now_t or not now_r + then + mynet:set_markup(' ' .. text .. '-' .. ' ') + return + end + + if net.last_t[iface] and net.last_t[iface] + then + net.send = tostring((now_t - net.last_t[iface]) / delta / unit) + net.recv = tostring((now_r - net.last_r[iface]) / delta / unit) + + text = text + .. '' + .. string.format('%.1f', net.send) + .. '' + .. spr + .. '' + .. string.format('%.1f', net.recv) + .. '' + + mynet:set_markup(' ' .. text .. ' ') + else + mynet:set_markup(' ' .. text .. '-' .. ' ') + end + + net.last_t[iface] = now_t + net.last_r[iface] = now_r + end + + local mynettimer = timer({ timeout = delta }) + mynettimer:connect_signal("timeout", mynetupdate) + mynettimer:start() + mynettimer:emit_signal("timeout") + + mynet:buttons(awful.util.table.join( + awful.button({}, 0, function() + helpers.run_in_terminal(app) + mynetupdate() + end))) + + net.widget = mynet + + return setmetatable(net, { __index = net.widget }) +end + +return setmetatable(net, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/sysload.lua b/widgets/sysload.lua new file mode 100644 index 0000000..8583ccb --- /dev/null +++ b/widgets/sysload.lua @@ -0,0 +1,70 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local markup = require("lain.util.markup") +local helpers = require("lain.helpers") + +local awful = require("awful") +local beautiful = require("beautiful") +local wibox = require("wibox") + +local io = io +local string = { format = string.format, + match = string.match } + +local setmetatable = setmetatable + +-- System load +-- lain.widgets.sysload +local sysload = {} + +function worker(args) + local args = args or {} + local refresh_timeout = args.refresh_timeout or 5 + local show_all = args.show_all or false + local header = args.header or " Load " + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or header_color + local app = args.app or "top" + + local mysysload = wibox.widget.textbox() + + local mysysloadupdate = function() + local f = io.open("/proc/loadavg") + local ret = f:read("*all") + f:close() + + if show_all + then + local a, b, c = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") + mysysload:set_text(string.format("%s %s %s", a, b, c)) + else + local a = string.match(ret, "([^%s]+) ") + mysysload:set_text(string.format("%s", a)) + end + mysysload:set_markup(markup(header_color, header) .. + markup(color, mysysload._layout.text .. " ")) + end + + local mysysloadtimer = timer({ timeout = refresh_timeout }) + mysysloadtimer:connect_signal("timeout", mysysloadupdate) + mysysloadtimer:start() + mysysloadtimer:emit_signal("timeout") + + mysysload:buttons(awful.util.table.join( + awful.button({}, 0, + function() + helpers.run_in_terminal(app) + end) + )) + + return mysysload +end + +return setmetatable(sysload, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/temp.lua b/widgets/temp.lua new file mode 100644 index 0000000..301bc1c --- /dev/null +++ b/widgets/temp.lua @@ -0,0 +1,52 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + +--]] + +local markup = require("lain.util.markup") + +local beautiful = require("beautiful") +local wibox = require("wibox") + +local io = io +local tonumber = tonumber + +local setmetatable = setmetatable + +-- coretemp +-- lain.widgets.temp +local temp = {} + +function worker(args) + local args = args or {} + local refresh_timeout = args.refresh_timeout or 5 + local header = args.header or " Temp " + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or header_color + local footer = args.footer or "C " + + local mytemp = wibox.widget.textbox() + + local mytempupdate = function() + local f = io.open("/sys/class/thermal/thermal_zone0/temp") + local ret = f:read("*all") + f:close() + + ret = tonumber(ret) / 1000 + + mytemp:set_markup(markup(header_color, header) .. + markup(color, ret .. footer)) + end + + local mytemptimer = timer({ timeout = refresh_timeout }) + mytemptimer:connect_signal("timeout", mytempupdate) + mytemptimer:start() + mytemptimer:emit_signal("timeout") + + return mytemp +end + +return setmetatable(temp, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/yawn/README.rst b/widgets/yawn/README.rst new file mode 100644 index 0000000..d067db3 --- /dev/null +++ b/widgets/yawn/README.rst @@ -0,0 +1,133 @@ +========================================= +Yahoo's Awesome (WM) Weather Notification +========================================= + +---------------- +Lain integration +---------------- + +:Author: Luke Bonham +:License: WTFPLv2_ +:Version: 2.0-git + +Description +----------- + +Yawn is a module for Awesome WM providing brief and compact +weather notification via Naughty and Yahoo! Weather API. + +Originally a port of perceptive_, it became a completely new module after various improvements and style changes. + +----- +Usage +----- + +You can ``register`` Yawn to get a set of widgets, or ``attach`` it to +an existent widget. + +register +^^^^^^^^ + +Call: :: + + lain.widgets.yawn(id, args) + +Arguments: + +``id`` + An integer that defines the WOEID code of your city. + To obtain it you can google 'yahoo weather %CITYNAME%' and follow the first link. + It will look like:: + + http://weather.yahoo.com/united-states/california/san-diego-2487889/ + + and the last number in that link will be the ID you need. +``args`` + An optional table which can contain the following settings: + ``u`` + Units. Type: string. Possible values: "c" (Celsius), "f" (Fahrenheit). Default: "c". + + ``toshow`` + What to show. Type: string. Possible values: "units", "forecast", "both". + Default: "forecast". + + ``units_color`` + Color of units text. Type: string. Possible values: hexadecimal color + codes. + + ``forecast_color`` + Color of forecast text. Type: string. Possible values: hexadecimal color + codes. + + ``notification_color`` + Color of notification text. Type: string. Possible values: hexadecimal color + codes. + + ``spr`` + A separator. Type: string. You can define it when ``toshow`` is set to "both". + + ``footer`` + A footer. Type: string. You can define it when ``toshow`` is set to + "both". + +The function creates an imagebox icon and a textbox widget. Add them to you wibox like this: :: + + right_layout:add(lain.widgets.yawn.icon) + right_layout:add(lain.widgets.yawn.widget) + +Hovering over ``yawn.icon`` will display the notification. + +attach +^^^^^^ + +Call: :: + + lain.widgets.yawn.attach(widget, id, args) + +Arguments: + +``widget`` + The widget which you want to attach yawn to. +``id`` + same as in ``register`` +``args`` + same as in ``register`` + +Hovering over ``widget`` will display the notification. + +-------------- +Popup shortcut +-------------- + +You can also create a keybinding for the weather popup like this: :: + + globalkeys = awful.util.table.join( + ... + awful.key( { "Mod1" }, "w", function () lain.widgets.yawn.show(5) end ) + ... + +where ``show`` argument is an integer defining timeout seconds. + +------------ +Localization +------------ + +Default language is English, but Yawn can be localized. +Move to ``localizations`` subdirectory and fill ``localization_template``. + +Once you're done, rename it like your locale id. In my case: :: + + $ lua + Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio + > print(os.getenv("LANG"):match("(%S*$*)[.]")) + it_IT + > + +hence I named my file "it_IT" (Italian localization). + +**NOTE:** If you create a localization, feel free to send me! I will add it. + +.. _WTFPLv2: http://www.wtfpl.net +.. _perceptive: https://github.com/ioga/perceptive +.. _Tamsyn: http://www.fial.com/~scott/tamsyn-font/ +.. _Rainbow: https://github.com/copycat-killer/awesome-copycats> diff --git a/widgets/yawn/icons/BlowingSnow.png b/widgets/yawn/icons/BlowingSnow.png new file mode 100755 index 0000000000000000000000000000000000000000..6223f8f7d2c1be89dbb216537dbfe0e97e4edd28 GIT binary patch literal 11454 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 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/Cloudy.png b/widgets/yawn/icons/Cloudy.png new file mode 100755 index 0000000000000000000000000000000000000000..bac1e7ebb84426f6bf1704f4c8a3c70486713cd1 GIT binary patch literal 7469 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 GBL4%n%mMoV literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/DayClear.png b/widgets/yawn/icons/DayClear.png new file mode 100755 index 0000000000000000000000000000000000000000..d9e2745cee4f88db9a855ed58d9bc3f2c34ddb12 GIT binary patch literal 6147 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 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/DayMostlyCloudy.png b/widgets/yawn/icons/DayMostlyCloudy.png new file mode 100755 index 0000000000000000000000000000000000000000..22b929c612e7d04a2408bc71625114908f255769 GIT binary patch literal 8016 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 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/DayPartlyCloudy.png b/widgets/yawn/icons/DayPartlyCloudy.png new file mode 100755 index 0000000000000000000000000000000000000000..8fd0a5b04d686db4e7dea16981db46d5d1f94de2 GIT binary patch literal 7478 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 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/Foggy.png b/widgets/yawn/icons/Foggy.png new file mode 100755 index 0000000000000000000000000000000000000000..009039f8dd2433627a9499003f6c86bfad4b0c80 GIT binary patch literal 7325 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
  • S236D+`KjrhMq5Ij+iT7#d>q&))}ssJ4g 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 SkrO>h^&xJMv@VQGJePR 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%0A%@Z-MgdAQ8>#OcqF{V6qfz^dJoC^ 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 Q|Gz*qRdrO}DA`2)AC2#6RsaA1 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/LightSnowShowers.png b/widgets/yawn/icons/LightSnowShowers.png new file mode 100755 index 0000000000000000000000000000000000000000..d797ee948695d7ce46053fe7b54433b610b3097c GIT binary patch literal 8779 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 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/MixedRainAndHail.png b/widgets/yawn/icons/MixedRainAndHail.png new file mode 100755 index 0000000000000000000000000000000000000000..758b01e48eaa6ad27d8b0d692e285a92e90a4ee1 GIT binary patch literal 9060 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 F{s-1-Kk5Jg literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/MixedRainAndSleet.png b/widgets/yawn/icons/MixedRainAndSleet.png new file mode 100755 index 0000000000000000000000000000000000000000..7f0d252565ba1e256fc4fb281eab2ba2fbd1be12 GIT binary patch literal 10978 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 IvXbTf?`dGNzKt4V`T=vcm9#$5vHe4?5 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 b@c`k>S|VAx$A*JPDIsNfb-5}T^U(hTcXN<$ literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/NightClear.png b/widgets/yawn/icons/NightClear.png new file mode 100755 index 0000000000000000000000000000000000000000..84ea1408ba782bc48e03bbbd79f862412d3cb48d GIT binary patch literal 5198 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 C7rvhW literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/NightMostlyCloudy.png b/widgets/yawn/icons/NightMostlyCloudy.png new file mode 100755 index 0000000000000000000000000000000000000000..d8b3673492f457ab354bf4276b2a2e49cc4c6dee GIT binary patch literal 7058 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 Yv4~UN31ejeKT-jzikb?Qa+V?g10eTDiU0rr literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/NightPartlyCloudy.png b/widgets/yawn/icons/NightPartlyCloudy.png new file mode 100755 index 0000000000000000000000000000000000000000..9e4404d7511aa84a563fbc2e4933ee032a1ce88e GIT binary patch literal 6583 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 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/README.md b/widgets/yawn/icons/README.md new file mode 100644 index 0000000..e4dc111 --- /dev/null +++ b/widgets/yawn/icons/README.md @@ -0,0 +1,6 @@ +Yawn icons +========== + +These are [Plain Weather Icons](http://merlinthered.deviantart.com/art/plain-weather-icons-157162192), created by [MerlinTheRed](http://merlinthered.deviantart.com/). + + diff --git a/widgets/yawn/icons/Rain.png b/widgets/yawn/icons/Rain.png new file mode 100755 index 0000000000000000000000000000000000000000..d00552a5fd8d96d08d0e5915d51a7963d40cc7ae GIT binary patch literal 8052 zcmX|m1yodB)b?c29REQyS?8rKOPu=@t-yp*vIr>F)Zj|NpJ; ztaawBnK^ggd-pl}+0TAXw3>=MHYOP+007vE3Njkt82qoJqk^CP;-;hE0Ckg6e1i@) ze{_o|@H>XHg034lfBs)bl6sNj4gN^#F013N>15^ZW$J1PczJno*gD#|nVULWayYqK z=NyWXfs+XTO_KC*w{da>lr3HDZ5`j(SZY{W46f1ofq%dL|28~a%`E{NcXwxDPELpa zH_P3|($&&}!@|G_7y(~@tO<}h+cXD)Nhw%x(__<+1 z+(QJ!W1v~{e`ckfoPAtvt!>-^X=xfscXwA?GY@xLCr5S_Cr4=~2k<`Twx;&%nl|9$ zOWNDoSg8MyQ4X~n<*y`2N&lWl5#FM8M2B0{$>{} zh))zHh$KbSG5j%QLT1ZrUub#nVOZ!jAaQyJaJ(gu`2Yx`sAB2B}G9-f-2Cm|gl8AsLyfDs7BILIpW+u^rl3b~7e!B37P6gt0rOXl2iGqRx$tW4W zdsfrs=bOE6(Jtw>teUFED`#V+#v7_Upo=T!upX3qYoJWC`4ZmHbzBAGz3rx?C!QZ zTI+05m3VM>aC38GcE@Ut74|KsFUJyMUIO6a!Zd1x*<>)HZu4j&yRg4$7#rt-eDVqC zO9MnaK0!bG!ZX&L`?0lgD23f+V-Jczw+x>UzuS++ zz`z)&Owc10a^36@^Si9_6#f*Akd{Nwrf)m`_;xO`jwZYd)zBM;BW$+l^w&X!hJULx zT$OAR0?f(Al3=rNat4i?)jf-9K2{tV9c_1<|67E?AmR)SM<?>lgj~44ddy>vUT$ljj&NxvXz6p{q?Yb zQ00eYig+CoYa0h#6drCE?wg!$j(C01YuX*2R+R_dojc3EX5;jJEFSvC+qJya1mWp1Ny ziyRzQt>5y6g5Q3j<}QEDw5YoJU?r7BGo4Drvx>BB3{amf?nQ<^7xQ&L-JPv;`Y|@v z`TdV;Yn)sWWoz-w%8LKyKs2FWWo6~l<$`$vCE&x594}$gTNVgIGl1Bj=e^B9imWMJ z;B4Qo-vqbyu2{q3{(ezgWZc8ul~e0ZNsdvZi4&s~9sti2a@)!$X4U#ZD(Zbq^uE^w z=g*S$M6THNxX4jQhvRA+Sr2`(#dUcsl#NanGaOe5*Xgggm;J9+_tgb%k5lRy#rk|aenHc~^q_K6& z@*cP>HRu@{Na4=rN%$NgTJV_PzYO@HMX z7#TlPi}{|nx3#s+#l*zeX;FDD+mq6LC{{dAuH#f-XY`XPo7kTFBLPA3E<(j2N;^yBzWEH-M zs5-oW<3VAZoKE-olJDa|hhH$95({4f`Kd_!shhS@K%;_*g0eD7{Mfw4jeRN`;_mgU zSM^puGF>|L-VYE=O-*sTy1Ajr|EviM4GldxI5@bwJXoHGUUwi1nUPMj;d7bQ%4p1@ z7JlESBBwAt5F^2Cf&_aY@+He3h)?4#%($N0kEXNxEtu8S(pnfLVvMGiXznbuq6mkp z@C;OyxYiCo=chG80rrBCkSRtpIH^TU`@$46j01h@CT*VCF1VK$R8;I{eSV!02t6fz zCARo#VV~}fa_tQ-FdUg!MfnrO#~UZl@?v+^oLM#3-%v$mTrg!M3`OA=eB;DhCE+>D z3!06&hXG8Wo@XPUDmmDv9q$W`hXFQo0guw_9;0znK`DArI7vH z2`6PFbzxz_JHMo4OY~ToBS)w@U2Lo(2r?%C1n0XAt0{MDw#Raa%Ufi!jiz~{ zy9>_1lUOtW_|=C?jT1?~`mTw|!ootZR4FT2-2E?NrmCuH^xxVkF{O;`T{L@ncr+zV zt*xyYfB|xMI?6epD-qO185#zYLIm}k5~JVG_z|3U&@l8w_=cQ3ROvRL))=;5dVm3Y z(9YC)?tHk?>YFjjr-la|#EV1gUSFR?Ae^0t;wf{e0?sE_@!V+^&%O9}(#HH!(UBI6 zRG0nRdrcG;n(XGWz)Xm*`ZJzhw6U>~Vy)R>+3wGuKgMupUP){56kYjjXb3(er!`de zw#upFGgT&sq~Kc4NS>FMcu5@76*$xhA&q9`EwiyH&#E#KZ$r5e|7G~`VPlyE7G`Z+ zCS>ry)B5~sU$-O72?I$T)~c12ZBsu<@%Vgk58AiVp&va&KI&R|Co0FCT-k=4|k zj$c~RORk7#$~Al458?0oebRU#kn{WVylkd`)0zQ7r`QbYU-beh_>H!<*XcKMr+wtW zZ}`~Y>lb7X=^`0DIj>vi8y!& zMN~O}i$k}5vs>bN<9z`#8qUWV+$%i!=Qg&sCjb=&G@lm$a-FCUIJ2{}enB^*#_<9< zV=U@bK@_GvM^|2=cl!;TA3@?kH++T+IRS(V)T*P##>TpMtjG8BxJ>(a)rr_AyFUp^ z4em^rN<8&bKOT3}s1hVGMj)WTIBesdQr!Q#kOqC7h=e4bn=CH=#fmhAX?{h;yZ*z~ z_8^ETOr``0y;hd4egc<55OMqmgdcto14loqSo5Z94o+fy1UJ_9_cYdZ=uI|qDggD3 z^qIOj+ivG~SUSJ@`0?W{*wqVPeA7l6#LLdfu{-LzJAC^er;$DKpOVaad-EkILg@E? zk}_j50AFf#+nyw3R@ny=w9dag1$|(MDM~;rE&1*z$y2pH-5qs1g__WzXFr4BJ%b<( zhcnaGjHqkHQ;GSWbY8732ky?4PfSlww^QKAYl*rE-X8mQvh(rr)v)O|@1M}i$Mc5x zchWN5!?kMXc1zZEPaUu7}HI_N!H|b$vK?+A~z-XW$xqOiQy=RaR~)EiPV2NlxAe zL9W-aWw~0*E_BSQA!p30ebB5fXKV`!BB(%?l4r_@1tGMT!Ce{(sN+HFwhi*fk&mtt zm5HE|$2b0zMm6)(v$GyaspI40>04V{w?*;^f!*dq@kf`3t9~S#%afB6@`x2;N_qh3 zdh=|VCCsqj%A%|Pur^vusqcD5Q+14t$Lfa@9qqu{uOaH7`*q9F^oP2lB59Zw>U}vK z)SX88KtcL-k%{K{evFBy&+`YaXL^6DcC`rrxEs9<6^0JovFC_|K$e*o8P6Bv?m!h6 zmlKCcBg>V^Nf*zn!_}t-tFi2t8$U8bMEze$vqnIMg)YgEx4cXz6wO)+E%P#po9zv{ zRP)E>dyf@*F!Kz*uxZHK?~(onsT$g<%MfL3eM3X(u6?ml(dW;9hPwjp9u0JLZ(4_b z+oDa8o-8e9;g6ZAlVnJMcFfRU>hTuT{`p&y#bdn% zLhEX7db$?D2nvgMUQJV7U0q3A+bt(&$8nzopq+s!4}t`n4TiQ;f;K&h*Cxs<4;8`? zV&NQYC1dh+7T&Oc_l;o*i`-NgMB=i6fq_$C{Cp!JB2rR#{hHi?mrQ!e^GicR18BDH za;98!{cydzd+Q(U7Bn=ZG{sfzZk8+EihFyCz3H_JFdlnm(jH-wXUh5>$oI>@6Vo58 z?_+)hmi>@(UTSM;sZ@ZiyrQDetFP}3%YlBah}p1zY*-ld>_-+)q?MIbNxQ)p_tNRC z^u)x(-LsoE5T|p*s3uSnhTOmk5NkUpJA3>e8QTXlM-b}g>~n7UO9M>@?hEUJt^2wo zyBjP$J$M{ZU7 zFav=1py&PW4qC3>bBBaSY2!*Suw3&wP4A56q1qjBshz z888{)=m}wIwxRd;{>x(m>-X}Kc*$tbo^ufZUHOht^JV)N-b@i=HnZ>8ngvWm9LtD} z=p!+kjK-T;IA2!IoguknQo&nC8q-mG!p134stnsbt4A!zm=p;Zn3&@CZ$4B%pJ*T{ z&{q&W=o2pL$o*!=m8-Uh`quC@S^;5*JkV^oGr_Q{@Kj0$lO_-ip(5-#L$SEL1wkom z(_J`-U2*lvyiP|hw0?-dL_8#~Rh&ei#}^Ch$7MN2(xdp1TP_KL4zh>dAZ>Ol=KAF` zY~e|pxNENY)HeXoqKWyrJe)+YP4E*Lh$_rnI%}og6!_7g3!JWvhRhSby&(q_`f+|Xn;Pwsu%Qy;C`ASUDE;hDZ% zUVpqiXl&%=(clbU@x`jfItimLYh1MFCm|+YjjUEe@{yjJN8a#jW+RP?97nZZK$AIR zlHlqsino`Q9Sl1?J$(ZFsl_=~99srR;yf80`g4q7VAXYq->_)lJ0W)U4DB<0)fR6A z6vU4im;7HK>6zDMBWb~bl$CS*xcL<>w0I)I86%JTG$Tie3UIA@E;}rO#dRQ~fPfc8 zu-SR9uw6EGd}46((~7eokol68)yY$k;x&U}Xb3V|JnD@M`4-^?neST+rvgU{Wv#nS=J!I5kSHbjeVN*#V=M_xqVN z^qjzigMfOPX+l-elgtr|HjQM4S{=4QycLlo#vYI4nO)(CN(%9!rlhpUc`4h~5? z3tdrAx7zufVRXy0Aq|_OF!3ZWoA~RCINE7d*K)4MyUc`{r<-9PUfsb$%*9k7Y5_|E zcYahD10bVsXH?WMh%A3SP+$pJ$mKliYq4L{SVtg^lNl5PUs-y9Ovif+SK=N4`F=3r zb4iNz!9*R-PcV#J^2M_G9%Lo$FKKB_*@l9m&%JZx9e*k5gPydAn@pt&vsbxz2e=kv z&;S6NVVnEI!`1qeuBqwIv1EoD9BOfcroe~WfZ&M+^XXpu-}Pb<_X189@OgYf(cLg& zV&bv6$*=Fka_00F!o9DG{*JY*xW2|X7o29h4-6tN6PW_MOQ%ryAc(l#(s=PLzenp_ zpDh5OC=MKo-Kr~sK&q1dUcsotzLcilsNvDWU@jC1fT5w`z6=3so8vo~UYg1vP@v;7 zGUPDo&_Uaso-vg)g(RYrkfavSyL1HX&dx}Xr~UT*rtq`eI{!=bC$vLrP%O+Ke};NK z=?Uhr3$REN#QxeXHJ=5Xjn67YN)^Qv+H90Roo!D9A-{r@VS7o38WFj zT95{zgz&436A1J(dzI|=1kGr)ZO!Y zox!v6$;IOi%gqibffd5=Oa{ar)Xc?~jjD!^w1~-{joYf@a>*`5t4b#c&D%!HAu8g6 zNCLQKCyDLZb5T}S4nkhBn1sF&O#A4IRBBZ3dHXct_nE+huI<*@&w9*ku$bWuM%~+8w-cBzKU6o2a>;%v6 ziH-7qT|aVK2IUNq9|4mCj87qBn>*1I$+yG)#RtnRc|u_AxC(lGNYPM~YN8Z`v6bKX zyr18lQPLvwAvw0_n|*8M#aLMTMxUfN_}6Ga8Ma<)+HXh_`-drSVjdN6LR!mgj4qt5 zDcqKx`1={ukN?pV)ve7T4R=9A9$RPe*l{$fJ|lTs#^elo+(=19s@Syk0N zW@>hvfN#MAk!NF{+d{1`D5j9TYshQV#kuz?V}hpvKm}>vf)Mr(+rBWV5-H^7pudQM zXb{8ou~DV8PNe<@%wcY5u5v(#?sGsQ%C(UX_fSNpO#52fO!MA zF*3k8Sr{a6m4FE@RFO$4(Z8`qvWMIhkymGt`0%Br4-Gv9poNf&kI)5Sk+5a5#}pFM z2fv6pce)7nMBQ2YlJ;s4YvaYtlcCot-;z~>a{itjFWEHhSE|rl!D#}H8gV@)J~o*Y z0QkPfs=3XPVMoU)v)qt@6YPs@Vs2h&rOWxz(Yq>s-%j?pw5-fV$gE<)f?y7#xPbWk zw?p<|XJ2v2MvR`pL|W-8l2}WI1mNQ00z1E-#I@&=yK4T#j0*VvGuw0|nbF*VfBAVB z&|yj$Fs8N}Pe;&)_BRLug$ns!AHM;(T=s*e=c@HprLG%Ht2zgHQGhQ<7O-%9dO5b~ zBxM<6>1vKPJeGp#D1IcapEpQ7P7RA{AeU-vYNCWbI-|Gq15ol0zdxAuYc3fej#7#M zKuT9vw`=y@pU?f3gUo7vYyXAL#y(B~jmM0@@zHws({-_8ik^)6n|-Ok&EX_3BvrPb zmZT$OZ?})r<^WN2fCdz$UJxiE|F;v^txDOVK$i_Q`2<^fP161Jc(+wjQX*i;G4FaS z4~l|M-j6riUV!-E3afsFBsw3R0zlIWF4|je??A}sbmUDBCAc;Nmz2q@xDYCx2^dJk z^6?b9bBl{UwM9k0m%$T>jt0~Ih;`tx5zD@-OBb zyz~|=Di=IlAXbJTl|eOuM9^bb_`p5!rX-=nv0spJx!#QS&P@=nzIJkPI(RIUiWkiH z7B+u}R9J}wTw{Na9rM!I?kGlgtp@t`-##z5$WjB91Y?uV?z%b`^MHT{Srtn2DWY>0 zr00?*aqvnvU%IfC#X3E`Hw|I|TEaQco@mJ>W zQELUzhl^h!@y?OH*k>&*^LYrE%&aQ!OBT>E4(HbwHI~)tek2ixr+$RvU;wH7B=nGF zzgxXeW_?2xTK0K#e8%BjRzGOo6#>KqwQ)Z#T|Hl*;C)&fAg`+}BB>6D`D-^oal3+M zQc#zwhg}v-&*B}YOzHiIsV|@Y6^QC5!`h|Jr`FFO97R4G1l4`aNID%udf`Tw1`{(^oT bIC(mO&E@D(xc>(pLj#JkDl%WBOhW$$bRr|s literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/RainThunder.png b/widgets/yawn/icons/RainThunder.png new file mode 100755 index 0000000000000000000000000000000000000000..d30e120582fe1084bbfc6f33f67dfa4ef4e66539 GIT binary patch literal 9879 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 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/Showers.png b/widgets/yawn/icons/Showers.png new file mode 100755 index 0000000000000000000000000000000000000000..3cc6665dc0e98c2be584079add634d9744b459a5 GIT binary patch literal 9694 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 O6i`>zR;p4k5B(n_WNM25 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/SnowShowers.png b/widgets/yawn/icons/SnowShowers.png new file mode 100755 index 0000000000000000000000000000000000000000..30534a20d052bbc9c6353dd9eb950f3ea5956954 GIT binary patch literal 9961 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 literal 0 HcmV?d00001 diff --git a/widgets/yawn/icons/na.png b/widgets/yawn/icons/na.png new file mode 100755 index 0000000000000000000000000000000000000000..62a5350d878dccc626e9e7be17e728aab0737b87 GIT binary patch literal 11160 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 uAxI$vvXU%&SeT6Z$sT;G_Uh)zHFuz)Q)>Is(", "") + weather_data = weather_data:match("Current Conditions:.-Full") + weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ") + weather_data = weather_data:gsub("Forecast:.-\n", "") + weather_data = weather_data:gsub("\nFull", "") + weather_data = weather_data:gsub("[\n]$", "") + weather_data = weather_data:gsub(" [-] " , ": ") + weather_data = weather_data:gsub("[.]", ",") + weather_data = weather_data:gsub("High: ", "") + weather_data = weather_data:gsub(" Low: ", " - ") + + -- Getting info for text widget + local now = weather_data:sub(weather_data:find("Now:")+5, + weather_data:find("\n")-1) + local forecast = now:sub(1, now:find(",")-1) + local units = now:sub(now:find(",")+2, -2) + + -- Day/Night icon change + local hour = tonumber(os.date("%H")) + sky = icon_path + + if forecast == "Clear" or + forecast == "Fair" or + forecast == "Partly Cloudy" or + forecast == "Mostly Cloudy" + then + if hour >= 6 and hour <= 18 + then + sky = sky .. "Day" + else + sky = sky .. "Night" + end + end + + sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png" + + -- In case there's no defined icon for current forecast + f = io.popen(sky) + if f == nil then + sky = icon_path .. "na.png" + else + io.close(f) + end + + -- Localization + local f = io.open(localizations_path .. language, "r") + if language:find("en_") == nil and f ~= nil + then + io.close(f) + for line in io.lines(localizations_path .. language) + do + word = string.sub(line, 1, line:find("|")-1) + translation = string.sub(line, line:find("|")+1) + weather_data = string.gsub(weather_data, word, translation) + end + end + + -- Finally setting infos + forecast = weather_data:match(": %S+"):gsub(": ", ""):gsub(",", "") + yawn.forecast = markup(yawn.forecast_color, markup.font(beautiful.font, forecast)) + yawn.units = markup(yawn.units_color, markup.font(beautiful.font, units)) + yawn.icon:set_image(sky) + + if toshow == "forecast" then + return yawn.forecast + elseif toshow == "units" then + return yawn.units + else -- "both" + return yawn.forecast .. spr + .. yawn.units .. footer + end +end + +function yawn.hide() + if notification ~= nil then + naughty.destroy(notification) + notification = nil + end +end + +function yawn.show(t_out) + if yawn.widget._layout.text == "?" + then + if update_timer ~= nil + then + update_timer:emit_signal("timeout") + else + fetch_weather(settings) + end + end + + yawn.hide() + + notification = naughty.notify({ + text = weather_data, + icon = sky, + timeout = t_out, + fg = yawn.notification_color + }) +end + +function yawn.register(id, args) + local args = args or {} + + settings = { args.toshow, args.spr, args.footer } + + yawn.units_color = args.units_color or + beautiful.fg_normal or "#FFFFFF" + yawn.forecast_color = args.forecast_color or + yawn.units_color + yawn.notification_color = args.notification_color or + beautiful.fg_focus or "#FFFFFF" + + if args.u == "f" then units_set = '?u=f&w=' end + + city_id = id + + update_timer = timer({ timeout = 600 }) -- 10 mins + update_timer:connect_signal("timeout", function() + yawn.widget:set_markup(fetch_weather(settings)) + end) + update_timer:start() + update_timer:emit_signal("timeout") + + yawn.icon:connect_signal("mouse::enter", function() + yawn.show(0) + end) + yawn.icon:connect_signal("mouse::leave", function() + yawn.hide() + end) +end + +function yawn.attach(widget, id, args) + yawn.register(id, args) + + widget:connect_signal("mouse::enter", function() + yawn.show(0) + end) + + widget:connect_signal("mouse::leave", function() + yawn.hide() + end) +end + +-- }}} + +return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end }) diff --git a/widgets/yawn/localizations/it_IT b/widgets/yawn/localizations/it_IT new file mode 100644 index 0000000..0b74b60 --- /dev/null +++ b/widgets/yawn/localizations/it_IT @@ -0,0 +1,57 @@ +Now:|Ora: +Sun:|Dom: +Mon:|Lun: +Tue:|Mar: +Wed:|Mer: +Thu:|Gio: +Fri:|Ven: +Sat:|Sab: +Mostly Sunny|Abbastanza Soleggiato +Sunny|Soleggiato +Sun|Soleggiato +Rain/Thunder|Temporali +Isolated Thunderstorms|Temporali Isolati +Scattered Thunderstorms|Temporali Sparsi +Thundershowers|Rovesci Temporaleschi +Thunderstorms|Temporali +Thunder|Temporale +AM|In Mattinata +PM|Nel Pomeriggio +Early|In Mattinata +Late|In Serata +Few|Sporadiche +Severe|Forti +Clear|Sereno +Fair|Sereno +Partly|Parzialmente +Mostly|Molto +Cloudy|Nuvoloso +Clouds|Nuvoloso +Scattered Showers|Temporali Sparsi +Light Snow Showers|Nevicate Leggere +Snow Showers|Nevicate +aeavy Snow|Forti Nevicate +Scattered Snow Showers|Nevicate Sparse +Mixed Rain And Snow|Pioggia E Neve +Mixed Rain And Sleet|Pioggia E Nevischio +Mixed Snow And Sleet|Neve E Nevischio +Mixed Rain And Hail|Pioggia E Grandine +Snow Flurries|Folate Di Neve +Blowing Snow|Neve Battente +Blowing Rain|Pioggia Battente +Heavy Rain|Forti Piogge +Freezing Rain|Pioggia Congelantesi +Showers|Piogge +Light Rain|Pioggia Leggera +Heavy|Forti +Rain|Piovoso +Windy|Ventoso +Wind|Ventoso +Snow|Neve +Sleet|Nevischio +Drizzle|Pioggerella +Freezing Drizzle|Pioggerella Congelantesi +Hail|Grandine +Foggy|Nebbia +Haze|Nebbia +Light|Leggere diff --git a/widgets/yawn/localizations/localization_template b/widgets/yawn/localizations/localization_template new file mode 100644 index 0000000..98d527d --- /dev/null +++ b/widgets/yawn/localizations/localization_template @@ -0,0 +1,57 @@ +Now:| +Sun:| +Mon:| +Tue:| +Wed:| +Thu:| +Fri:| +Sat:| +Mostly Sunny| +Sunny| +Sun| +Rain/Thunder| +Isolated Thunderstorms| +Scattered Thunderstorms| +Thundershowers| +Thunderstorms| +Thunder| +AM| +PM| +Early| +Late| +Few| +Severe| +Clear| +Fair| +Partly| +Mostly| +Cloudy| +Clouds| +Scattered Showers| +Light Snow Showers| +Snow Showers| +Heavy Snow| +Scattered Snow Showers| +Mixed Rain And Snow| +Mixed Rain And Sleet| +Mixed Snow And Sleet| +Mixed Rain And Hail| +Snow Flurries| +Blowing Snow| +Blowing Rain| +Heavy Rain| +Freezing Rain| +Showers| +Light Rain| +Heavy| +Rain| +Windy| +Wind| +Snow| +Sleet| +Drizzle| +Freezing Drizzle| +Hail| +Foggy| +Haze| +Light| From 635f0576554301d505233fd4116d8429f310d87a Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 7 Sep 2013 16:46:56 +0200 Subject: [PATCH 002/546] version 1.0 --- README.md | 419 -------------------------------------------- README.rst | 25 +++ util/markup.lua | 33 ---- widgets/mpd.lua | 13 +- widgets/net.lua | 12 +- widgets/sysload.lua | 2 +- 6 files changed, 38 insertions(+), 466 deletions(-) delete mode 100644 README.md create mode 100644 README.rst diff --git a/README.md b/README.md deleted file mode 100644 index 8aa9449..0000000 --- a/README.md +++ /dev/null @@ -1,419 +0,0 @@ -VAin agaIN -========== - -Author: Luke Bonham - -Source: https://github.com/copycat-killer/vain - -Version: 1.9.9 - -Release version: 2.0 - -**Please note**: until release version, this documentation will be not updated. - -Foreword --------- - -Based on a port of [awesome-vain](https://github.com/vain/awesome-vain), this -costantly evolving module provides new layouts, a set of widgets and -utility functions in order to improve Awesome usability and configurability. - -This work is licensed under [GNU GPLv2 License](http://www.gnu.org/licenses/gpl-2.0.html). -Installation -============ - -Simply clone this repository into your Awesome directory. - -Widgets -======= - -systemload ----------- - -Show the current system load in a textbox. Read it directly from -`/proc/loadavg`. - - mysysload = vain.widgets.systemload() - -A click on the widget will call `htop` in your `terminal`. - -The function takes a table as an optional argument. That table may -contain: - -* `.refresh_timeout`: Default to 10 seconds. -* `.show_all`: Show all three values (`true`) or only the first one (`false`). Default to `false`. -* `.color`: Default to beautiful.bg_normal or "#FFFFFF". - -cpu --------- - -Shows the average CPU usage percent for a given amount of time. - - mycpuusage = vain.widgets.cpu() - -A click on the widget will call `htop` in your `terminal`. - -The function takes a table as optional argument, which can contain: - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`refresh_timeout` | Refresh timeout seconds | int | 10 -`header` | Text to show before value | string | " Vol " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to show after value | string | "%" - -**Note**: `footer` color is `color`. - -memusage --------- - -Show used memory and total memory in MiB. - - mymem = vain.widgets.mem() - - -The function takes a table as an optional argument. That table may -contain: - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`refresh_timeout` | Refresh timeout seconds | int | 10 -`show_swap` | Show amount of used swap space? | boolean | false -`show_total` | Show amout of total memory? | boolean | false -`header` | Text to show before value | string | " Vol " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to show after value | string | "MB" - -**Note**: `footer` color is `color`. - -mailcheck ---------- -Checks maildirs and shows the result in a textbox. -Maildirs are structured as follows: - - ~/Mail - . - |-- arch - | |-- cur - | |-- new - | `-- tmp - |-- gmail - | |-- cur - | |-- new - | `-- tmp - . - . - . - -therefore `mailcheck` checks whether there are files in the `new` -directories. To do so, it calls `find`. If there's new mail, the textbox -will say something like "mail: bugs(3), system(1)", otherwise it says -"no mail". - - mymailcheck = vain.widgets.mailcheck("/path/to/my/maildir") - -The function takes a table as an optional argument. That table may -contain: - -* `.mailprogram`: Your favourite mail program. Clicking on the widget will - spawn it. Default is `mutt`. -* `.refresh_timeout`: Default to 60 seconds. -* `.mailpath`: Path to your maildir, default is `~/Mail`. -* `.ignore_boxes`: Another table which lists boxes (just the last part, - like `lists`) to ignore. Default to an empty table. -* `.initial_update`: Check for mail when starting Awesome (`true`) or - wait for the first refresh timeout (`false`)? Default to `false`. -* `.header_text`: Text to show along with output, default is "Mail". -* `.header_text_color`: Default to "#9E9E9E". -* `.color_newmail`: Default to "#D4D4D4". -* `.color_nomail`: Default to "#9E9E9E". -* `.shadow`: Hides widget when there are no mails. Default is `false`. - -imapcheck ---------- - -Check new mails over imap protocol. - -Dependencies: - -* Python3 - -Since [luasec](https://github.com/brunoos/luasec/) is still not officially -supported in lua 5.2, writing a pure lua solution would have meant too many -hacks and dependencies, resulting in a very big and not efficient-proven submodule. - -That's why I chose Python. - -Python offers [imaplib](http://docs.python.org/2/library/imaplib.html), a simple yet powerful IMAP4 client library which provides encrypted communication over SSL sockets. - -Basically, `imapcheck` calls ``vain/scripts/checkmail`` and parse its output in a widget. New mails are also notified through Naughty, with a popup like this: - - +---------------------------------------------------+ - | +---+ | - | |\ /| donald@disney.org has 3 new messages | - | +---+ | - | Latest From: Mickey Mouse | - | Subject: Re: Vacation Day | - | | - | Not after what you did yesterday. | - | Daisy told me everything [...] | - | | - +---------------------------------------------------+ - -Text will be cut if the mail is too long. - - myimapcheck = vain.widgets.mailcheck(args) - -The function takes a table as argument. Required table parameters are: - -* `.server`: You email server. Example: `imap.gmail.com`. -* `.mail`: Your email. -* `.password`: Your email password. - -while the optional are: - -* `.port`: Imap port. Default is `993`. -* `.refresh_timeout`: Default to 60 seconds. -* `.notify_timeout`: Notification timeout. Default to 8 seconds. -* `.notify_position`: Notification position. Default is "top_left". Check - [Naughty position parameter](http://awesome.naquadah.org/doc/api/modules/naughty.html) for a list of other possible values. -* `.mailprogram`: Your favourite mail program. Clicking on the widget will - spawn it. Default is `mutt`. -* `.mail_encoding`: If you wish to set an encoding. Default is `nil`. -* `.initial_update`: Check for mail when starting Awesome (`true`) or - wait for the first refresh timeout (`false`)? Default to `false`. -* `.header_text`: Text to show along with output, default is "Mail". -* `.header_text_color`: Default to "#9E9E9E". -* `.color_newmail`: Default to "#D4D4D4". -* `.color_nomail`: Default to "#9E9E9E". -* `.shadow`: Hides widget when there are no mails. Default is `false`. -* `.maxlen`: Maximum mail length. If mail is longer, it will be cut. Default is - `100`. -* `.is_plain`: Define whether `.password` field is a plain password (`true`) or a function that retrieves it (`false`). Default to `false`. - -Let's focus better on `.is_plain` parameter. - -You can just easily set your password like this: - - args.is_plain = false - args.password = "mypassword" - -and you'll have the same security provided by `~/.netrc`. (In this case, it's -better to set your `rc.lua` permissions to 700 or 600) - -**Or**, you can use a keyring, like gnome's: - - args.password = "gnome-keyring-query get password" - -(`gnome-keyring-query` is not in gnome-keyring pkg, you have to download it -separately) - -or the very light [python keyring](https://pypi.python.org/pypi/keyring). - -When `.is_plain` is `false`, it *executes* `.password` before using it, so you can also use whatever password fetching solution you want. - -You can also define your icon for the naughty notification. Just set `vain_mail_notify` into your ``theme.lua``. - - - -mpd ---- - -Provides a `table` with 2 elements: - -* `table["widget"]` is a textbox displaying current song in play. - -* `table["force"]` is a function to *force* the widget to update, exactly - like `vicious.force()`. - -Also, a notification is shown when a new song is playing. - -Dependencies: - -* libnotify -* imagemagick - - - mpdwidget = vain.widgets.mpd() - ... - right_layout:add(mpdwidget["widget"]) - -The function takes a table as an optional argument. That table may -contain: - -* `.password`: Mpd password. Default is unset. -* `.host`: Mpd host. Default is "127.0.0.1" (localhost). -* `.port`: Mpd port. Default is "6600". -* `.music_dir`: Your music directory. Default is "~/Music". If you have to - change this, be sure to write the absolute path. -* `.refresh_timeout`: Widget refresh timeout. Default is `1`. -* `.notify_timeout`: Notification timeout. Default is `5`. -* `.color_artist`: Artist name color. Default is `#9E9E9E`. -* `.color_song`: Song name color. Default is `#EBEBFF`. -* `.musicplr`: Your favourite music player. Clicking on the widget will spawn - it. Default is `ncmpcpp`. -* `.shadow`: Hides widget when no song is playing. Default is `false`. - -You can use `table["force"]` to make your mpd keybindings immediate. -Example usage: - - globalkeys = awful.util.table.join( - ... - -- Music control - awful.key({ altkey, "Control" }, "Up", function () - awful.util.spawn_with_shell( "mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle", false ) - mpdwidget["force"]() - end), - awful.key({ altkey, "Control" }, "Down", function () - awful.util.spawn_with_shell( "mpc stop || ncmpcpp stop || ncmpc stop || pms stop", false ) - mpdwidget["force"]() - end ), - awful.key({ altkey, "Control" }, "Left", function () - awful.util.spawn_with_shell( "mpc prev || ncmpcpp prev || ncmpc prev || pms prev", false ) - mpdwidget["force"]() - end ), - awful.key({ altkey, "Control" }, "Right", function () - awful.util.spawn_with_shell( "mpc next || ncmpcpp next || ncmpc next || pms next", false ) - mpdwidget["force"]() - end ), - -net ---- - -Monitors network interfaces and shows current traffic in a textbox. If -the interface is not present or if there's not enough data yet, you'll -see `wlan0: -` or similar. Otherwise, the current traffic is shown in -kilobytes per second as `eth0: ↑(00,010.2), ↓(01,037.8)` or similar. - - neteth0 = vain.widgets.net() - -The function takes a table as an optional argument. That table may -contain: - -* `.iface`: Default to `eth0`. -* `.refresh_timeout`: Default to 2 seconds. -* `.color`: Default to beautiful.bg_normal or "#FFFFFF". - -gitodo ------- - -This is an integration of [gitodo](https://github.com/vain/gitodo) into -Awesome. - - todolist = vain.widgets.gitodo() - -The function takes a table as an optional argument. That table may -contain: - -* `.refresh_timeout`: Default to 120 seconds. -* `.initial_update`: Check for todo items when starting Awesome (`true`) - or wait for the first refresh timeout (`false`)? Default to `true`. - -`beautiful.gitodo_normal` is used as the color for non-outdated items, -`beautiful.gitodo_warning` for those items close to their deadline and -`beautiful.gitodo_outdated` is the color of outdated items. - - - -Utility functions -================= - -I'll only explain the more complex functions. See the source code for -the others. - -menu\_clients\_current\_tags ----------------------------- - -Similar to `awful.menu.clients()`, but this menu only shows the clients -of currently visible tags. Use it like this: - - globalkeys = awful.util.table.join( - ... - awful.key({ "Mod1" }, "Tab", function() - awful.menu.menu_keys.down = { "Down", "Alt_L", "Tab", "j" } - awful.menu.menu_keys.up = { "Up", "k" } - vain.util.menu_clients_current_tags({ width = 350 }, { keygrabber = true }) - end), - ... - ) - -magnify\_client ---------------- - -Set a client to floating and resize it in the same way the "magnifier" -layout does it. Place it on the "current" screen (derived from the mouse -position). This allows you to magnify any client you wish, regardless of -the currently used layout. Use it with a client keybinding like this: - - clientkeys = awful.util.table.join( - ... - awful.key({ modkey, "Control" }, "m", vain.util.magnify_client), - ... - ) - -If you want to "de-magnify" it, just reset the clients floating state to -`false` (hit `Mod4`+`CTRL`+`Space`, for example). - -niceborder\_{focus, unfocus} ----------------------------- - -By default, your `rc.lua` contains something like this: - - client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) - client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) - -You can change it to this: - - client.connect_signal("focus", vain.util.niceborder_focus(c)) - client.connect_signal("unfocus", vain.util.niceborder_unfocus(c)) - -Now, when a client is focused or unfocused, Awesome will look up its -nice value in `/proc//stat`. If it's less than 0, the client is -classified as "high priority"; if it's greater than 0, the client is -classified as "low priority". If it's equal to 0, nothing special -happens. - -This requires to define additional colors in your `theme.lua`. For example: - - theme.border_focus_highprio = "#FF0000" - theme.border_normal_highprio = "#A03333" - - theme.border_focus_lowprio = "#3333FF" - theme.border_normal_lowprio = "#333366" - -tag\_view\_nonempty ------------------------------- - -This function lets you jump to the next/previous non-empty tag. -It takes two arguments: - -* `direction`: `1` for next non-empty tag, `-1` for previous. -* `sc`: Screen in which the taglist is. Default is `mouse.screen` or `1`. This - argument is optional. - -Usage example: - - globalkeys = awful.util.table.join( - ... - -- Non-empty tag browsing - awful.key({ altkey }, "Left", function () vain.util.tag_view_nonempty(-1) - end), - awful.key({ altkey }, "Right", function () vain.util.tag_view_nonempty(1) end), - ... - -prompt\_rename\_tag -------------------- - -This function enables you to dynamically rename the current tag you have -focused. -Usage example: - - globalkeys = awful.util.table.join( - .. - -- Dynamic tag renaming - awful.key({ modkey, "Shift" }, "r", function () vain.util.prompt_rename_tag(mypromptbox) end), - ... - -Credits goes to [minism](https://bbs.archlinux.org/viewtopic.php?pid=1315135#p1315135). diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..264c9b0 --- /dev/null +++ b/README.rst @@ -0,0 +1,25 @@ +Lain +==== + +--------------------------------------------- +Layouts, widgets and utilities for Awesome WM +--------------------------------------------- + +Author: Luke Bonham +Version: 1.0-git +License: GNU-GPLv2_ +Source: https://github.com/copycat-killer/vain + +Based on a port of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve Awesome usability and +configurability. + +Read the wiki_ for all the info. + +Screenshots +----------- + +.. image:: + +.. _GNU-GPLv2: http://www.gnu.org/licenses/gpl-2.0.html +.. _awesome-vain: https://github.com/vain/awesome-vain +.. _wiki: https://github.com/copycat-killer/lain/wiki diff --git a/util/markup.lua b/util/markup.lua index e7baec0..dbb8529 100644 --- a/util/markup.lua +++ b/util/markup.lua @@ -19,39 +19,6 @@ local markup = {} local fg = {} local bg = {} ---[[ clean this as soon as you document it - - +-- markup - | - |`-- bold() Set bold. - |`-- italic() Set italicized text. - |`-- strike() Set strikethrough text. - |`-- underline() Set underlined text. - |`-- monospace() Set monospaced text. - |`-- big() Set bigger text. - |`-- small() Set smaller text. - |`-- font() Set the font of the text. - | - |`--+ bg - | | - | |`-- color() Set background color. - | |`-- focus() Set focus background color. - | |`-- normal() Set normal background color. - | `-- urgent() Set urgent background color. - | - |`--+ fg - | | - | |`-- color() Set foreground color. - | |`-- focus() Set focus foreground color. - | |`-- normal() Set normal foreground color. - | `-- urgent() Set urgent foreground color. - | - |`-- focus() Set both foreground and background focus colors. - |`-- normal() Set both foreground and background normal colors. - `-- urgent() Set both foreground and background urgent colors. - -]] - -- Convenience tags. function markup.bold(text) return '' .. tostring(text) .. '' end function markup.italic(text) return '' .. tostring(text) .. '' end diff --git a/widgets/mpd.lua b/widgets/mpd.lua index dcb7101..0b9a4c9 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -33,11 +33,10 @@ function worker(args) local port = args.port or "6600" local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" local refresh_timeout = args.refresh_timeout or 1 - local notify_timeout = args.notify_timeout or 5 local color_artist = args.color_artist or beautiful.fg_normal or "#FFFFFF" local color_song = args.color_song or beautiful.fg_focus or "#FFFFFF" - local spr = args.spr or "" - local musicplr = args.musicplr or "ncmpcpp" + local spr = args.spr or " " + local app = args.app or "ncmpcpp" local shadow = args.shadow or false local mpdcover = helpers.scripts_dir .. "mpdcover" @@ -100,18 +99,18 @@ function worker(args) icon = "/tmp/mpdcover.png", fg = beautiful.fg_focus or "#FFFFFF", bg = beautiful.bg_normal or "#000000" , - timeout = notify_timeout, + timeout = 6, replaces_id = mpd.id }).id end mympd:set_markup(markup(color_artist, " " .. mpd_state["{Artist}"]) .. spr .. - markup(color_song, " " .. mpd_state["{Title}"] .. " ")) + markup(color_song, mpd_state["{Title}"] .. " ")) elseif mpd_state["{state}"] == "pause" then mympd:set_markup(markup(color_artist, " mpd") .. spr .. - markup(color_song, " paused ")) + markup(color_song, "paused ")) else helpers.set_map("current mpd track", nil) set_nompd() @@ -126,7 +125,7 @@ function worker(args) mympd:buttons(awful.util.table.join( awful.button({}, 0, function() - helpers.run_in_terminal(musicplr) + helpers.run_in_terminal(app) end) )) diff --git a/widgets/net.lua b/widgets/net.lua index f361146..18727f1 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -29,7 +29,7 @@ local net = { last_r = {} } -local unit = { +net.units = { ["b"] = 1, ["kb"] = 1024, ["mb"] = 1024^2, @@ -52,12 +52,12 @@ function worker(args) local args = args or {} local iface = args.iface or net.get_device() local delta = args.refresh_timeout or 2 - local unit = args.unit or unit["kb"] + local units = args.units or net.units["kb"] local spr = args.spr or " " local header = args.header or iface local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color_up = args.color_up or beautiful.fg_focus or header_color - local color_down = args.color_down or beautiful.fg_focus or header_color + local color_up = args.color_up or beautiful.fg_focus or "#FFFFFF" + local color_down = args.color_down or beautiful.fg_focus or "#FFFFFF" local app = args.app or "sudo wifi-menu" helpers.set_map(iface, true) @@ -113,8 +113,8 @@ function worker(args) if net.last_t[iface] and net.last_t[iface] then - net.send = tostring((now_t - net.last_t[iface]) / delta / unit) - net.recv = tostring((now_r - net.last_r[iface]) / delta / unit) + net.send = tostring((now_t - net.last_t[iface]) / delta / units) + net.recv = tostring((now_r - net.last_r[iface]) / delta / units) text = text .. '' diff --git a/widgets/sysload.lua b/widgets/sysload.lua index 8583ccb..eb06828 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -30,7 +30,7 @@ function worker(args) local show_all = args.show_all or false local header = args.header or " Load " local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or header_color + local color = args.color or beautiful.fg_focus or "#FFFFFF" local app = args.app or "top" local mysysload = wibox.widget.textbox() From b45861fefee598f65220cf5a847702e4f93ef0dc Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 7 Sep 2013 16:47:17 +0200 Subject: [PATCH 003/546] version 1.0 --- widgets/yawn/icons/DayFair.png | 1 + widgets/yawn/icons/Drizzle.png | 1 + widgets/yawn/icons/Haze.png | 1 + widgets/yawn/icons/NightFair.png | 1 + widgets/yawn/icons/Sleet.png | 1 + widgets/yawn/icons/Snow.png | 1 + widgets/yawn/icons/SnowFlurries.png | 1 + 7 files changed, 7 insertions(+) create mode 120000 widgets/yawn/icons/DayFair.png create mode 120000 widgets/yawn/icons/Drizzle.png create mode 120000 widgets/yawn/icons/Haze.png create mode 120000 widgets/yawn/icons/NightFair.png create mode 120000 widgets/yawn/icons/Sleet.png create mode 120000 widgets/yawn/icons/Snow.png create mode 120000 widgets/yawn/icons/SnowFlurries.png diff --git a/widgets/yawn/icons/DayFair.png b/widgets/yawn/icons/DayFair.png new file mode 120000 index 0000000..8ee94d1 --- /dev/null +++ b/widgets/yawn/icons/DayFair.png @@ -0,0 +1 @@ +DayClear.png \ No newline at end of file diff --git a/widgets/yawn/icons/Drizzle.png b/widgets/yawn/icons/Drizzle.png new file mode 120000 index 0000000..df34463 --- /dev/null +++ b/widgets/yawn/icons/Drizzle.png @@ -0,0 +1 @@ +Rain.png \ No newline at end of file diff --git a/widgets/yawn/icons/Haze.png b/widgets/yawn/icons/Haze.png new file mode 120000 index 0000000..0874a83 --- /dev/null +++ b/widgets/yawn/icons/Haze.png @@ -0,0 +1 @@ +Hail.png \ No newline at end of file diff --git a/widgets/yawn/icons/NightFair.png b/widgets/yawn/icons/NightFair.png new file mode 120000 index 0000000..23df45a --- /dev/null +++ b/widgets/yawn/icons/NightFair.png @@ -0,0 +1 @@ +NightClear.png \ No newline at end of file diff --git a/widgets/yawn/icons/Sleet.png b/widgets/yawn/icons/Sleet.png new file mode 120000 index 0000000..f8f9693 --- /dev/null +++ b/widgets/yawn/icons/Sleet.png @@ -0,0 +1 @@ +SnowShowers.png \ No newline at end of file diff --git a/widgets/yawn/icons/Snow.png b/widgets/yawn/icons/Snow.png new file mode 120000 index 0000000..f8f9693 --- /dev/null +++ b/widgets/yawn/icons/Snow.png @@ -0,0 +1 @@ +SnowShowers.png \ No newline at end of file diff --git a/widgets/yawn/icons/SnowFlurries.png b/widgets/yawn/icons/SnowFlurries.png new file mode 120000 index 0000000..2e090cd --- /dev/null +++ b/widgets/yawn/icons/SnowFlurries.png @@ -0,0 +1 @@ +BlowingSnow.png \ No newline at end of file From c4ff9d6c8fb3b2aeed01b2668a2be469921a9ac0 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 7 Sep 2013 16:51:00 +0200 Subject: [PATCH 004/546] readme updated --- README.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 264c9b0..de2ed65 100644 --- a/README.rst +++ b/README.rst @@ -18,7 +18,9 @@ Read the wiki_ for all the info. Screenshots ----------- -.. image:: +.. image:: http://i.imgur.com/8D9A7lW.png +.. image:: http://i.imgur.com/9Iv3OR3.png +.. image:: http://i.imgur.com/STCPcaJ.png .. _GNU-GPLv2: http://www.gnu.org/licenses/gpl-2.0.html .. _awesome-vain: https://github.com/vain/awesome-vain From 6d7d870816a8ef1227e41f193818ab424a4d7d29 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 02:38:48 -0700 Subject: [PATCH 005/546] Initial commit --- LICENSE | 13 +++++++++++++ README.md | 4 ++++ 2 files changed, 17 insertions(+) create mode 100644 README.md diff --git a/LICENSE b/LICENSE index d159169..716f177 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,8 @@ +<<<<<<< HEAD GNU GENERAL PUBLIC LICENSE +======= +GNU GENERAL PUBLIC LICENSE +>>>>>>> 32a5f32... Initial commit Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., @@ -290,8 +294,13 @@ 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. +<<<<<<< HEAD Copyright (C) +======= + Next generation Vain + Copyright (C) 2013 Luke Bonham +>>>>>>> 32a5f32... Initial commit 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 @@ -329,7 +338,11 @@ 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. +<<<<<<< HEAD , 1 April 1989 +======= + {signature of Ty Coon}, 1 April 1989 +>>>>>>> 32a5f32... Initial commit Ty Coon, President of Vice This General Public License does not permit incorporating your program into diff --git a/README.md b/README.md new file mode 100644 index 0000000..2f3d7af --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +lain +==== + +Next generation Vain From 9bcd8011a3298b306ad61b983f9139293076e300 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 7 Sep 2013 16:57:07 +0200 Subject: [PATCH 006/546] readme updated --- README.md | 4 ---- README.rst | 8 ++++---- 2 files changed, 4 insertions(+), 8 deletions(-) delete mode 100644 README.md diff --git a/README.md b/README.md deleted file mode 100644 index 2f3d7af..0000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -lain -==== - -Next generation Vain diff --git a/README.rst b/README.rst index de2ed65..22d9a27 100644 --- a/README.rst +++ b/README.rst @@ -5,10 +5,10 @@ Lain Layouts, widgets and utilities for Awesome WM --------------------------------------------- -Author: Luke Bonham -Version: 1.0-git -License: GNU-GPLv2_ -Source: https://github.com/copycat-killer/vain +:Author: Luke Bonham +:Version: 1.0-git +:License: GNU-GPLv2_ +:Source: https://github.com/copycat-killer/vain Based on a port of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve Awesome usability and configurability. From f278805dc7d34fc9c7fd49776c9fb8b17ae71ace Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 7 Sep 2013 17:14:10 +0200 Subject: [PATCH 007/546] yawn doc added --- widgets/yawn/README.rst | 133 ---------------------------------------- 1 file changed, 133 deletions(-) delete mode 100644 widgets/yawn/README.rst diff --git a/widgets/yawn/README.rst b/widgets/yawn/README.rst deleted file mode 100644 index d067db3..0000000 --- a/widgets/yawn/README.rst +++ /dev/null @@ -1,133 +0,0 @@ -========================================= -Yahoo's Awesome (WM) Weather Notification -========================================= - ----------------- -Lain integration ----------------- - -:Author: Luke Bonham -:License: WTFPLv2_ -:Version: 2.0-git - -Description ------------ - -Yawn is a module for Awesome WM providing brief and compact -weather notification via Naughty and Yahoo! Weather API. - -Originally a port of perceptive_, it became a completely new module after various improvements and style changes. - ------ -Usage ------ - -You can ``register`` Yawn to get a set of widgets, or ``attach`` it to -an existent widget. - -register -^^^^^^^^ - -Call: :: - - lain.widgets.yawn(id, args) - -Arguments: - -``id`` - An integer that defines the WOEID code of your city. - To obtain it you can google 'yahoo weather %CITYNAME%' and follow the first link. - It will look like:: - - http://weather.yahoo.com/united-states/california/san-diego-2487889/ - - and the last number in that link will be the ID you need. -``args`` - An optional table which can contain the following settings: - ``u`` - Units. Type: string. Possible values: "c" (Celsius), "f" (Fahrenheit). Default: "c". - - ``toshow`` - What to show. Type: string. Possible values: "units", "forecast", "both". - Default: "forecast". - - ``units_color`` - Color of units text. Type: string. Possible values: hexadecimal color - codes. - - ``forecast_color`` - Color of forecast text. Type: string. Possible values: hexadecimal color - codes. - - ``notification_color`` - Color of notification text. Type: string. Possible values: hexadecimal color - codes. - - ``spr`` - A separator. Type: string. You can define it when ``toshow`` is set to "both". - - ``footer`` - A footer. Type: string. You can define it when ``toshow`` is set to - "both". - -The function creates an imagebox icon and a textbox widget. Add them to you wibox like this: :: - - right_layout:add(lain.widgets.yawn.icon) - right_layout:add(lain.widgets.yawn.widget) - -Hovering over ``yawn.icon`` will display the notification. - -attach -^^^^^^ - -Call: :: - - lain.widgets.yawn.attach(widget, id, args) - -Arguments: - -``widget`` - The widget which you want to attach yawn to. -``id`` - same as in ``register`` -``args`` - same as in ``register`` - -Hovering over ``widget`` will display the notification. - --------------- -Popup shortcut --------------- - -You can also create a keybinding for the weather popup like this: :: - - globalkeys = awful.util.table.join( - ... - awful.key( { "Mod1" }, "w", function () lain.widgets.yawn.show(5) end ) - ... - -where ``show`` argument is an integer defining timeout seconds. - ------------- -Localization ------------- - -Default language is English, but Yawn can be localized. -Move to ``localizations`` subdirectory and fill ``localization_template``. - -Once you're done, rename it like your locale id. In my case: :: - - $ lua - Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio - > print(os.getenv("LANG"):match("(%S*$*)[.]")) - it_IT - > - -hence I named my file "it_IT" (Italian localization). - -**NOTE:** If you create a localization, feel free to send me! I will add it. - -.. _WTFPLv2: http://www.wtfpl.net -.. _perceptive: https://github.com/ioga/perceptive -.. _Tamsyn: http://www.fial.com/~scott/tamsyn-font/ -.. _Rainbow: https://github.com/copycat-killer/awesome-copycats> From 9c829662f1940329184744696eb0f6e5fdb0e15a Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 8 Sep 2013 15:41:11 +0200 Subject: [PATCH 008/546] some fixes --- widgets/calendar.lua | 2 +- widgets/fs.lua | 8 +++---- widgets/imap.lua | 13 ++++++------ widgets/mpd.lua | 17 +++++++-------- widgets/yawn/init.lua | 49 +++++++++++++++++++------------------------ 5 files changed, 41 insertions(+), 48 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 4b6d469..38b4d8b 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -29,7 +29,7 @@ local function create(background, foreground) calendar.notify_icon = nil calendar.font_size = 12 calendar.bg = background or beautiful.bg_normal or "#FFFFFF" - calendar.fg = foreground or beautiful.fg_normal or "#FFFFFF" + calendar.fg = foreground or beautiful.fg_focus or "#FFFFFF" end function calendar:hide() diff --git a/widgets/fs.lua b/widgets/fs.lua index 9611617..283771f 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -43,7 +43,7 @@ function fs:show(t_out) notification = naughty.notify({ text = ws, timeout = t_out, - fg = beautiful.fg_focus, + fg = fs.color, }) end @@ -56,8 +56,8 @@ local function worker(args) local refresh_timeout = args.refresh_timeout or 600 local header = args.header or " Hdd " local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or "#FFFFFF" - local footer = args.header or "" + fs.color = args.color or beautiful.fg_focus or "#FFFFFF" + local footer = args.footer or "" local shadow = args.shadow or false local myfs = wibox.widget.textbox() @@ -71,7 +71,7 @@ local function worker(args) local function set_text() local info = fs_info['{' .. partition .. ' used_p}'] myfs:set_markup(markup(header_color, header) - .. markup(color, info .. footer) .. " ") + .. markup(fs.color, info .. footer)) end for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount) diff --git a/widgets/imap.lua b/widgets/imap.lua index 94652b6..5f8667d 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -35,8 +35,7 @@ function worker(args) local refresh_timeout = args.refresh_timeout or 60 local header = args.header or " Mail " local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color_newmail = args.color_newmail or beautiful.fg_focus or "#FFFFFF" - local color_nomail = args.color_nomail or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or "#FFFFFF" local mail_encoding = args.mail_encoding or nil local maxlen = args.maxlen or 200 local app = args.app or "mutt" @@ -63,7 +62,7 @@ function worker(args) then myimapcheck:set_text('') else - myimapcheck:set_markup(markup(color_nomail, " no mail ")) + myimapcheck:set_markup(markup(color, " no mail ")) end end @@ -97,8 +96,8 @@ function worker(args) elseif ws:find("CheckMailError: invalid credentials") ~= nil then helpers.set_map(mail, true) - myimapcheck.set_markup(markup(header_color, header) .. - markup(color_newmail, "invalid credentials ")) + myimapcheck:set_markup(markup(header_color, header) .. + markup(color, "invalid credentials ")) else mailcount = ws:match("%d") or "?" @@ -109,7 +108,7 @@ function worker(args) end myimapcheck:set_markup(markup(header_color, header) .. - markup(color_newmail, mailcount) .. " ") + markup(color, mailcount) .. " ") if helpers.get_map(mail) then @@ -137,7 +136,7 @@ function worker(args) end naughty.notify({ title = notify_title, - fg = color_newmail, + fg = color, text = ws, icon = beautiful.lain_mail_notify or helpers.icons_dir .. "mail.png", diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 0b9a4c9..9a9c28e 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -33,8 +33,8 @@ function worker(args) local port = args.port or "6600" local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" local refresh_timeout = args.refresh_timeout or 1 - local color_artist = args.color_artist or beautiful.fg_normal or "#FFFFFF" - local color_song = args.color_song or beautiful.fg_focus or "#FFFFFF" + local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" + local color = args.color or beautiful.fg_focus or "#FFFFFF" local spr = args.spr or " " local app = args.app or "ncmpcpp" local shadow = args.shadow or false @@ -53,7 +53,7 @@ function worker(args) then mympd:set_text('') else - mympd:set_markup(markup(color_artist, " mpd "), markup(color_song , "off ")) + mympd:set_markup(markup(header_color, " mpd "), markup(color , "off ")) end end @@ -97,20 +97,19 @@ function worker(args) mpd_state["{Date}"] .. "\n" .. mpd_state["{Title}"], icon = "/tmp/mpdcover.png", - fg = beautiful.fg_focus or "#FFFFFF", - bg = beautiful.bg_normal or "#000000" , + fg = color, timeout = 6, replaces_id = mpd.id }).id end - mympd:set_markup(markup(color_artist, " " .. mpd_state["{Artist}"]) + mympd:set_markup(markup(header_color, " " .. mpd_state["{Artist}"]) .. spr .. - markup(color_song, mpd_state["{Title}"] .. " ")) + markup(color, mpd_state["{Title}"] .. " ")) elseif mpd_state["{state}"] == "pause" then - mympd:set_markup(markup(color_artist, " mpd") + mympd:set_markup(markup(header_color, " mpd") .. spr .. - markup(color_song, "paused ")) + markup(color, "paused ")) else helpers.set_map("current mpd track", nil) set_nompd() diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index f248e25..20c90b1 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -1,11 +1,9 @@ --[[ - - Yahoo's Awesome (WM) Weather Notification - - Licensed under WTFPL v2 - * (c) 2013, Luke Bonham - + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + --]] local markup = require("lain.util.markup") @@ -26,8 +24,7 @@ local tonumber = tonumber local setmetatable = setmetatable --- yawn integration --- https://github.com/copycat-killer/yawn +-- YAhoo! Weather Notification -- lain.widgets.yawn local yawn = { @@ -52,20 +49,19 @@ local update_timer = nil local function fetch_weather(args) local toshow = args.toshow or "forecast" - local spr = args.spr or " " - local footer = args.footer or "" local url = api_url .. units_set .. city_id local f = io.popen("curl --connect-timeout 1 -fsm 2 '" .. url .. "'" ) local text = f:read("*all") - io.close(f) + f:close() -- In case of no connection or invalid city ID -- widgets won't display if text == "" or text:match("City not found") then sky = icon_path .. "na.png" + yawn.icon:set_image(sky) if text == "" then weather_data = "Service not available at the moment." return "N/A" @@ -119,14 +115,14 @@ local function fetch_weather(args) if f == nil then sky = icon_path .. "na.png" else - io.close(f) + f:close() end -- Localization local f = io.open(localizations_path .. language, "r") if language:find("en_") == nil and f ~= nil then - io.close(f) + f:close() for line in io.lines(localizations_path .. language) do word = string.sub(line, 1, line:find("|")-1) @@ -136,18 +132,20 @@ local function fetch_weather(args) end -- Finally setting infos - forecast = weather_data:match(": %S+"):gsub(": ", ""):gsub(",", "") - yawn.forecast = markup(yawn.forecast_color, markup.font(beautiful.font, forecast)) - yawn.units = markup(yawn.units_color, markup.font(beautiful.font, units)) + both = weather_data:match(": %S+.-\n"):gsub(": ", "") + forecast = weather_data:match(": %S+.-,"):gsub(": ", ""):gsub(",", "\n") + units = units:gsub(" ", "") + + yawn.forecast = markup(yawn.color, " " .. markup.font(beautiful.font, forecast) .. " ") + yawn.units = markup(yawn.color, " " .. markup.font(beautiful.font, units)) yawn.icon:set_image(sky) if toshow == "forecast" then return yawn.forecast elseif toshow == "units" then return yawn.units - else -- "both" - return yawn.forecast .. spr - .. yawn.units .. footer + else + return both end end @@ -175,21 +173,16 @@ function yawn.show(t_out) text = weather_data, icon = sky, timeout = t_out, - fg = yawn.notification_color + fg = yawn.color }) end function yawn.register(id, args) local args = args or {} - settings = { args.toshow, args.spr, args.footer } + settings = args - yawn.units_color = args.units_color or - beautiful.fg_normal or "#FFFFFF" - yawn.forecast_color = args.forecast_color or - yawn.units_color - yawn.notification_color = args.notification_color or - beautiful.fg_focus or "#FFFFFF" + yawn.color = args.color or beautiful.fg_normal or "#FFFFFF" if args.u == "f" then units_set = '?u=f&w=' end @@ -208,6 +201,8 @@ function yawn.register(id, args) yawn.icon:connect_signal("mouse::leave", function() yawn.hide() end) + + return yawn end function yawn.attach(widget, id, args) From 52a50fafa078c4fb715c7d274d875ff37e6d96f8 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 8 Sep 2013 19:19:41 +0200 Subject: [PATCH 009/546] some other space fixes --- widgets/calendar.lua | 6 +++--- widgets/cpu.lua | 4 ++-- widgets/fs.lua | 2 +- widgets/imap.lua | 6 +++--- widgets/maildir.lua | 2 +- widgets/mem.lua | 8 ++++---- widgets/mpd.lua | 11 ++++++----- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 38b4d8b..e5f6e88 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -23,7 +23,7 @@ local setmetatable = setmetatable local calendar = {} local notification = nil -local function create(background, foreground) +local function create(foreground, background) calendar.offset = 0 calendar.icons_dir = icons_dir .. "cal/white/" -- default calendar.notify_icon = nil @@ -111,8 +111,8 @@ function calendar:show(t_out, inc_offset) timeout = tims }) end -function calendar:attach(widget, background, foreground) - create(background, foreground) +function calendar:attach(widget, foreground, background) + create(foreground, background) widget:connect_signal("mouse::enter", function () calendar:show() end) widget:connect_signal("mouse::leave", function () calendar:hide() end) widget:buttons(awful.util.table.join( awful.button({ }, 1, function () diff --git a/widgets/cpu.lua b/widgets/cpu.lua index cf0b76c..3890e5e 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -32,7 +32,7 @@ function worker(args) local header = args.header or " Cpu " local header_color = args.header or beautiful.fg_normal or "#FFFFFF" local color = args.color or beautiful.fg_focus or "#FFFFFF" - local footer = args.footer or "%" + local footer = args.footer or "% " local w = wibox.widget.textbox() @@ -62,7 +62,7 @@ function worker(args) local dtotal = total - cpu.last_total local dta = math.ceil((dactive / dtotal) * 100) - w:set_markup(markup(header_color, header) .. markup(color, dta .. footer) .. " ") + w:set_markup(markup(header_color, header) .. markup(color, dta .. footer)) -- Save current data for the next run. cpu.last_active = active diff --git a/widgets/fs.lua b/widgets/fs.lua index 283771f..344bd87 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -57,7 +57,7 @@ local function worker(args) local header = args.header or " Hdd " local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" fs.color = args.color or beautiful.fg_focus or "#FFFFFF" - local footer = args.footer or "" + local footer = args.footer or " " local shadow = args.shadow or false local myfs = wibox.widget.textbox() diff --git a/widgets/imap.lua b/widgets/imap.lua index 5f8667d..f06660b 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -33,7 +33,7 @@ function worker(args) local port = args.port or "993" local refresh_timeout = args.refresh_timeout or 60 - local header = args.header or " Mail " + local header = args.header or "Mail " local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" local color = args.color or beautiful.fg_focus or "#FFFFFF" local mail_encoding = args.mail_encoding or nil @@ -96,7 +96,7 @@ function worker(args) elseif ws:find("CheckMailError: invalid credentials") ~= nil then helpers.set_map(mail, true) - myimapcheck:set_markup(markup(header_color, header) .. + myimapcheck:set_markup(" " .. markup(header_color, header) .. markup(color, "invalid credentials ")) else mailcount = ws:match("%d") or "?" @@ -107,7 +107,7 @@ function worker(args) helpers.set_map(mail .. " count", mailcount) end - myimapcheck:set_markup(markup(header_color, header) .. + myimapcheck:set_markup(" " .. markup(header_color, header) .. markup(color, mailcount) .. " ") if helpers.get_map(mail) diff --git a/widgets/maildir.lua b/widgets/maildir.lua index b5437bd..98de091 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -108,7 +108,7 @@ function worker(args) myimapcheck:set_markup(markup(color_nomail, " no mail ")) end else - myimapcheck:set_markup(markup(header_color, header) .. + myimapcheck:set_markup(" " .. markup(header_color, header) .. markup(color_newmail, newmail) .. " ") end end diff --git a/widgets/mem.lua b/widgets/mem.lua index 09be00f..3034e89 100644 --- a/widgets/mem.lua +++ b/widgets/mem.lua @@ -35,7 +35,7 @@ function worker(args) local header = args.header or " Mem " local header_color = args.header or beautiful.fg_normal or "#FFFFFF" local color = args.color or beautiful.fg_focus or "#FFFFFF" - local footer = args.footer or "MB" + local footer = args.footer or "MB " local widg = wibox.widget.textbox() @@ -62,17 +62,17 @@ function worker(args) then local fmt = "%" .. string.len(mem.total) .. ".0f/%.0f" widg:set_markup(markup(header_color, header) .. - markup(color, string.format(fmt, used, mem.total) .. footer .. " ")) + markup(color, string.format(fmt, used, mem.total) .. footer)) else widg:set_markup(markup(header_color, header) .. - markup(color, used .. footer .. " ")) + markup(color, used .. footer)) end if show_swap then widg:set_markup(widg._layout.text .. ' (' .. string.format('%.0f '.. footer, swapused) - .. ') ') + .. ')') end end diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 9a9c28e..8db62ae 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -36,6 +36,7 @@ function worker(args) local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" local color = args.color or beautiful.fg_focus or "#FFFFFF" local spr = args.spr or " " + local footer = args.footer or "" local app = args.app or "ncmpcpp" local shadow = args.shadow or false @@ -53,7 +54,7 @@ function worker(args) then mympd:set_text('') else - mympd:set_markup(markup(header_color, " mpd "), markup(color , "off ")) + mympd:set_markup(markup(header_color, "mpd ") .. markup(color , "off") .. footer) end end @@ -102,14 +103,14 @@ function worker(args) replaces_id = mpd.id }).id end - mympd:set_markup(markup(header_color, " " .. mpd_state["{Artist}"]) + mympd:set_markup(markup(header_color, mpd_state["{Artist}"]) .. spr .. - markup(color, mpd_state["{Title}"] .. " ")) + markup(color, mpd_state["{Title}"]) .. footer) elseif mpd_state["{state}"] == "pause" then - mympd:set_markup(markup(header_color, " mpd") + mympd:set_markup(markup(header_color, "mpd") .. spr .. - markup(color, "paused ")) + markup(color, "paused") .. footer) else helpers.set_map("current mpd track", nil) set_nompd() From a2379fd5555c3a392142b21b4d8ff28d91c37831 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 9 Sep 2013 01:58:31 +0200 Subject: [PATCH 010/546] readme updated --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 22d9a27..2524de3 100644 --- a/README.rst +++ b/README.rst @@ -8,7 +8,7 @@ Layouts, widgets and utilities for Awesome WM :Author: Luke Bonham :Version: 1.0-git :License: GNU-GPLv2_ -:Source: https://github.com/copycat-killer/vain +:Source: https://github.com/copycat-killer/lain Based on a port of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve Awesome usability and configurability. From 8d37b9a1e4521a220f20ce2e1414f656aa3a5015 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 10 Sep 2013 23:02:11 +0200 Subject: [PATCH 011/546] totally reworked widgets --- README.rst | 2 +- helpers.lua | 46 ++++-------- widgets/alsa.lua | 103 ++++++++----------------- widgets/alsabar.lua | 43 ++++++----- widgets/bat.lua | 102 +++++++++---------------- widgets/calendar.lua | 27 +++---- widgets/cpu.lua | 31 ++++---- widgets/fs.lua | 102 ++++++++++++------------- widgets/imap.lua | 170 +++++++++++++++++------------------------- widgets/init.lua | 6 +- widgets/maildir.lua | 60 ++++----------- widgets/mem.lua | 45 +++-------- widgets/mpd.lua | 121 ++++++++++++------------------ widgets/net.lua | 133 ++++++++++----------------------- widgets/sysload.lua | 44 +++-------- widgets/temp.lua | 31 +++----- widgets/yawn/init.lua | 88 ++++++++-------------- 17 files changed, 415 insertions(+), 739 deletions(-) diff --git a/README.rst b/README.rst index 2524de3..6ce1c47 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,7 @@ Layouts, widgets and utilities for Awesome WM :License: GNU-GPLv2_ :Source: https://github.com/copycat-killer/lain -Based on a port of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve Awesome usability and +Successor of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve Awesome usability and configurability. Read the wiki_ for all the info. diff --git a/helpers.lua b/helpers.lua index 7677768..a8c4cd7 100644 --- a/helpers.lua +++ b/helpers.lua @@ -4,14 +4,12 @@ Licensed under GNU General Public License v2 * (c) 2013, Luke Bonham * (c) 2010-2012, Peter Hofmann - * (c) 2010, Adrian C. --]] -local awful = require("awful") local debug = require("debug") -local pairs = pairs local rawget = rawget +local io = { open = io.open } -- Lain helper functions for internal use -- lain.helpers @@ -30,33 +28,6 @@ end -- }}} --- {{{ --- If lain.terminal is a string, e.g. "xterm", then "xterm -e " .. cmd is --- run. But if lain.terminal is a function, then terminal(cmd) is run. - -function helpers.run_in_terminal(cmd) - if type(terminal) == "function" - then - terminal(cmd) - elseif type(terminal) == "string" - then - awful.util.spawn(terminal .. ' -e ' .. cmd) - end -end - --- }}} - --- {{{ Format units to one decimal point - -function helpers.uformat(array, key, value, unit) - for u, v in pairs(unit) do - array["{"..key.."_"..u.."}"] = string.format("%.1f", value/v) - end - return array -end - --- }}} - -- {{{ Read the first line of a file or return nil. function helpers.first_line(f) @@ -73,6 +44,21 @@ end -- }}} +-- {{{ Timer maker + +helpers.timer_table = {} + +function helpers.newtimer(name, timeout, fun, nostart) + helpers.timer_table[name] = timer({ timeout = timeout }) + helpers.timer_table[name]:connect_signal("timeout", fun) + helpers.timer_table[name]:start() + if not nostart then + helpers.timer_table[name]:emit_signal("timeout") + end +end + +-- }}} + -- {{{ A map utility helpers.map_table = {} diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 7c26908..8571ec6 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -2,102 +2,65 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - * (c) 2010, Adrian C. + * (c) 2013, Luke Bonham + * (c) 2010, Adrian C. --]] -local markup = require("lain.util.markup") -local run_in_terminal = require("lain.helpers").run_in_terminal +local newtimer = require("lain.helpers").newtimer -local awful = require("awful") -local beautiful = require("beautiful") local wibox = require("wibox") -local io = io -local string = { format = string.format, - match = string.match } +local io = { popen = io.popen } +local string = { match = string.match } local setmetatable = setmetatable --- ALSA volume infos --- nain.widgets.alsa -local alsa = { - volume = 0, - mute = false, -} +-- ALSA volume +-- lain.widgets.alsa +local alsa = {} -function worker(args) - local args = args or {} - local channel = args.channel or "Master" - local step = args.step or "1%" - local header = args.header or " Vol " - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or "#FFFFFF" +local function worker(args) + local args = args or {} + local timeout = args.timeout or 5 + local channel = args.channel or "Master" + local settings = args.settings or function() end - local myvolume = wibox.widget.textbox() - local myvolumeupdate = function() + widget = wibox.widget.textbox('') + + function update() local f = io.popen('amixer get ' .. channel) local mixer = f:read("*all") f:close() - local volume, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + volume = {} - if volume == nil + volume.level, volume.status = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + + if volume.level == nil then - alsa.volume = 0 - else - alsa.volume = volume + volume.level = 0 + volume.status = "off" end - if mute == nil or mute == 'on' + if volume.status == "" then - alsa.mute = true - mute = '' - else - alsa.mute = false - mute = 'M' + if volume.level == 0 + then + volume.status = "off" + else + volume.status = "on" + end end - local ret = markup(color, string.format("%d%s", volume, mute)) - myvolume:set_markup(markup(header_color, header) .. ret .. " ") + settings() end - local myvolumetimer = timer({ timeout = 5 }) - myvolumetimer:connect_signal("timeout", myvolumeupdate) - myvolumetimer:start() - myvolumetimer:emit_signal("timeout") + newtimer("alsa", timeout, update) - myvolume:buttons(awful.util.table.join( - awful.button({}, 1, - function() - run_in_terminal('alsamixer') - end), - awful.button({}, 3, - function() - awful.util.spawn('amixer sset ' .. channel ' toggle') - end), + output = { widget = widget, notify = update } - awful.button({}, 4, - function() - awful.util.spawn('amixer sset ' .. channel .. ' ' .. step '+') - myvolumeupdate() - end), - - awful.button({}, 5, - function() - awful.util.spawn('amixer sset ' .. channel .. ' ' .. step '-') - myvolumeupdate() - end) - )) - - alsa.widget = myvolume - alsa.channel = channel - alsa.step = step - alsa.notify = myvolumeupdate - - return setmetatable(alsa, { __index = alsa.widget }) + return setmetatable(output, { __index = output.widget }) end return setmetatable(alsa, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 0421f5c..7f5fe87 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -6,6 +6,8 @@ * (c) 2013, Rman --]] +local newtimer = require("lain.helpers").newtimer + local awful = require("awful") local beautiful = require("beautiful") local naughty = require("naughty") @@ -32,12 +34,14 @@ local alsabar = unmute = "#A4CE8A" }, + terminal = terminal or "xterm", mixer = terminal .. " -e alsamixer", notifications = { font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), font_size = "11", + color = beautiful.fg_focus, bar_size = 18 -- Awesome default }, @@ -49,9 +53,9 @@ function alsabar:notify() local preset = { title = "", text = "", - timeout = 3, + timeout = 15, font = alsabar.notifications.font .. " " .. alsabar.notifications.font_size, - fg = beautiful.fg_focus + fg = alsabar.notifications.color } if alsabar._muted then @@ -72,7 +76,7 @@ function alsabar:notify() end end -function worker(args) +local function worker(args) local args = args or {} local width = args.width or 63 local height = args.heigth or 1 @@ -85,6 +89,7 @@ function worker(args) alsabar.notifications = args.notifications or alsabar.notifications alsabar.bar = awful.widget.progressbar() + alsabar.bar:set_background_color(alsabar.colors.background) alsabar.bar:set_color(alsabar.colors.unmute) alsabar.tooltip = awful.tooltip({ objects = { alsabar.bar } }) @@ -97,18 +102,18 @@ function worker(args) alsabar.bar:set_vertical(true) end - local myvolumebarupdate = function() + function update() -- Get mixer control contents local f = io.popen("amixer get " .. alsabar.channel) local mixer = f:read("*all") f:close() -- Capture mixer control state: [5%] ... ... [on] - local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") - -- Handle mixers without data + local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + if volu == nil then - volu = 0 - mute = "off" + volu = 0 + mute = "off" end alsabar._current_level = tonumber(volu) / 100 @@ -126,10 +131,7 @@ function worker(args) end end - local myvolumebartimer = timer({ timeout = 5 }) - myvolumebartimer:connect_signal("timeout", myvolumebarupdate) - myvolumebartimer:start() - myvolumebartimer:emit_signal("timeout") + newtimer("alsabar", 5, update) alsabar.bar:buttons (awful.util.table.join ( awful.button ({}, 1, function() @@ -151,14 +153,15 @@ function worker(args) end) )) - return { widget = alsabar.bar, - channel = alsabar.channel, - step = alsabar.step, - notify = function() - myvolumebarupdate() - alsabar.notify() - end - } + return { + widget = alsabar.bar, + channel = alsabar.channel, + step = alsabar.step, + notify = function() + update() + alsabar.notify() + end + } end return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/bat.lua b/widgets/bat.lua index 0461607..5a811f0 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -7,10 +7,9 @@ --]] -local markup = require("lain.util.markup") +local newtimer = require("lain.helpers").newtimer local first_line = require("lain.helpers").first_line -local beautiful = require("beautiful") local naughty = require("naughty") local wibox = require("wibox") @@ -21,25 +20,24 @@ local setmetatable = setmetatable -- Battery infos -- lain.widgets.bat -local bat = { - status = "not present", - perc = "N/A", - time = "N/A", -} +local bat = { id = nil } -function worker(args) +local function worker(args) local args = args or {} + local timeout = args.timeout or 30 local battery = args.battery or "BAT0" - local show_all = args.show_all or false - local refresh_timeout = args.refresh_timeout or 30 - local header = args.header or " Bat " - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or "#FFFFFF" - local shadow = args.shadow or false + local settings = args.settings or function() end - local mybattery = wibox.widget.textbox() + bat_now = { + status = "not present", + perc = "N/A", + time = "N/A", + watt = "N/A" + } - local mybatteryupdate = function() + widget = wibox.widget.textbox('') + + function update() local present = first_line("/sys/class/power_supply/" .. battery .. "/present") @@ -58,90 +56,62 @@ function worker(args) local tot = first_line("/sys/class/power_supply/" .. battery .. "/energy_full") - bat.status = first_line("/sys/class/power_supply/" + bat_now.status = first_line("/sys/class/power_supply/" .. battery .. "/status") local time_rat = 0 - if bat.status == "Charging" + if bat_now.status == "Charging" then - status = "(+)" time_rat = (tot - rem) / rate - elseif bat.status == "Discharging" + elseif bat_now.status == "Discharging" then - status = "(-)" time_rat = rem / rate - else - status = "(.)" end local hrs = math.floor(time_rat) local min = (time_rat - hrs) * 60 - bat.time = string.format("%02d:%02d", hrs, min) - local amount = (rem / tot) * 100 - - if shadow - then - bat.perc = string.format("%d", amount) - else - bat.perc = string.format("%d%%", amount) - end - - local watt = string.format("%.2fW", (rate * ratev) / 1e12) - - if show_all - then - text = watt .. " " .. bat.perc .. " " .. bat.time .. " " .. bat.status - else - text = bat.perc - end + bat_now.time = string.format("%02d:%02d", hrs, min) + bat_now.perc = (rem / tot) * 100 + bat_now.watt = string.format("%.2fW", (rate * ratev) / 1e12) -- notifications for low and critical states - if amount <= 5 + if bat_now.perc <= 5 then - naughty.notify{ + bat.id = naughty.notify({ text = "shutdown imminent", title = "battery nearly exhausted", position = "top_right", timeout = 15, fg="#000000", bg="#ffffff", - ontop = true - } - elseif amount <= 15 + ontop = true, + replaces_id = bat.id + }).id + elseif bat.perc <= 15 then - old_id = naughty.notify{ + bat.id = naughty.notify({ text = "plug the cable", title = "battery low", position = "top_right", - timeout = 5, + timeout = 15, fg="#202020", bg="#cdcdcd", - ontop = true - } + ontop = true, + replaces_id = bat.id + }).id end - else - text = "none" + + bat_now.perc = string.format("%d", bat_now.perc) end - if shadow - then - mybattery:set_text('') - else - mybattery:set_markup(markup(header_color, header) - .. markup(color, text) .. " ") - end + settings() end - local mybatterytimer = timer({ timeout = refresh_timeout }) - mybatterytimer:connect_signal("timeout", mybatteryupdate) - mybatterytimer:start() - mybatterytimer:emit_signal("timeout") + newtimer("bat", timeout, update) - bat.widget = mybattery - - return setmetatable(bat, { __index = bat.widget }) + return widget end return setmetatable(bat, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index e5f6e88..e28e735 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -13,7 +13,7 @@ local beautiful = require("beautiful") local naughty = require("naughty") local io = io -local os = { date = os.date } +local os = { date = os.date } local tonumber = tonumber local setmetatable = setmetatable @@ -23,15 +23,6 @@ local setmetatable = setmetatable local calendar = {} local notification = nil -local function create(foreground, background) - calendar.offset = 0 - calendar.icons_dir = icons_dir .. "cal/white/" -- default - calendar.notify_icon = nil - calendar.font_size = 12 - calendar.bg = background or beautiful.bg_normal or "#FFFFFF" - calendar.fg = foreground or beautiful.fg_focus or "#FFFFFF" -end - function calendar:hide() if notification ~= nil then naughty.destroy(notification) @@ -59,7 +50,7 @@ function calendar:show(t_out, inc_offset) end calendar.offset = 0 - calendar.notify_icon = calendar.icons_dir .. today .. ".png" + calendar.notify_icon = calendar.icons .. today .. ".png" -- bg and fg inverted to highlight today f = io.popen( init_t .. today .. @@ -106,13 +97,23 @@ function calendar:show(t_out, inc_offset) notification = naughty.notify({ text = c_text, icon = calendar.notify_icon, + position = calendar.position, fg = calendar.fg, bg = calendar.bg, timeout = tims }) end -function calendar:attach(widget, foreground, background) - create(foreground, background) +function calendar:attach(widget, args) + local args = args or {} + calendar.icons = args.icons or icons_dir .. "cal/white/" + calendar.font_size = tonumber(args.font_size) or 12 + calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" + calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF" + calendar.position = args.position or "top_right" + + calendar.offset = 0 + calendar.notify_icon = nil + widget:connect_signal("mouse::enter", function () calendar:show() end) widget:connect_signal("mouse::leave", function () calendar:hide() end) widget:buttons(awful.util.table.join( awful.button({ }, 1, function () diff --git a/widgets/cpu.lua b/widgets/cpu.lua index 3890e5e..f9bbe72 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -7,15 +7,15 @@ --]] -local markup = require("lain.util.markup") local first_line = require("lain.helpers").first_line +local newtimer = require("lain.helpers").newtimer -local beautiful = require("beautiful") local wibox = require("wibox") local math = { ceil = math.ceil } local string = { format = string.format, gmatch = string.gmatch } +local tostring = tostring local setmetatable = setmetatable @@ -26,17 +26,14 @@ local cpu = { last_active = 0 } -function worker(args) - local args = args or {} - local refresh_timeout = args.refresh_timeout or 5 - local header = args.header or " Cpu " - local header_color = args.header or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or "#FFFFFF" - local footer = args.footer or "% " +local function worker(args) + local args = args or {} + local timeout = args.timeout or 5 + local settings = args.settings or function() end - local w = wibox.widget.textbox() + widget = wibox.widget.textbox('') - local cpuusageupdate = function() + function update() -- Read the amount of time the CPUs have spent performing -- different kinds of work. Read the first line of /proc/stat -- which is the sum of all CPUs. @@ -60,21 +57,19 @@ function worker(args) -- Read current data and calculate relative values. local dactive = active - cpu.last_active local dtotal = total - cpu.last_total - local dta = math.ceil((dactive / dtotal) * 100) - w:set_markup(markup(header_color, header) .. markup(color, dta .. footer)) + usage = tostring(math.ceil((dactive / dtotal) * 100)) + + settings() -- Save current data for the next run. cpu.last_active = active cpu.last_total = total end - local cpuusagetimer = timer({ timeout = refresh_timeout }) - cpuusagetimer:connect_signal("timeout", cpuusageupdate) - cpuusagetimer:start() - cpuusagetimer:emit_signal("timeout") + newtimer("cpu", timeout, update) - return w + return widget end return setmetatable(cpu, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/fs.lua b/widgets/fs.lua index 344bd87..f934248 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -8,7 +8,6 @@ --]] -local markup = require("lain.util.markup") local helpers = require("lain.helpers") local beautiful = require("beautiful") @@ -16,14 +15,16 @@ local wibox = require("wibox") local naughty = require("naughty") local io = io -local string = { match = string.match } +local pairs = pairs +local string = { match = string.match, + format = string.format } local tonumber = tonumber local setmetatable = setmetatable -- File system disk space usage -- lain.widgets.fs -local fs = {} +local fs = { notification_preset = {} } local notification = nil function fs:hide() @@ -41,38 +42,29 @@ function fs:show(t_out) f:close() notification = naughty.notify({ + preset = fs.notification_preset, text = ws, - timeout = t_out, - fg = fs.color, + timeout = t_out }) end --- Variable definitions +-- Units definitions local unit = { ["mb"] = 1024, ["gb"] = 1024^2 } local function worker(args) - local args = args or {} + local args = args or {} local partition = args.partition or "/" - local refresh_timeout = args.refresh_timeout or 600 - local header = args.header or " Hdd " - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - fs.color = args.color or beautiful.fg_focus or "#FFFFFF" - local footer = args.footer or " " - local shadow = args.shadow or false + local timeout = args.timeout or 600 + local settings = args.settings or function() end - local myfs = wibox.widget.textbox() + widget = wibox.widget.textbox('') helpers.set_map("fs", false) - local fsupdate = function() - local fs_info = {} -- Get data from df - local f = io.popen("LC_ALL=C df -kP") + function update() + fs_info = {} - local function set_text() - local info = fs_info['{' .. partition .. ' used_p}'] - myfs:set_markup(markup(header_color, header) - .. markup(fs.color, info .. footer)) - end + local f = io.popen("LC_ALL=C df -kP") for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount) local s = string.match(line, "^.-[%s]([%d]+)") @@ -80,55 +72,57 @@ local function worker(args) local m = string.match(line, "%%[%s]([%p%w]+)") if u and m then -- Handle 1st line and broken regexp - helpers.uformat(fs_info, m .. " used", u, unit) - fs_info["{" .. m .. " used_p}"] = tonumber(p) + fs_info[m .. " size_mb"] = string.format("%.1f", tonumber(s) / unit["mb"]) + fs_info[m .. " size_gb"] = string.format("%.1f", tonumber(s) / unit["gb"]) + fs_info[m .. " used_p"] = tonumber(p) + fs_info[m .. " avail_p"] = 100 - tonumber(p) end end f:close() - if shadow + -- chosen partition easy stuff + -- you can however check whatever partition else + used = fs_info[partition .. " used_p"] + available = fs_info[partition .. " avail_p"] + size_mb = fs_info[partition .. " size_mb"] + size_gb = fs_info[partition .. " size_gb"] + + notification_preset = { fg = beautiful.fg_normal } + + settings() + + fs.notification_preset = notification_preset + + if used >= 99 and not helpers.get_map("fs") then - myfs:set_text('') + naughty.notify({ + title = "warning", + text = partition .. " ran out!\nmake some room", + timeout = 8, + fg = "#000000", + bg = "#FFFFFF" + }) + helpers.set_map("fs", true) else - set_text() - end - - local part = fs_info['{' .. partition .. ' used_p}'] - - if part >= 90 then - if part >= 99 and not helpers.get_map("fs") then - naughty.notify({ title = "warning", - text = partition .. " ran out!\n" - .. "make some room", - timeout = 8, - position = "top_right", - fg = beautiful.fg_urgent, - bg = beautiful.bg_urgent }) - helpers.set_map("fs", true) - end - if shadow then set_text() end + helpers.set_map("fs", false) end end - local fstimer = timer({ timeout = refresh_timeout }) - fstimer:connect_signal("timeout", fsupdate) - fstimer:start() - fstimer:emit_signal("timeout") + helpers.newtimer("fs " .. partition, timeout, update) - myfs:connect_signal('mouse::enter', function () fs:show(0) end) - myfs:connect_signal('mouse::leave', function () fs:hide() end) + widget:connect_signal('mouse::enter', function () fs:show(0) end) + widget:connect_signal('mouse::leave', function () fs:hide() end) - local fs_out = - { - widget = myfs, + output = { + widget = widget, show = function(t_out) - fsupdate() + update() fs:show(t_out) end } - return setmetatable(fs_out, { __index = fs_out.widget }) + return setmetatable(output, { __index = output.widget }) end return setmetatable(fs, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/imap.lua b/widgets/imap.lua index f06660b..2c7067c 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -6,160 +6,126 @@ --]] -local markup = require("lain.util.markup") local helpers = require("lain.helpers") -local awful = require("awful") -local beautiful = require("beautiful") local naughty = require("naughty") local wibox = require("wibox") -local io = io +local io = { popen = io.popen } local tonumber = tonumber -local string = string +local string = { len = string.len, + format = string.format } local setmetatable = setmetatable --- Mail imap check +-- Mail IMAP check -- lain.widgets.imap -local imap = {} +local imap = { stored = nil } function worker(args) - local args = args or {} + local args = args or {} - local server = args.server - local mail = args.mail + local server = args.server + local mail = args.mail local password = args.password - local port = args.port or "993" - local refresh_timeout = args.refresh_timeout or 60 - local header = args.header or "Mail " - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or "#FFFFFF" - local mail_encoding = args.mail_encoding or nil - local maxlen = args.maxlen or 200 - local app = args.app or "mutt" + local port = args.port or "993" + local timeout = args.timeout or 60 + local encoding = args.encoding or nil + local maxlen = args.maxlen or 200 local is_plain = args.is_plain or false - local shadow = args.shadow or false + local settings = args.settings or function() end + + local checkmail = helpers.scripts_dir .. "checkmail" helpers.set_map(mail, true) helpers.set_map(mail .. " count", "0") - local checkmail = helpers.scripts_dir .. "checkmail" - if not is_plain then - local f = io.popen(password) - password = f:read("*all"):gsub("\n", ""):gsub("\r", "") - f:close() + if not imap.stored + then + local f = io.popen(password) + password = f:read("*all"):gsub("\n", ""):gsub("\r", "") + f:close() + imap.stored = password + else + password = imap.stored + end end - local myimapcheck = wibox.widget.textbox() + widget = wibox.widget.textbox('') - local myimapcheckupdate = function() - function set_nomail() - if shadow - then - myimapcheck:set_text('') - else - myimapcheck:set_markup(markup(color, " no mail ")) - end - end + function update() + to_execute = string.format("%s -s %s -u %s -p %s --port %s", + checkmail, server, mail, password, port) - conn = io.popen("ip link show") - check_conn = conn:read("*all") - conn:close() - - if not check_conn:find("state UP") then - set_nomail() - return - end - - to_execute = checkmail .. ' -s ' .. server .. - ' -u ' .. mail .. ' -p ' .. password - .. ' --port ' .. port - - if mail_encoding ~= nil + if encoding ~= nil then - to_execute = to_execute .. ' --encoding ' - .. mail_encoding + to_execute = string.format("%s --encoding %s", + to_execute, encoding) end f = io.popen(to_execute) ws = f:read("*all") f:close() + mailcount = "0" + if ws:find("No new messages") ~= nil then helpers.set_map(mail, true) - set_nomail() elseif ws:find("CheckMailError: invalid credentials") ~= nil then helpers.set_map(mail, true) - myimapcheck:set_markup(" " .. markup(header_color, header) .. - markup(color, "invalid credentials ")) + mailcount = "invalid credentials" else - mailcount = ws:match("%d") or "?" - - if helpers.get_map(mail .. " count") ~= mailcount and mailcount ~= "?" + mailcount = ws:match("%d") or "0" + if helpers.get_map(mail .. " count") ~= mailcount and mailcount ~= "0" then helpers.set_map(mail, true) helpers.set_map(mail .. " count", mailcount) end + end - myimapcheck:set_markup(" " .. markup(header_color, header) .. - markup(color, mailcount) .. " ") + notification_preset = { + icon = helpers.icons_dir .. "mail.png", + timeout = 8, + position = "top_left" + } - if helpers.get_map(mail) + settings() + + + if helpers.get_map(mail) and tonumber(mailcount) >= 1 + then + notify_title = ws:match(mail .. " has %d new message.?") + ws = ws:gsub(notify_title, "", 1):gsub("\n", "", 2) + + -- trying to remove useless infos + ws = ws:gsub("--Content.%S+.-\n", "") + ws = ws:gsub("--%d+.-\n", "") + + if string.len(ws) > maxlen then - if mailcount == "?" - -- May happens sometimes using keyrings or other password fetchers. - -- Since this should be automatically fixed in short times, we threat - -- this exception delaying the update to the next timeout. - then - set_nomail() - return - elseif tonumber(mailcount) >= 1 - then - notify_title = ws:match(mail .. " has %d new message.?") - ws = ws:gsub(notify_title, "", 1):gsub("\n", "", 2) - - ws = ws:gsub("--Content.%S+.-\n", "") - ws = ws:gsub("--%d+.-\n", "") - - if string.len(ws) > maxlen - then - ws = ws:sub(1, maxlen) .. "[...]" - end - - notify_title = notify_title:gsub("\n", "") - end - - naughty.notify({ title = notify_title, - fg = color, - text = ws, - icon = beautiful.lain_mail_notify or - helpers.icons_dir .. "mail.png", - timeout = 8, - position = "top_left" }) - - helpers.set_map(mail, false) + ws = ws:sub(1, maxlen) .. "[...]" end + + notify_title = notify_title:gsub("\n", "") + + naughty.notify({ + preset = notification_preset, + title = notify_title, + text = ws + }) + + helpers.set_map(mail, false) end end - local myimapchecktimer = timer({ timeout = refresh_timeout }) - myimapchecktimer:connect_signal("timeout", myimapcheckupdate) - myimapchecktimer:start() - myimapcheck:buttons(awful.util.table.join( - awful.button({}, 0, + helpers.newtimer(mail, timeout, update, true) - function() - helpers.run_in_terminal(app) - end) - )) - - return myimapcheck + return widget end return setmetatable(imap, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/init.lua b/widgets/init.lua index 78cac9b..0e863ba 100644 --- a/widgets/init.lua +++ b/widgets/init.lua @@ -15,10 +15,6 @@ local wrequire = require("lain.helpers").wrequire local setmetatable = setmetatable -local widgets = -{ - _NAME = "lain.widgets", - terminal = "xterm" -- X default -} +local widgets = { _NAME = "lain.widgets" } return setmetatable(widgets, { __index = wrequire }) diff --git a/widgets/maildir.lua b/widgets/maildir.lua index 98de091..00ab771 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -7,11 +7,8 @@ --]] -local markup = require("lain.util.markup") -local run_in_terminal = require("lain.helpers").run_in_terminal +local newtimer = require("lain.helpers").newtimer -local awful = require("awful") -local beautiful = require("beautiful") local wibox = require("wibox") local io = io @@ -28,25 +25,20 @@ local setmetatable = setmetatable local maildir = {} function worker(args) - local args = args or {} - local mailpath = args.mailpath or os.getenv("HOME") .. "/Mail" + local args = args or {} + local timeout = args.timeout or 60 + local mailpath = args.mailpath or os.getenv("HOME") .. "/Mail" local ignore_boxes = args.ignore_boxes or {} - local refresh_timeout = args.refresh_timeout or 60 - local header = args.header or " Mail " - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color_newmail = args.color_newmail or beautiful.fg_focus or "#FFFFFF" - local color_nomail = args.color_nomail or beautiful.fg_normal or "#FFFFFF" - local app = args.app or "mutt" - local shadow = args.shadow or false + local settings = args.settings or function() end - local mymailcheck = wibox.widget.textbox() - local mymailcheckupdate = function() + widget = wibox.widget.textbox('') + + function update() -- Find pathes to mailboxes. local p = io.popen("find " .. mailpath .. " -mindepth 1 -maxdepth 1 -type d" .. " -not -name .git") local boxes = {} - local line = "" repeat line = p:read("*l") if line ~= nil @@ -73,7 +65,8 @@ function worker(args) table.sort(boxes) - local newmail = "" + newmail = "no mail" + local count = 0 for box, number in pairs(boxes) do @@ -91,39 +84,12 @@ function worker(args) end end - if count == 1 then - -- it will be only executed once - for box, number in pairs(boxes) - do -- it's useless to show only INBOX(x) - if box == "INBOX" then newmail = number end - end - end - - if newmail == "" - then - if shadow - then - mymailcheck:set_text('') - else - myimapcheck:set_markup(markup(color_nomail, " no mail ")) - end - else - myimapcheck:set_markup(" " .. markup(header_color, header) .. - markup(color_newmail, newmail) .. " ") - end + settings() end - local mymailchecktimer = timer({ timeout = refresh_timeout }) - mymailchecktimer:connect_signal("timeout", mymailcheckupdate) - mymailchecktimer:start() - mymailcheck:buttons(awful.util.table.join( - awful.button({}, 0, - function() - run_in_terminal(app) - end) - )) + newtimer(mailpath, timeout, update, true) - return mymailcheck + return widget end return setmetatable(maildir, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/mem.lua b/widgets/mem.lua index 3034e89..d0ff223 100644 --- a/widgets/mem.lua +++ b/widgets/mem.lua @@ -9,10 +9,8 @@ --]] -local markup = require("lain.util.markup") -local run_in_terminal = require("lain.helpers").run_in_terminal +local newtimer = require("lain.helpers").newtimer -local beautiful = require("beautiful") local wibox = require("wibox") local io = { lines = io.lines } @@ -28,19 +26,14 @@ local setmetatable = setmetatable local mem = {} function worker(args) - local args = args or {} - local refresh_timeout = args.refresh_timeout or 10 - local show_swap = args.show_swap or false - local show_total = args.show_total or false - local header = args.header or " Mem " - local header_color = args.header or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or "#FFFFFF" - local footer = args.footer or "MB " + local args = args or {} + local timeout = args.timeout or 3 + local settings = args.settings or function() end - local widg = wibox.widget.textbox() + widget = wibox.widget.textbox('') - local upd = function() - local mem = {} + function update() + mem = {} for line in io.lines("/proc/meminfo") do for k, v in string.gmatch(line, "([%a]+):[%s]+([%d]+).+") @@ -58,30 +51,12 @@ function worker(args) used = mem.total - (mem.free + mem.buf + mem.cache) swapused = mem.swap - mem.swapf - if show_total - then - local fmt = "%" .. string.len(mem.total) .. ".0f/%.0f" - widg:set_markup(markup(header_color, header) .. - markup(color, string.format(fmt, used, mem.total) .. footer)) - else - widg:set_markup(markup(header_color, header) .. - markup(color, used .. footer)) - end - - if show_swap - then - widg:set_markup(widg._layout.text .. ' (' - .. string.format('%.0f '.. footer, swapused) - .. ')') - end + settings() end - local tmr = timer({ timeout = refresh_timeout }) - tmr:connect_signal("timeout", upd) - tmr:start() - tmr:emit_signal("timeout") + newtimer("mem", timeout, update) - return widg + return widget end return setmetatable(mem, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 8db62ae..8ba1cde 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -7,10 +7,9 @@ --]] -local markup = require("lain.util.markup") local helpers = require("lain.helpers") -local awful = require("awful") +local util = require("awful.util") local beautiful = require("beautiful") local naughty = require("naughty") local wibox = require("wibox") @@ -27,111 +26,87 @@ local setmetatable = setmetatable local mpd = { id = nil } function worker(args) - local args = args or {} - local password = args.password or "" - local host = args.host or "127.0.0.1" - local port = args.port or "6600" + local args = args or {} + local timeout = args.timeout or 1 + local password = args.password or "" + local host = args.host or "127.0.0.1" + local port = args.port or "6600" local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" - local refresh_timeout = args.refresh_timeout or 1 - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or "#FFFFFF" - local spr = args.spr or " " - local footer = args.footer or "" - local app = args.app or "ncmpcpp" - local shadow = args.shadow or false + local settings = args.settings or function() end local mpdcover = helpers.scripts_dir .. "mpdcover" - local mpdh = "telnet://"..host..":"..port - local echo = "echo 'password "..password.."\nstatus\ncurrentsong\nclose'" + local mpdh = "telnet://" .. host .. ":" .. port + local echo = "echo 'password " .. password .. "\nstatus\ncurrentsong\nclose'" - local mympd = wibox.widget.textbox() + widget = wibox.widget.textbox('') helpers.set_map("current mpd track", nil) - local mympdupdate = function() - local function set_nompd() - if shadow - then - mympd:set_text('') - else - mympd:set_markup(markup(header_color, "mpd ") .. markup(color , "off") .. footer) - end - end - - local mpd_state = { - ["{state}"] = "N/A", - ["{file}"] = "N/A", - ["{Artist}"] = "N/A", - ["{Title}"] = "N/A", - ["{Album}"] = "N/A", - ["{Date}"] = "N/A" + function update() + mpd_now = { + state = "N/A", + file = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", + date = "N/A" } - -- Get data from MPD server local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh) for line in f:lines() do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do - if k == "state" then mpd_state["{"..k.."}"] = v - elseif k == "file" then mpd_state["{"..k.."}"] = v - elseif k == "Artist" then mpd_state["{"..k.."}"] = awful.util.escape(v) - elseif k == "Title" then mpd_state["{"..k.."}"] = awful.util.escape(v) - elseif k == "Album" then mpd_state["{"..k.."}"] = awful.util.escape(v) - elseif k == "Date" then mpd_state["{"..k.."}"] = awful.util.escape(v) + if k == "state" then mpd_now.state = v + elseif k == "file" then mpd_now.file = v + elseif k == "Artist" then mpd_now.artist = util.escape(v) + elseif k == "Title" then mpd_now.title = util.escape(v) + elseif k == "Album" then mpd_now.album = util.escape(v) + elseif k == "Date" then mpd_now.date = util.escape(v) end end end f:close() - if mpd_state["{state}"] == "play" + notification_preset = { + title = "Now playing", + text = mpd_now.artist .. " (" .. + mpd_now.album .. ") - " .. + mpd_now.date .. "\n" .. + mpd_now.title, + fg = beautiful.fg_normal or "#FFFFFF", + bg = beautiful.bg_normal or "#000000", + timeout = 6 + } + + settings() + + if mpd_now.state == "play" then - if mpd_state["{Title}"] ~= helpers.get_map("current mpd track") + if mpd_now.title ~= helpers.get_map("current mpd track") then - helpers.set_map("current mpd track", mpd_state["{Title}"]) + helpers.set_map("current mpd track", mpd_now.title) + os.execute(mpdcover .. " '" .. music_dir .. "' '" - .. mpd_state["{file}"] .. "'") + .. mpd_now.file .. "'") + mpd.id = naughty.notify({ - title = "Now playing", - text = mpd_state["{Artist}"] .. " (" .. - mpd_state["{Album}"] .. ") - " .. - mpd_state["{Date}"] .. "\n" .. - mpd_state["{Title}"], + preset = notification_preset, icon = "/tmp/mpdcover.png", - fg = color, - timeout = 6, replaces_id = mpd.id }).id end - mympd:set_markup(markup(header_color, mpd_state["{Artist}"]) - .. spr .. - markup(color, mpd_state["{Title}"]) .. footer) - elseif mpd_state["{state}"] == "pause" + elseif mpd_now.state ~= "pause" then - mympd:set_markup(markup(header_color, "mpd") - .. spr .. - markup(color, "paused") .. footer) - else helpers.set_map("current mpd track", nil) - set_nompd() end end - local mympdtimer = timer({ timeout = refresh_timeout }) - mympdtimer:connect_signal("timeout", mympdupdate) - mympdtimer:start() - mympdtimer:emit_signal("timeout") + helpers.newtimer("mpd", timeout, update) - mympd:buttons(awful.util.table.join( - awful.button({}, 0, - function() - helpers.run_in_terminal(app) - end) - )) + output = { widget = widget, notify = update } - local mpd_out = { widget = mympd, notify = mympdupdate } - - return setmetatable(mpd_out, { __index = mpd_out.widget }) + return setmetatable(output, { __index = output.widget }) end return setmetatable(mpd, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/net.lua b/widgets/net.lua index 18727f1..f05235b 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -7,33 +7,24 @@ --]] -local markup = require("lain.util.markup") local helpers = require("lain.helpers") -local awful = require("awful") -local beautiful = require("beautiful") +local notify_fg = require("beautiful").fg_focus +local naughty = require("naughty") local wibox = require("wibox") local io = io local tostring = tostring -local string = { format = string.format } +local string = { format = string.format, + gsub = string.gsub } local setmetatable = setmetatable -- Network infos -- lain.widgets.net local net = { - send = "0", - recv = "0", - last_t = {}, - last_r = {} -} - -net.units = { - ["b"] = 1, - ["kb"] = 1024, - ["mb"] = 1024^2, - ["gb"] = 1024^3 + last_t = 0, + last_r = 0 } function net.get_device() @@ -51,103 +42,61 @@ end function worker(args) local args = args or {} local iface = args.iface or net.get_device() - local delta = args.refresh_timeout or 2 - local units = args.units or net.units["kb"] - local spr = args.spr or " " - local header = args.header or iface - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color_up = args.color_up or beautiful.fg_focus or "#FFFFFF" - local color_down = args.color_down or beautiful.fg_focus or "#FFFFFF" - local app = args.app or "sudo wifi-menu" + local units = args.units or 1024 --kb + local timeout = args.timeout or 2 + local settings = args.settings or function() end + + widget = wibox.widget.textbox('') helpers.set_map(iface, true) - helpers.set_map("carrier", 0) - local mynet = wibox.widget.textbox() + function update() + if iface == "" then iface = net.get_device() end - local mynetupdate = function() - if iface == "" then - iface = net.get_device() - header = iface - end - - local carrier = helpers.first_line('/sys/class/net/' .. iface .. - '/carrier') or "" - local state = helpers.first_line('/sys/class/net/' .. iface .. - '/operstate') + carrier = helpers.first_line('/sys/class/net/' .. iface .. + '/carrier') or "0" + state = helpers.first_line('/sys/class/net/' .. iface .. + '/operstate') or "down" local now_t = helpers.first_line('/sys/class/net/' .. iface .. - '/statistics/tx_bytes') + '/statistics/tx_bytes') or 0 local now_r = helpers.first_line('/sys/class/net/' .. iface .. - '/statistics/rx_bytes') - local text = '' .. header .. ' ' + '/statistics/rx_bytes') or 0 + + sent = tostring((now_t - net.last_t) / timeout / units) + sent = string.gsub(string.format('%.1f', sent), ",", ".") + + received = tostring((now_r - net.last_r) / timeout / units) + received = string.gsub(string.format('%.1f', received), ",", ".") + + settings() + + net.last_t = now_t + net.last_r = now_r if carrier ~= "1" then if helpers.get_map(iface) then n_title = iface - if n_title == "" then - n_title = "network" - header = "Net" - end - naughty.notify({ title = n_title, text = "no carrier", - timeout = 7, - position = "top_left", - icon = beautiful.lain_no_net_notify or - helpers.icons_dir .. "no_net.png", - fg = beautiful.fg_focus or "#FFFFFF" }) - - mynet:set_markup(markup(header_color, header) .. markup(color_up, " Off")) + if n_title == "" then n_title = "network" end + naughty.notify({ + title = n_title, + text = "no carrier", + timeout = 7, + position = "top_left", + icon = helpers.icons_dir .. "no_net.png", + fg = notify_fg or "#FFFFFF" + }) helpers.set_map(iface, false) end - return else helpers.set_map(iface, true) end - - if state == 'down' or not now_t or not now_r - then - mynet:set_markup(' ' .. text .. '-' .. ' ') - return - end - - if net.last_t[iface] and net.last_t[iface] - then - net.send = tostring((now_t - net.last_t[iface]) / delta / units) - net.recv = tostring((now_r - net.last_r[iface]) / delta / units) - - text = text - .. '' - .. string.format('%.1f', net.send) - .. '' - .. spr - .. '' - .. string.format('%.1f', net.recv) - .. '' - - mynet:set_markup(' ' .. text .. ' ') - else - mynet:set_markup(' ' .. text .. '-' .. ' ') - end - - net.last_t[iface] = now_t - net.last_r[iface] = now_r end - local mynettimer = timer({ timeout = delta }) - mynettimer:connect_signal("timeout", mynetupdate) - mynettimer:start() - mynettimer:emit_signal("timeout") + helpers.newtimer(iface, timeout, update) - mynet:buttons(awful.util.table.join( - awful.button({}, 0, function() - helpers.run_in_terminal(app) - mynetupdate() - end))) - - net.widget = mynet - - return setmetatable(net, { __index = net.widget }) + return widget end return setmetatable(net, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/sysload.lua b/widgets/sysload.lua index eb06828..6167d82 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -7,11 +7,8 @@ --]] -local markup = require("lain.util.markup") -local helpers = require("lain.helpers") +local newtimer = require("lain.helpers").newtimer -local awful = require("awful") -local beautiful = require("beautiful") local wibox = require("wibox") local io = io @@ -26,45 +23,24 @@ local sysload = {} function worker(args) local args = args or {} - local refresh_timeout = args.refresh_timeout or 5 - local show_all = args.show_all or false - local header = args.header or " Load " - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or "#FFFFFF" - local app = args.app or "top" + local timeout = args.timeout or 5 + local settings = args.settings or function() end - local mysysload = wibox.widget.textbox() + widget = wibox.widget.textbox('') - local mysysloadupdate = function() + function update() local f = io.open("/proc/loadavg") local ret = f:read("*all") f:close() + + a, b, c = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") - if show_all - then - local a, b, c = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") - mysysload:set_text(string.format("%s %s %s", a, b, c)) - else - local a = string.match(ret, "([^%s]+) ") - mysysload:set_text(string.format("%s", a)) - end - mysysload:set_markup(markup(header_color, header) .. - markup(color, mysysload._layout.text .. " ")) + settings() end - local mysysloadtimer = timer({ timeout = refresh_timeout }) - mysysloadtimer:connect_signal("timeout", mysysloadupdate) - mysysloadtimer:start() - mysysloadtimer:emit_signal("timeout") + newtimer("sysload", timeout, update) - mysysload:buttons(awful.util.table.join( - awful.button({}, 0, - function() - helpers.run_in_terminal(app) - end) - )) - - return mysysload + return widget end return setmetatable(sysload, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/temp.lua b/widgets/temp.lua index 301bc1c..5b1ebf5 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -6,9 +6,8 @@ --]] -local markup = require("lain.util.markup") +local newtimer = require("lain.helpers").newtimer -local beautiful = require("beautiful") local wibox = require("wibox") local io = io @@ -21,32 +20,22 @@ local setmetatable = setmetatable local temp = {} function worker(args) - local args = args or {} - local refresh_timeout = args.refresh_timeout or 5 - local header = args.header or " Temp " - local header_color = args.header_color or beautiful.fg_normal or "#FFFFFF" - local color = args.color or beautiful.fg_focus or header_color - local footer = args.footer or "C " + local args = args or {} + local timeout = args.timeout or 5 + local settings = args.settings or function() end - local mytemp = wibox.widget.textbox() + widget = wibox.widget.textbox('') - local mytempupdate = function() + function update() local f = io.open("/sys/class/thermal/thermal_zone0/temp") - local ret = f:read("*all") + coretemp_now = tonumber(f:read("*all")) / 1000 f:close() - - ret = tonumber(ret) / 1000 - - mytemp:set_markup(markup(header_color, header) .. - markup(color, ret .. footer)) + settings() end - local mytemptimer = timer({ timeout = refresh_timeout }) - mytemptimer:connect_signal("timeout", mytempupdate) - mytemptimer:start() - mytemptimer:emit_signal("timeout") + newtimer("coretemp", timeout, update) - return mytemp + return widget end return setmetatable(temp, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 20c90b1..9bed983 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -6,9 +6,8 @@ --]] -local markup = require("lain.util.markup") +local newtimer = require("lain.helpers").newtimer -local beautiful = require("beautiful") local naughty = require("naughty") local wibox = require("wibox") @@ -28,10 +27,9 @@ local setmetatable = setmetatable -- lain.widgets.yawn local yawn = { - units = "", - forecast = "", - icon = wibox.widget.imagebox(), - widget = wibox.widget.textbox() + icon = wibox.widget.imagebox(), + widget = wibox.widget.textbox(''), + notification_preset = {} } local project_path = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]] @@ -44,33 +42,32 @@ local weather_data = nil local notification = nil local city_id = nil local sky = nil -local settings = {} -local update_timer = nil - -local function fetch_weather(args) - local toshow = args.toshow or "forecast" +local settings = function() end +local function fetch_weather() local url = api_url .. units_set .. city_id local f = io.popen("curl --connect-timeout 1 -fsm 2 '" .. url .. "'" ) local text = f:read("*all") f:close() + -- handle no suitable icon found + yawn.icon:set_image(icon_path .. "na.png") + -- In case of no connection or invalid city ID -- widgets won't display if text == "" or text:match("City not found") then - sky = icon_path .. "na.png" - yawn.icon:set_image(sky) if text == "" then weather_data = "Service not available at the moment." - return "N/A" + yawn.widget:set_text("N/A") else weather_data = "City not found!\n" .. "Are you sure " .. city_id .. " is your Yahoo city ID?" - return "?" + yawn.widget:set_text("?") end + return end -- Processing raw data @@ -88,8 +85,8 @@ local function fetch_weather(args) -- Getting info for text widget local now = weather_data:sub(weather_data:find("Now:")+5, weather_data:find("\n")-1) - local forecast = now:sub(1, now:find(",")-1) - local units = now:sub(now:find(",")+2, -2) + forecast = now:sub(1, now:find(",")-1) + units = now:sub(now:find(",")+2, -2) -- Day/Night icon change local hour = tonumber(os.date("%H")) @@ -110,14 +107,6 @@ local function fetch_weather(args) sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png" - -- In case there's no defined icon for current forecast - f = io.popen(sky) - if f == nil then - sky = icon_path .. "na.png" - else - f:close() - end - -- Localization local f = io.open(localizations_path .. language, "r") if language:find("en_") == nil and f ~= nil @@ -132,21 +121,18 @@ local function fetch_weather(args) end -- Finally setting infos - both = weather_data:match(": %S+.-\n"):gsub(": ", "") + yawn.icon:set_image(sky) + widget = wibox.widget.textbox() + forecast = weather_data:match(": %S+.-,"):gsub(": ", ""):gsub(",", "\n") units = units:gsub(" ", "") + notification_preset = {} + -- anche notification preset, con fg, bg e position - yawn.forecast = markup(yawn.color, " " .. markup.font(beautiful.font, forecast) .. " ") - yawn.units = markup(yawn.color, " " .. markup.font(beautiful.font, units)) - yawn.icon:set_image(sky) + settings() - if toshow == "forecast" then - return yawn.forecast - elseif toshow == "units" then - return yawn.units - else - return both - end + yawn.widget = widget + yawn.notification_preset = notification_preset end function yawn.hide() @@ -159,41 +145,29 @@ end function yawn.show(t_out) if yawn.widget._layout.text == "?" then - if update_timer ~= nil - then - update_timer:emit_signal("timeout") - else - fetch_weather(settings) - end + fetch_weather(settings) end yawn.hide() notification = naughty.notify({ + preset = yawn.notification_preset, text = weather_data, icon = sky, - timeout = t_out, - fg = yawn.color + timeout = t_out }) end function yawn.register(id, args) - local args = args or {} - - settings = args - - yawn.color = args.color or beautiful.fg_normal or "#FFFFFF" + local args = args or {} + local timeout = args.timeout or 600 + settings = args.settings or function() end if args.u == "f" then units_set = '?u=f&w=' end city_id = id - update_timer = timer({ timeout = 600 }) -- 10 mins - update_timer:connect_signal("timeout", function() - yawn.widget:set_markup(fetch_weather(settings)) - end) - update_timer:start() - update_timer:emit_signal("timeout") + newtimer("yawn", timeout, fetch_weather) yawn.icon:connect_signal("mouse::enter", function() yawn.show(0) @@ -202,7 +176,7 @@ function yawn.register(id, args) yawn.hide() end) - return yawn + return { icon = yawn.icon, widget = yawn.widget } end function yawn.attach(widget, id, args) @@ -217,6 +191,4 @@ function yawn.attach(widget, id, args) end) end --- }}} - return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end }) From 701549145d89db1c1d500ff2ffcda66fe843bd30 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 11 Sep 2013 00:10:53 +0200 Subject: [PATCH 012/546] wiki updated --- widgets/fs.lua | 2 +- widgets/net.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/fs.lua b/widgets/fs.lua index f934248..3a36bf3 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -53,8 +53,8 @@ local unit = { ["mb"] = 1024, ["gb"] = 1024^2 } local function worker(args) local args = args or {} - local partition = args.partition or "/" local timeout = args.timeout or 600 + local partition = args.partition or "/" local settings = args.settings or function() end widget = wibox.widget.textbox('') diff --git a/widgets/net.lua b/widgets/net.lua index f05235b..e086c4b 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -41,9 +41,9 @@ end function worker(args) local args = args or {} + local timeout = args.timeout or 2 local iface = args.iface or net.get_device() local units = args.units or 1024 --kb - local timeout = args.timeout or 2 local settings = args.settings or function() end widget = wibox.widget.textbox('') From 0ef82f83e0baaa2936b6204a24ee3b3b638fd409 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 11 Sep 2013 19:39:14 +0200 Subject: [PATCH 013/546] refresh widget fix --- widgets/alsa.lua | 10 +++--- widgets/bat.lua | 13 ++++---- widgets/cpu.lua | 9 +++--- widgets/fs.lua | 33 ++++++++++--------- widgets/imap.lua | 26 +++++++-------- widgets/maildir.lua | 11 ++++--- widgets/mem.lua | 11 ++++--- widgets/mpd.lua | 46 ++++++++++++--------------- widgets/net.lua | 11 ++++--- widgets/sysload.lua | 11 ++++--- widgets/temp.lua | 11 ++++--- widgets/yawn/icons/LightRain.png | 1 + widgets/yawn/init.lua | 54 +++++++++++++++++--------------- 13 files changed, 124 insertions(+), 123 deletions(-) create mode 120000 widgets/yawn/icons/LightRain.png diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 8571ec6..887f398 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -26,9 +26,9 @@ local function worker(args) local channel = args.channel or "Master" local settings = args.settings or function() end - widget = wibox.widget.textbox('') + alsa.widget = wibox.widget.textbox('') - function update() + function alsa.update() local f = io.popen('amixer get ' .. channel) local mixer = f:read("*all") f:close() @@ -56,11 +56,9 @@ local function worker(args) settings() end - newtimer("alsa", timeout, update) + newtimer("alsa", timeout, alsa.update) - output = { widget = widget, notify = update } - - return setmetatable(output, { __index = output.widget }) + return setmetatable(alsa, { __index = alsa.widget }) end return setmetatable(alsa, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/bat.lua b/widgets/bat.lua index 5a811f0..fa61c34 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -20,7 +20,7 @@ local setmetatable = setmetatable -- Battery infos -- lain.widgets.bat -local bat = { id = nil } +local bat = {} local function worker(args) local args = args or {} @@ -28,6 +28,8 @@ local function worker(args) local battery = args.battery or "BAT0" local settings = args.settings or function() end + bat.widget = wibox.widget.textbox('') + bat_now = { status = "not present", perc = "N/A", @@ -35,9 +37,7 @@ local function worker(args) watt = "N/A" } - widget = wibox.widget.textbox('') - - function update() + function bat.update() local present = first_line("/sys/class/power_supply/" .. battery .. "/present") @@ -106,12 +106,13 @@ local function worker(args) bat_now.perc = string.format("%d", bat_now.perc) end + widget = bat.widget settings() end - newtimer("bat", timeout, update) + newtimer("bat", timeout, bat.update) - return widget + return bat.widget end return setmetatable(bat, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/cpu.lua b/widgets/cpu.lua index f9bbe72..f307b26 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -31,9 +31,9 @@ local function worker(args) local timeout = args.timeout or 5 local settings = args.settings or function() end - widget = wibox.widget.textbox('') + cpu.widget = wibox.widget.textbox('') - function update() + function cpu.update() -- Read the amount of time the CPUs have spent performing -- different kinds of work. Read the first line of /proc/stat -- which is the sum of all CPUs. @@ -60,6 +60,7 @@ local function worker(args) usage = tostring(math.ceil((dactive / dtotal) * 100)) + widget = cpu.widget settings() -- Save current data for the next run. @@ -67,9 +68,9 @@ local function worker(args) cpu.last_total = total end - newtimer("cpu", timeout, update) + newtimer("cpu", timeout, cpu.update) - return widget + return cpu.widget end return setmetatable(cpu, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/fs.lua b/widgets/fs.lua index 3a36bf3..b580010 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -24,8 +24,10 @@ local setmetatable = setmetatable -- File system disk space usage -- lain.widgets.fs -local fs = { notification_preset = {} } -local notification = nil +local fs = {} + +local notification = nil +notification_preset = { fg = beautiful.fg_normal } function fs:hide() if notification ~= nil then @@ -42,7 +44,7 @@ function fs:show(t_out) f:close() notification = naughty.notify({ - preset = fs.notification_preset, + preset = notification_preset, text = ws, timeout = t_out }) @@ -57,11 +59,11 @@ local function worker(args) local partition = args.partition or "/" local settings = args.settings or function() end - widget = wibox.widget.textbox('') + fs.widget = wibox.widget.textbox('') helpers.set_map("fs", false) - function update() + function fs.update() fs_info = {} local f = io.popen("LC_ALL=C df -kP") @@ -83,17 +85,14 @@ local function worker(args) -- chosen partition easy stuff -- you can however check whatever partition else - used = fs_info[partition .. " used_p"] - available = fs_info[partition .. " avail_p"] - size_mb = fs_info[partition .. " size_mb"] - size_gb = fs_info[partition .. " size_gb"] - - notification_preset = { fg = beautiful.fg_normal } + used = tonumber(fs_info[partition .. " used_p"]) + available = tonumber(fs_info[partition .. " avail_p"]) + size_mb = tonumber(fs_info[partition .. " size_mb"]) + size_gb = tonumber(fs_info[partition .. " size_gb"]) + widget = fs.widget settings() - fs.notification_preset = notification_preset - if used >= 99 and not helpers.get_map("fs") then naughty.notify({ @@ -109,16 +108,16 @@ local function worker(args) end end - helpers.newtimer("fs " .. partition, timeout, update) + helpers.newtimer(partition, timeout, fs.update) widget:connect_signal('mouse::enter', function () fs:show(0) end) widget:connect_signal('mouse::leave', function () fs:hide() end) output = { - widget = widget, + widget = fs.widget, show = function(t_out) - update() - fs:show(t_out) + fs.update() + fs:show(t_out) end } diff --git a/widgets/imap.lua b/widgets/imap.lua index 2c7067c..9821cb3 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -20,9 +20,9 @@ local setmetatable = setmetatable -- Mail IMAP check -- lain.widgets.imap -local imap = { stored = nil } +local imap = {} -function worker(args) +local function worker(args) local args = args or {} local server = args.server @@ -54,9 +54,15 @@ function worker(args) end end - widget = wibox.widget.textbox('') + imap.widget = wibox.widget.textbox('') - function update() + notification_preset = { + icon = helpers.icons_dir .. "mail.png", + timeout = 8, + position = "top_left" + } + + function imap.update() to_execute = string.format("%s -s %s -u %s -p %s --port %s", checkmail, server, mail, password, port) @@ -88,15 +94,9 @@ function worker(args) end end - notification_preset = { - icon = helpers.icons_dir .. "mail.png", - timeout = 8, - position = "top_left" - } - + widget = imap.widget settings() - if helpers.get_map(mail) and tonumber(mailcount) >= 1 then notify_title = ws:match(mail .. " has %d new message.?") @@ -123,9 +123,9 @@ function worker(args) end end - helpers.newtimer(mail, timeout, update, true) + helpers.newtimer(mail, timeout, imap.update, true) - return widget + return imap.widget end return setmetatable(imap, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/maildir.lua b/widgets/maildir.lua index 00ab771..4ac34bc 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -24,16 +24,16 @@ local setmetatable = setmetatable -- lain.widgets.maildir local maildir = {} -function worker(args) +local function worker(args) local args = args or {} local timeout = args.timeout or 60 local mailpath = args.mailpath or os.getenv("HOME") .. "/Mail" local ignore_boxes = args.ignore_boxes or {} local settings = args.settings or function() end - widget = wibox.widget.textbox('') + maildir.widget = wibox.widget.textbox('') - function update() + function maildir.update() -- Find pathes to mailboxes. local p = io.popen("find " .. mailpath .. " -mindepth 1 -maxdepth 1 -type d" .. @@ -84,12 +84,13 @@ function worker(args) end end + widget = maildir.widget settings() end - newtimer(mailpath, timeout, update, true) + newtimer(mailpath, timeout, maildir.update, true) - return widget + return maildir.widget end return setmetatable(maildir, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/mem.lua b/widgets/mem.lua index d0ff223..f014149 100644 --- a/widgets/mem.lua +++ b/widgets/mem.lua @@ -25,14 +25,14 @@ local setmetatable = setmetatable -- lain.widgets.mem local mem = {} -function worker(args) +local function worker(args) local args = args or {} local timeout = args.timeout or 3 local settings = args.settings or function() end - widget = wibox.widget.textbox('') + mem.widget = wibox.widget.textbox('') - function update() + function mem.update() mem = {} for line in io.lines("/proc/meminfo") do @@ -51,12 +51,13 @@ function worker(args) used = mem.total - (mem.free + mem.buf + mem.cache) swapused = mem.swap - mem.swapf + widget = mem.widget settings() end - newtimer("mem", timeout, update) + newtimer("mem", timeout, mem.update) - return widget + return mem.widget end return setmetatable(mem, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 8ba1cde..016f2a3 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -10,24 +10,24 @@ local helpers = require("lain.helpers") local util = require("awful.util") -local beautiful = require("beautiful") local naughty = require("naughty") local wibox = require("wibox") -local io = io +local io = { popen = io.popen } local os = { execute = os.execute, getenv = os.getenv } -local string = { gmatch = string.gmatch } +local string = { format = string.format, + gmatch = string.gmatch } local setmetatable = setmetatable -- MPD infos -- lain.widgets.mpd -local mpd = { id = nil } +local mpd = {} -function worker(args) +local function worker(args) local args = args or {} - local timeout = args.timeout or 1 + local timeout = args.timeout or 2 local password = args.password or "" local host = args.host or "127.0.0.1" local port = args.port or "6600" @@ -38,11 +38,16 @@ function worker(args) local mpdh = "telnet://" .. host .. ":" .. port local echo = "echo 'password " .. password .. "\nstatus\ncurrentsong\nclose'" - widget = wibox.widget.textbox('') + mpd.widget = wibox.widget.textbox('') + + notification_preset = { + title = "Now playing", + timeout = 6 + } helpers.set_map("current mpd track", nil) - function update() + function mpd.update() mpd_now = { state = "N/A", file = "N/A", @@ -52,7 +57,7 @@ function worker(args) date = "N/A" } - local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh) + local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 1 " .. mpdh) for line in f:lines() do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do @@ -68,17 +73,9 @@ function worker(args) f:close() - notification_preset = { - title = "Now playing", - text = mpd_now.artist .. " (" .. - mpd_now.album .. ") - " .. - mpd_now.date .. "\n" .. - mpd_now.title, - fg = beautiful.fg_normal or "#FFFFFF", - bg = beautiful.bg_normal or "#000000", - timeout = 6 - } - + notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist, + mpd_now.album, mpd_now.date, mpd_now.title) + widget = mpd.widget settings() if mpd_now.state == "play" @@ -87,8 +84,7 @@ function worker(args) then helpers.set_map("current mpd track", mpd_now.title) - os.execute(mpdcover .. " '" .. music_dir .. "' '" - .. mpd_now.file .. "'") + os.execute(string.format("%s %q %q", mpdcover, music_dir, mpd_now.file)) mpd.id = naughty.notify({ preset = notification_preset, @@ -102,11 +98,9 @@ function worker(args) end end - helpers.newtimer("mpd", timeout, update) + helpers.newtimer("mpd", timeout, mpd.update) - output = { widget = widget, notify = update } - - return setmetatable(output, { __index = output.widget }) + return setmetatable(mpd, { __index = mpd.widget }) end return setmetatable(mpd, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/net.lua b/widgets/net.lua index e086c4b..d692df1 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -39,18 +39,18 @@ function net.get_device() end end -function worker(args) +local function worker(args) local args = args or {} local timeout = args.timeout or 2 local iface = args.iface or net.get_device() local units = args.units or 1024 --kb local settings = args.settings or function() end - widget = wibox.widget.textbox('') + net.widget = wibox.widget.textbox('') helpers.set_map(iface, true) - function update() + function net.update() if iface == "" then iface = net.get_device() end carrier = helpers.first_line('/sys/class/net/' .. iface .. @@ -68,6 +68,7 @@ function worker(args) received = tostring((now_r - net.last_r) / timeout / units) received = string.gsub(string.format('%.1f', received), ",", ".") + widget = net.widget settings() net.last_t = now_t @@ -94,9 +95,9 @@ function worker(args) end end - helpers.newtimer(iface, timeout, update) + helpers.newtimer(iface, timeout, net.update) - return widget + return net.widget end return setmetatable(net, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/sysload.lua b/widgets/sysload.lua index 6167d82..90bdedf 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -21,26 +21,27 @@ local setmetatable = setmetatable -- lain.widgets.sysload local sysload = {} -function worker(args) +local function worker(args) local args = args or {} local timeout = args.timeout or 5 local settings = args.settings or function() end - widget = wibox.widget.textbox('') + sysload.widget = wibox.widget.textbox('') - function update() + function sysload.update() local f = io.open("/proc/loadavg") local ret = f:read("*all") f:close() a, b, c = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") + widget = sysload.widget settings() end - newtimer("sysload", timeout, update) + newtimer("sysload", timeout, sysload.update) - return widget + return sysload.widget end return setmetatable(sysload, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/temp.lua b/widgets/temp.lua index 5b1ebf5..e568138 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -19,23 +19,24 @@ local setmetatable = setmetatable -- lain.widgets.temp local temp = {} -function worker(args) +local function worker(args) local args = args or {} local timeout = args.timeout or 5 local settings = args.settings or function() end - widget = wibox.widget.textbox('') + temp.widget = wibox.widget.textbox('') - function update() + function temp.update() local f = io.open("/sys/class/thermal/thermal_zone0/temp") coretemp_now = tonumber(f:read("*all")) / 1000 f:close() + widget = temp.widget settings() end - newtimer("coretemp", timeout, update) + newtimer("coretemp", timeout, temp.update) - return widget + return temp.widget end return setmetatable(temp, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/yawn/icons/LightRain.png b/widgets/yawn/icons/LightRain.png new file mode 120000 index 0000000..df34463 --- /dev/null +++ b/widgets/yawn/icons/LightRain.png @@ -0,0 +1 @@ +Rain.png \ No newline at end of file diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 9bed983..e0e6f68 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -27,33 +27,31 @@ local setmetatable = setmetatable -- lain.widgets.yawn local yawn = { - icon = wibox.widget.imagebox(), - widget = wibox.widget.textbox(''), - notification_preset = {} + icon = wibox.widget.imagebox(), + widget = wibox.widget.textbox('') } -local project_path = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]] -local localizations_path = project_path .. 'localizations/' -local icon_path = project_path .. 'icons/' -local api_url = 'http://weather.yahooapis.com/forecastrss' -local units_set = '?u=c&w=' -- Default is Celsius -local language = string.match(os.getenv("LANG"), "(%S*$*)[.]") -local weather_data = nil -local notification = nil -local city_id = nil -local sky = nil -local settings = function() end +local project_path = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]] +local localizations_path = project_path .. 'localizations/' +local icon_path = project_path .. 'icons/' +local api_url = 'http://weather.yahooapis.com/forecastrss' +local units_set = '?u=c&w=' -- Default is Celsius +local language = string.match(os.getenv("LANG"), "(%S*$*)[.]") +local weather_data = nil +local notification = nil +local city_id = nil +local sky = nil +local settings = function() end + +notification_preset = {} local function fetch_weather() local url = api_url .. units_set .. city_id - local f = io.popen("curl --connect-timeout 1 -fsm 2 '" + local f = io.popen("curl --connect-timeout 1 -fsm 1 '" .. url .. "'" ) local text = f:read("*all") f:close() - -- handle no suitable icon found - yawn.icon:set_image(icon_path .. "na.png") - -- In case of no connection or invalid city ID -- widgets won't display if text == "" or text:match("City not found") @@ -107,6 +105,14 @@ local function fetch_weather() sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png" + -- In case there's no defined icon for current forecast + f = io.popen(sky) + if f == nil then + sky = icon_path .. "na.png" + else + io.close(f) + end + -- Localization local f = io.open(localizations_path .. language, "r") if language:find("en_") == nil and f ~= nil @@ -122,17 +128,13 @@ local function fetch_weather() -- Finally setting infos yawn.icon:set_image(sky) - widget = wibox.widget.textbox() + widget = yawn.widget forecast = weather_data:match(": %S+.-,"):gsub(": ", ""):gsub(",", "\n") units = units:gsub(" ", "") - notification_preset = {} - -- anche notification preset, con fg, bg e position + -- notification_preset = {} settings() - - yawn.widget = widget - yawn.notification_preset = notification_preset end function yawn.hide() @@ -151,7 +153,7 @@ function yawn.show(t_out) yawn.hide() notification = naughty.notify({ - preset = yawn.notification_preset, + preset = notification_preset, text = weather_data, icon = sky, timeout = t_out @@ -176,7 +178,7 @@ function yawn.register(id, args) yawn.hide() end) - return { icon = yawn.icon, widget = yawn.widget } + return yawn end function yawn.attach(widget, id, args) From 19dab60db9058b1da121e20199693d42896aacbf Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 11 Sep 2013 19:46:52 +0200 Subject: [PATCH 014/546] readme updated --- README.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 6ce1c47..cbad31c 100644 --- a/README.rst +++ b/README.rst @@ -10,8 +10,10 @@ Layouts, widgets and utilities for Awesome WM :License: GNU-GPLv2_ :Source: https://github.com/copycat-killer/lain -Successor of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve Awesome usability and -configurability. +Successor of awesome-vain_, this costantly evolving module +provides new layouts, a set of widgets and utility functions +in order to improve [Awesome](http://awesome.naquadah.org/) +usability and configurability. Read the wiki_ for all the info. From 9ef9727ccd2e3c950bb41de1e9a27dbe145d3af2 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 11 Sep 2013 19:54:54 +0200 Subject: [PATCH 015/546] readme updated --- README.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.rst b/README.rst index cbad31c..dcd0d93 100644 --- a/README.rst +++ b/README.rst @@ -10,6 +10,9 @@ Layouts, widgets and utilities for Awesome WM :License: GNU-GPLv2_ :Source: https://github.com/copycat-killer/lain +Description +----------- + Successor of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions in order to improve [Awesome](http://awesome.naquadah.org/) From b032f2241f4d5c604acdc7835109fa1cec8c81fa Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 11 Sep 2013 19:56:06 +0200 Subject: [PATCH 016/546] readme updated --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index dcd0d93..779428d 100644 --- a/README.rst +++ b/README.rst @@ -15,8 +15,7 @@ Description Successor of awesome-vain_, this costantly evolving module provides new layouts, a set of widgets and utility functions -in order to improve [Awesome](http://awesome.naquadah.org/) -usability and configurability. +in order to improve Awesome_ usability and configurability. Read the wiki_ for all the info. @@ -29,4 +28,5 @@ Screenshots .. _GNU-GPLv2: http://www.gnu.org/licenses/gpl-2.0.html .. _awesome-vain: https://github.com/vain/awesome-vain +.. _Awesome: http://awesome.naquadah.org/ .. _wiki: https://github.com/copycat-killer/lain/wiki From 5cde79f1c242afeb6cf748ddcba9e7582787c79d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 12 Sep 2013 02:26:48 +0200 Subject: [PATCH 017/546] new imap widget --- scripts/checkmail | 104 ------------------ widgets/bat.lua | 14 +-- widgets/imap.lua | 101 +++++------------ widgets/yawn/icons/ThunderintheVicinity.png | 1 + widgets/yawn/init.lua | 1 - widgets/yawn/localizations/it_IT | 1 + .../yawn/localizations/localization_template | 1 + 7 files changed, 38 insertions(+), 185 deletions(-) delete mode 100755 scripts/checkmail create mode 120000 widgets/yawn/icons/ThunderintheVicinity.png diff --git a/scripts/checkmail b/scripts/checkmail deleted file mode 100755 index 67c5206..0000000 --- a/scripts/checkmail +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/python - -# Simple email checker -# -# Wrote by copycat-killer on a rainy day of august 2013 -# to be used in Lain. -# -# https://github.com/copycat-killer/lain - -import sys, getopt, locale, imaplib - -def main(argv): - usage = "usage: checkmail -s -u -p [--port ] [--encoding ] [--cut]" - server = "" - user = "" - password = "" - port = 993 - cut = False - encoding = locale.getdefaultlocale()[1] - output = "" - - try: - opts, args = getopt.getopt(argv, "hs:u:p:", ["port=", "encoding=", "cut"]) - except getopt.GetoptError: - print(usage) - sys.exit(2) - - if len(argv) == 0: - print(usage) - sys.exit() - - for opt, arg in opts: - if opt == "-h": - print(usage) - sys.exit() - elif opt == "-s": - server = arg - elif opt == "-u": - user = arg - elif opt == "-p": - password = arg - elif opt == "--port": - port = int(arg) - elif opt == "--cut": - cut = True - elif opt == "--encoding": - encoding = arg - - try: - mail = imaplib.IMAP4_SSL(server, port) - mail.login(user, password) - except imaplib.IMAP4.error: - print("CheckMailError: invalid credentials") - sys.exit(2) - - status, counts = mail.status("Inbox","(MESSAGES UNSEEN)") - - unread = int(counts[0].split()[4][:-1]) - - if status == "OK" and unread: - mail.select("Inbox", readonly = 1) - ret, messages = mail.uid("search", None, "(UNSEEN)") - - if ret == "OK": - latest_email_uid = messages[0].split()[-1] - - ret_header, new_mail_header = mail.uid("fetch", latest_email_uid, - "(BODY.PEEK[HEADER.FIELDS (SUBJECT FROM)])") - ret_text, new_mail_text = mail.uid("fetch", latest_email_uid, "(BODY[TEXT])") - - if ret_header == "OK" and ret_text == "OK": - try: # not all the servers like this, that's why we try - mail.store(latest_email_uid, "-FLAGS", "\\Seen") - except imaplib.IMAP4.error: - # this simply means the server refused to - # toggle Seen flag from mail - print("[+Seen]\n") - - nm_header = new_mail_header[0][1].decode(encoding, "replace").strip() - nm_text = new_mail_text[0][1].decode(encoding, "replace").strip() - - if unread == 1: - print(user, "has 1 new message\n") - else: - print(user, "has", unread, "new messages\n") - nm_header.replace("From:", "Latest from:", 1) - - print(nm_header, "\n") - - if cut: - if len(nm_text) <= 100: - print(nm_text) - else: - print(nm_text[0:100]) - print("[...]") - else: - print(nm_text) - else: - print("No new messages") - - mail.logout() - -if __name__ == "__main__": - main(sys.argv[1:]) diff --git a/widgets/bat.lua b/widgets/bat.lua index fa61c34..ba1fa58 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -30,14 +30,14 @@ local function worker(args) bat.widget = wibox.widget.textbox('') - bat_now = { - status = "not present", - perc = "N/A", - time = "N/A", - watt = "N/A" - } - function bat.update() + bat_now = { + status = "not present", + perc = "N/A", + time = "N/A", + watt = "N/A" + } + local present = first_line("/sys/class/power_supply/" .. battery .. "/present") diff --git a/widgets/imap.lua b/widgets/imap.lua index 9821cb3..4df3610 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -11,10 +11,9 @@ local helpers = require("lain.helpers") local naughty = require("naughty") local wibox = require("wibox") -local io = { popen = io.popen } -local tonumber = tonumber -local string = { len = string.len, - format = string.format } +local io = { popen = io.popen } +local string = { format = string.format, + gsub = string.gsub } local setmetatable = setmetatable @@ -29,102 +28,58 @@ local function worker(args) local mail = args.mail local password = args.password - local port = args.port or "993" + local port = args.port or 993 local timeout = args.timeout or 60 - local encoding = args.encoding or nil - local maxlen = args.maxlen or 200 local is_plain = args.is_plain or false local settings = args.settings or function() end - local checkmail = helpers.scripts_dir .. "checkmail" + local head_command = "curl --connect-timeout 1 -fsm 3" + local request = "-X 'SEARCH (UNSEEN)'" - helpers.set_map(mail, true) - helpers.set_map(mail .. " count", "0") + helpers.set_map(mail, 0) if not is_plain then - if not imap.stored - then - local f = io.popen(password) - password = f:read("*all"):gsub("\n", ""):gsub("\r", "") - f:close() - imap.stored = password - else - password = imap.stored - end + local f = io.popen(password) + password = f:read("*all"):gsub("\n", "") + f:close() end imap.widget = wibox.widget.textbox('') - notification_preset = { - icon = helpers.icons_dir .. "mail.png", - timeout = 8, - position = "top_left" - } - function imap.update() - to_execute = string.format("%s -s %s -u %s -p %s --port %s", - checkmail, server, mail, password, port) + notification_preset = { + icon = helpers.icons_dir .. "mail.png", + position = "top_left" + } + + curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%s %s -k", + head_command, server, port, mail, password, request) - if encoding ~= nil - then - to_execute = string.format("%s --encoding %s", - to_execute, encoding) - end - - f = io.popen(to_execute) + f = io.popen(curl) ws = f:read("*all") f:close() - mailcount = "0" - - if ws:find("No new messages") ~= nil - then - helpers.set_map(mail, true) - elseif ws:find("CheckMailError: invalid credentials") ~= nil - then - helpers.set_map(mail, true) - mailcount = "invalid credentials" - else - mailcount = ws:match("%d") or "0" - if helpers.get_map(mail .. " count") ~= mailcount and mailcount ~= "0" - then - helpers.set_map(mail, true) - helpers.set_map(mail .. " count", mailcount) - end - end + t, mailcount = string.gsub(ws, "%d", "") + t = nil -- because it's useless widget = imap.widget settings() - if helpers.get_map(mail) and tonumber(mailcount) >= 1 + if mailcount > helpers.get_map(mail) and mailcount >= 1 then - notify_title = ws:match(mail .. " has %d new message.?") - ws = ws:gsub(notify_title, "", 1):gsub("\n", "", 2) - - -- trying to remove useless infos - ws = ws:gsub("--Content.%S+.-\n", "") - ws = ws:gsub("--%d+.-\n", "") - - if string.len(ws) > maxlen - then - ws = ws:sub(1, maxlen) .. "[...]" + if mailcount == 1 then + nt = mail .. " has one new message" + else + nt = mail .. " has " .. mailcount .. " new messages" end - - notify_title = notify_title:gsub("\n", "") - - naughty.notify({ - preset = notification_preset, - title = notify_title, - text = ws - }) - - helpers.set_map(mail, false) + naughty.notify({ preset = notification_preset, text = nt }) end + + helpers.set_map(mail, mailcount) end helpers.newtimer(mail, timeout, imap.update, true) - return imap.widget end diff --git a/widgets/yawn/icons/ThunderintheVicinity.png b/widgets/yawn/icons/ThunderintheVicinity.png new file mode 120000 index 0000000..1fb3b9c --- /dev/null +++ b/widgets/yawn/icons/ThunderintheVicinity.png @@ -0,0 +1 @@ +Cloudy.png \ No newline at end of file diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index e0e6f68..4d14966 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -132,7 +132,6 @@ local function fetch_weather() forecast = weather_data:match(": %S+.-,"):gsub(": ", ""):gsub(",", "\n") units = units:gsub(" ", "") - -- notification_preset = {} settings() end diff --git a/widgets/yawn/localizations/it_IT b/widgets/yawn/localizations/it_IT index 0b74b60..6435eff 100644 --- a/widgets/yawn/localizations/it_IT +++ b/widgets/yawn/localizations/it_IT @@ -14,6 +14,7 @@ Isolated Thunderstorms|Temporali Isolati Scattered Thunderstorms|Temporali Sparsi Thundershowers|Rovesci Temporaleschi Thunderstorms|Temporali +Thunder in the Vicinity|Temporale In Arrivo Thunder|Temporale AM|In Mattinata PM|Nel Pomeriggio diff --git a/widgets/yawn/localizations/localization_template b/widgets/yawn/localizations/localization_template index 98d527d..fd28868 100644 --- a/widgets/yawn/localizations/localization_template +++ b/widgets/yawn/localizations/localization_template @@ -14,6 +14,7 @@ Isolated Thunderstorms| Scattered Thunderstorms| Thundershowers| Thunderstorms| +Thunder in the Vicinity| Thunder| AM| PM| From bc574619fe7a9dd077d8fe6f972f1763b6936df0 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 12 Sep 2013 17:18:08 +0200 Subject: [PATCH 018/546] small fixes --- init.lua | 3 +- widgets/alsabar.lua | 99 ++++++++++++++++---------------- widgets/yawn/localizations/it_IT | 2 +- 3 files changed, 53 insertions(+), 51 deletions(-) diff --git a/init.lua b/init.lua index 3abf9f6..155d6cc 100644 --- a/init.lua +++ b/init.lua @@ -5,8 +5,7 @@ Layouts, widgets and utilities for Awesome WM Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann + * (c) 2013, Luke Bonham --]] diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 7f5fe87..8331c54 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -4,6 +4,7 @@ Licensed under GNU General Public License v2 * (c) 2013, Luke Bonham * (c) 2013, Rman + --]] local newtimer = require("lain.helpers").newtimer @@ -12,10 +13,11 @@ local awful = require("awful") local beautiful = require("beautiful") local naughty = require("naughty") -local io = io -local math = { modf = math.modf } -local string = { match = string.match, - rep = string.rep } +local io = { popen = io.popen } +local math = { modf = math.modf } +local string = { format = string.format, + match = string.match, + rep = string.rep } local tonumber = tonumber local setmetatable = setmetatable @@ -25,64 +27,77 @@ local setmetatable = setmetatable local alsabar = { channel = "Master", - step = "5%", + step = "5%", colors = { background = beautiful.bg_normal, - mute = "#EB8F8F", - unmute = "#A4CE8A" + mute = "#EB8F8F", + unmute = "#A4CE8A" }, terminal = terminal or "xterm", - mixer = terminal .. " -e alsamixer", + mixer = terminal .. " -e alsamixer", notifications = { - font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), + font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), font_size = "11", - color = beautiful.fg_focus, - bar_size = 18 -- Awesome default + color = beautiful.fg_focus, + bar_size = 18 }, _current_level = 0, - _muted = false + _muted = false } -function alsabar:notify() +function alsabar.notify() + alsabar.update() + local preset = { - title = "", text = "", - timeout = 15, - font = alsabar.notifications.font .. " " .. alsabar.notifications.font_size, - fg = alsabar.notifications.color + title = "", + text = "", + timeout = 4, + font = alsabar.notifications.font .. " " .. + alsabar.notifications.font_size, + fg = alsabar.notifications.color } - if alsabar._muted then + if alsabar._muted + then preset.title = alsabar.channel .. " - Muted" else preset.title = alsabar.channel .. " - " .. alsabar._current_level * 100 .. "%" end - local int = math.modf(alsabar._current_level * alsabar.notifications.bar_size) - preset.text = "[" .. string.rep("|", int) - .. string.rep(" ", alsabar.notifications.bar_size - int) .. "]" + int = math.modf(alsabar._current_level * alsabar.notifications.bar_size) + preset.text = "[" + .. string.rep("|", int) + .. string.rep(" ", alsabar.notifications.bar_size - int) + .. "]" if alsabar._notify ~= nil then - alsabar._notify = naughty.notify ({ replaces_id = alsabar._notify.id, - preset = preset }) + alsabar._notify = naughty.notify ({ + replaces_id = alsabar._notify.id, + preset = preset + }) else - alsabar._notify = naughty.notify ({ preset = preset }) + alsabar._notify = naughty.notify ({ + preset = preset + }) end end local function worker(args) local args = args or {} + local timeout = args.timeout or 4 local width = args.width or 63 local height = args.heigth or 1 local ticks = args.ticks or true local ticks_size = args.ticks_size or 7 local vertical = args.vertical or false + alsabar.channel = args.channel or alsabar.channel alsabar.step = args.step or alsabar.step alsabar.colors = args.colors or alsabar.colors @@ -98,11 +113,9 @@ local function worker(args) alsabar.bar:set_ticks(ticks) alsabar.bar:set_ticks_size(ticks_size) - if vertical then - alsabar.bar:set_vertical(true) - end + if vertical then alsabar.bar:set_vertical(true) end - function update() + function alsabar.update() -- Get mixer control contents local f = io.popen("amixer get " .. alsabar.channel) local mixer = f:read("*all") @@ -119,49 +132,39 @@ local function worker(args) alsabar._current_level = tonumber(volu) / 100 alsabar.bar:set_value(alsabar._current_level) - if mute == "" and volu == "0" or mute == "off" + if not mute and tonumber(volu) == 0 or mute == "off" then alsabar._muted = true alsabar.tooltip:set_text (" [Muted] ") alsabar.bar:set_color(alsabar.colors.mute) else alsabar._muted = false - alsabar.tooltip:set_text(" " .. alsabar.channel .. ": " .. volu .. "% ") + alsabar.tooltip:set_text(string.format(" %s:%s ", alsabar.channel, volu)) alsabar.bar:set_color(alsabar.colors.unmute) end end - newtimer("alsabar", 5, update) + newtimer("alsabar", timeout, alsabar.update) alsabar.bar:buttons (awful.util.table.join ( awful.button ({}, 1, function() awful.util.spawn(alsabar.mixer) end), awful.button ({}, 3, function() - awful.util.spawn("amixer sset " .. alsabar.channel .. " toggle") - myvolumebarupdate() + awful.util.spawn(string.format("amixer set %s toggle", alsabar.channel)) + alsabar.update() end), awful.button ({}, 4, function() - awful.util.spawn("amixer sset " .. alsabar.channel .. " " - .. alsabar.step .. "+") - myvolumebarupdate() + awful.util.spawn(string.format("amixer set %s %s+", alsabar.channel, alsabar.step)) + alsabar.update() end), awful.button ({}, 5, function() - awful.util.spawn("amixer sset " .. alsabar.channel .. " " - .. alsabar.step .. "-") - myvolumebarupdate() + awful.util.spawn(string.format("amixer set %s %s-", alsabar.channel, alsabar.step)) + alsabar.update() end) )) - return { - widget = alsabar.bar, - channel = alsabar.channel, - step = alsabar.step, - notify = function() - update() - alsabar.notify() - end - } + return alsabar end return setmetatable(alsabar, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/yawn/localizations/it_IT b/widgets/yawn/localizations/it_IT index 6435eff..2276e4b 100644 --- a/widgets/yawn/localizations/it_IT +++ b/widgets/yawn/localizations/it_IT @@ -14,7 +14,7 @@ Isolated Thunderstorms|Temporali Isolati Scattered Thunderstorms|Temporali Sparsi Thundershowers|Rovesci Temporaleschi Thunderstorms|Temporali -Thunder in the Vicinity|Temporale In Arrivo +Thunder in the Vicinity|Tuoni in avvicinamento Thunder|Temporale AM|In Mattinata PM|Nel Pomeriggio From 4bde4b5eea6ad1352078228c0d146f41b4c893e4 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 13 Sep 2013 00:07:44 +0200 Subject: [PATCH 019/546] widgets fix --- helpers.lua | 6 ++++-- widgets/alsa.lua | 21 +++++++++++---------- widgets/bat.lua | 6 +++--- widgets/calendar.lua | 20 ++++++++++---------- widgets/cpu.lua | 4 ++-- widgets/fs.lua | 18 +++++------------- widgets/imap.lua | 8 ++++---- widgets/maildir.lua | 5 ++--- widgets/mem.lua | 34 ++++++++++++++++------------------ widgets/mpd.lua | 8 ++++---- widgets/net.lua | 21 +++++++++++---------- widgets/sysload.lua | 7 +++---- widgets/temp.lua | 5 ++--- widgets/yawn/init.lua | 5 +++-- 14 files changed, 80 insertions(+), 88 deletions(-) diff --git a/helpers.lua b/helpers.lua index a8c4cd7..81910d2 100644 --- a/helpers.lua +++ b/helpers.lua @@ -8,8 +8,10 @@ --]] local debug = require("debug") -local rawget = rawget + +local capi = { timer = timer } local io = { open = io.open } +local rawget = rawget -- Lain helper functions for internal use -- lain.helpers @@ -49,7 +51,7 @@ end helpers.timer_table = {} function helpers.newtimer(name, timeout, fun, nostart) - helpers.timer_table[name] = timer({ timeout = timeout }) + helpers.timer_table[name] = capi.timer({ timeout = timeout }) helpers.timer_table[name]:connect_signal("timeout", fun) helpers.timer_table[name]:start() if not nostart then diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 887f398..3e025bb 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -29,30 +29,31 @@ local function worker(args) alsa.widget = wibox.widget.textbox('') function alsa.update() - local f = io.popen('amixer get ' .. channel) + local f = assert(io.popen('amixer get ' .. channel)) local mixer = f:read("*all") f:close() - volume = {} + volume_now = {} - volume.level, volume.status = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + volume_now.level, volume_now.status = string.match(mixer, "([%d]+)%%.*%[([%l]*)") - if volume.level == nil + if volume_now.level == nil then - volume.level = 0 - volume.status = "off" + volume_now.level = "0" + volume_now.status = "off" end - if volume.status == "" + if volume_now.status == "" then - if volume.level == 0 + if volume_now.level == "0" then - volume.status = "off" + volume_now.status = "off" else - volume.status = "on" + volume_now.status = "on" end end + widget = alsa.widget settings() end diff --git a/widgets/bat.lua b/widgets/bat.lua index ba1fa58..09b135f 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -30,9 +30,9 @@ local function worker(args) bat.widget = wibox.widget.textbox('') - function bat.update() + function update() bat_now = { - status = "not present", + status = "Not present", perc = "N/A", time = "N/A", watt = "N/A" @@ -110,7 +110,7 @@ local function worker(args) settings() end - newtimer("bat", timeout, bat.update) + newtimer("bat", timeout, update) return bat.widget end diff --git a/widgets/calendar.lua b/widgets/calendar.lua index e28e735..57fadd9 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -21,12 +21,12 @@ local setmetatable = setmetatable -- Calendar notification -- lain.widgets.calendar local calendar = {} -local notification = nil +local cal_notification = nil function calendar:hide() - if notification ~= nil then - naughty.destroy(notification) - notification = nil + if cal_notification ~= nil then + naughty.destroy(cal_notification) + cal_notification = nil end end @@ -95,12 +95,12 @@ function calendar:show(t_out, inc_offset) .. "" f:close() - notification = naughty.notify({ text = c_text, - icon = calendar.notify_icon, - position = calendar.position, - fg = calendar.fg, - bg = calendar.bg, - timeout = tims }) + cal_notification = naughty.notify({ text = c_text, + icon = calendar.notify_icon, + position = calendar.position, + fg = calendar.fg, + bg = calendar.bg, + timeout = tims }) end function calendar:attach(widget, args) diff --git a/widgets/cpu.lua b/widgets/cpu.lua index f307b26..55a3799 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -33,7 +33,7 @@ local function worker(args) cpu.widget = wibox.widget.textbox('') - function cpu.update() + function update() -- Read the amount of time the CPUs have spent performing -- different kinds of work. Read the first line of /proc/stat -- which is the sum of all CPUs. @@ -68,7 +68,7 @@ local function worker(args) cpu.last_total = total end - newtimer("cpu", timeout, cpu.update) + newtimer("cpu", timeout, update) return cpu.widget end diff --git a/widgets/fs.lua b/widgets/fs.lua index b580010..17037c4 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -27,7 +27,7 @@ local setmetatable = setmetatable local fs = {} local notification = nil -notification_preset = { fg = beautiful.fg_normal } +fs_notification_preset = { fg = beautiful.fg_normal } function fs:hide() if notification ~= nil then @@ -44,7 +44,7 @@ function fs:show(t_out) f:close() notification = naughty.notify({ - preset = notification_preset, + preset = fs_notification_preset, text = ws, timeout = t_out }) @@ -63,7 +63,7 @@ local function worker(args) helpers.set_map("fs", false) - function fs.update() + function update() fs_info = {} local f = io.popen("LC_ALL=C df -kP") @@ -108,20 +108,12 @@ local function worker(args) end end - helpers.newtimer(partition, timeout, fs.update) + helpers.newtimer(partition, timeout, update) widget:connect_signal('mouse::enter', function () fs:show(0) end) widget:connect_signal('mouse::leave', function () fs:hide() end) - output = { - widget = fs.widget, - show = function(t_out) - fs.update() - fs:show(t_out) - end - } - - return setmetatable(output, { __index = output.widget }) + return setmetatable(fs, { __index = fs.widget }) end return setmetatable(fs, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/imap.lua b/widgets/imap.lua index 4df3610..6574276 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -47,8 +47,8 @@ local function worker(args) imap.widget = wibox.widget.textbox('') - function imap.update() - notification_preset = { + function update() + mail_notification_preset = { icon = helpers.icons_dir .. "mail.png", position = "top_left" } @@ -73,13 +73,13 @@ local function worker(args) else nt = mail .. " has " .. mailcount .. " new messages" end - naughty.notify({ preset = notification_preset, text = nt }) + naughty.notify({ preset = mail_notification_preset, text = nt }) end helpers.set_map(mail, mailcount) end - helpers.newtimer(mail, timeout, imap.update, true) + helpers.newtimer(mail, timeout, update, true) return imap.widget end diff --git a/widgets/maildir.lua b/widgets/maildir.lua index 4ac34bc..d460881 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -33,7 +33,7 @@ local function worker(args) maildir.widget = wibox.widget.textbox('') - function maildir.update() + function update() -- Find pathes to mailboxes. local p = io.popen("find " .. mailpath .. " -mindepth 1 -maxdepth 1 -type d" .. @@ -88,8 +88,7 @@ local function worker(args) settings() end - newtimer(mailpath, timeout, maildir.update, true) - + newtimer(mailpath, timeout, update, true) return maildir.widget end diff --git a/widgets/mem.lua b/widgets/mem.lua index f014149..78ed3e0 100644 --- a/widgets/mem.lua +++ b/widgets/mem.lua @@ -1,12 +1,10 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - * (c) 2010, Adrian C. - * (c) 2009, Lucas de Vries - + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + --]] local newtimer = require("lain.helpers").newtimer @@ -32,30 +30,30 @@ local function worker(args) mem.widget = wibox.widget.textbox('') - function mem.update() - mem = {} + function update() + mem_now = {} for line in io.lines("/proc/meminfo") do for k, v in string.gmatch(line, "([%a]+):[%s]+([%d]+).+") do - if k == "MemTotal" then mem.total = math.floor(v / 1024) - elseif k == "MemFree" then mem.free = math.floor(v / 1024) - elseif k == "Buffers" then mem.buf = math.floor(v / 1024) - elseif k == "Cached" then mem.cache = math.floor(v / 1024) - elseif k == "SwapTotal" then mem.swap = math.floor(v / 1024) - elseif k == "SwapFree" then mem.swapf = math.floor(v / 1024) + if k == "MemTotal" then mem_now.total = math.floor(v / 1024) + elseif k == "MemFree" then mem_now.free = math.floor(v / 1024) + elseif k == "Buffers" then mem_now.buf = math.floor(v / 1024) + elseif k == "Cached" then mem_now.cache = math.floor(v / 1024) + elseif k == "SwapTotal" then mem_now.swap = math.floor(v / 1024) + elseif k == "SwapFree" then mem_now.swapf = math.floor(v / 1024) end end end - used = mem.total - (mem.free + mem.buf + mem.cache) - swapused = mem.swap - mem.swapf + mem_now.used = mem_now.total - (mem_now.free + mem_now.buf + mem_now.cache) + mem_now.swapused = mem_now.swap - mem_now.swapf widget = mem.widget settings() end - newtimer("mem", timeout, mem.update) + newtimer("mem", timeout, update) return mem.widget end diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 016f2a3..cd97b37 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -40,7 +40,7 @@ local function worker(args) mpd.widget = wibox.widget.textbox('') - notification_preset = { + mpd_notification_preset = { title = "Now playing", timeout = 6 } @@ -73,8 +73,8 @@ local function worker(args) f:close() - notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist, - mpd_now.album, mpd_now.date, mpd_now.title) + mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist, + mpd_now.album, mpd_now.date, mpd_now.title) widget = mpd.widget settings() @@ -87,7 +87,7 @@ local function worker(args) os.execute(string.format("%s %q %q", mpdcover, music_dir, mpd_now.file)) mpd.id = naughty.notify({ - preset = notification_preset, + preset = mpd_notification_preset, icon = "/tmp/mpdcover.png", replaces_id = mpd.id }).id diff --git a/widgets/net.lua b/widgets/net.lua index d692df1..b3deca6 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -50,23 +50,25 @@ local function worker(args) helpers.set_map(iface, true) - function net.update() + function update() + net_now = {} + if iface == "" then iface = net.get_device() end - carrier = helpers.first_line('/sys/class/net/' .. iface .. + net_now.carrier = helpers.first_line('/sys/class/net/' .. iface .. '/carrier') or "0" - state = helpers.first_line('/sys/class/net/' .. iface .. + net_now.state = helpers.first_line('/sys/class/net/' .. iface .. '/operstate') or "down" local now_t = helpers.first_line('/sys/class/net/' .. iface .. '/statistics/tx_bytes') or 0 local now_r = helpers.first_line('/sys/class/net/' .. iface .. '/statistics/rx_bytes') or 0 - sent = tostring((now_t - net.last_t) / timeout / units) - sent = string.gsub(string.format('%.1f', sent), ",", ".") + net_now.sent = tostring((now_t - net.last_t) / timeout / units) + net_now.sent = string.gsub(string.format('%.1f', net_now.sent), ",", ".") - received = tostring((now_r - net.last_r) / timeout / units) - received = string.gsub(string.format('%.1f', received), ",", ".") + net_now.received = tostring((now_r - net.last_r) / timeout / units) + net_now.received = string.gsub(string.format('%.1f', net_now.received), ",", ".") widget = net.widget settings() @@ -74,7 +76,7 @@ local function worker(args) net.last_t = now_t net.last_r = now_r - if carrier ~= "1" + if net_now.carrier ~= "1" then if helpers.get_map(iface) then @@ -95,8 +97,7 @@ local function worker(args) end end - helpers.newtimer(iface, timeout, net.update) - + helpers.newtimer(iface, timeout, update) return net.widget end diff --git a/widgets/sysload.lua b/widgets/sysload.lua index 90bdedf..868398c 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -28,19 +28,18 @@ local function worker(args) sysload.widget = wibox.widget.textbox('') - function sysload.update() + function update() local f = io.open("/proc/loadavg") local ret = f:read("*all") f:close() - a, b, c = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") + load_1, load_5, load_15 = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") widget = sysload.widget settings() end - newtimer("sysload", timeout, sysload.update) - + newtimer("sysload", timeout, update) return sysload.widget end diff --git a/widgets/temp.lua b/widgets/temp.lua index e568138..b57c477 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -26,7 +26,7 @@ local function worker(args) temp.widget = wibox.widget.textbox('') - function temp.update() + function update() local f = io.open("/sys/class/thermal/thermal_zone0/temp") coretemp_now = tonumber(f:read("*all")) / 1000 f:close() @@ -34,8 +34,7 @@ local function worker(args) settings() end - newtimer("coretemp", timeout, temp.update) - + newtimer("coretemp", timeout, update) return temp.widget end diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 4d14966..4c90df4 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -43,7 +43,7 @@ local city_id = nil local sky = nil local settings = function() end -notification_preset = {} +yawn_notification_preset = {} local function fetch_weather() local url = api_url .. units_set .. city_id @@ -56,6 +56,7 @@ local function fetch_weather() -- widgets won't display if text == "" or text:match("City not found") then + yawn.icon:set_image(icon_path .. "na.png") if text == "" then weather_data = "Service not available at the moment." yawn.widget:set_text("N/A") @@ -152,7 +153,7 @@ function yawn.show(t_out) yawn.hide() notification = naughty.notify({ - preset = notification_preset, + preset = yawn_notification_preset, text = weather_data, icon = sky, timeout = t_out From f7aa28919588d307083b4b5b1c010f26cbc63cde Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 13 Sep 2013 18:15:25 +0200 Subject: [PATCH 020/546] small fixes --- helpers.lua | 12 ++++++------ layout/uselesstile.lua | 2 +- util/init.lua | 22 +++++++++++----------- util/markup.lua | 12 ++++++------ widgets/alsa.lua | 10 +++++----- widgets/alsabar.lua | 6 +++--- widgets/cpu.lua | 3 ++- widgets/fs.lua | 4 ++-- widgets/imap.lua | 4 +++- widgets/mem.lua | 10 +++++----- widgets/net.lua | 2 +- widgets/sysload.lua | 2 +- 12 files changed, 46 insertions(+), 43 deletions(-) diff --git a/helpers.lua b/helpers.lua index 81910d2..97cb797 100644 --- a/helpers.lua +++ b/helpers.lua @@ -1,10 +1,10 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + --]] local debug = require("debug") @@ -46,7 +46,7 @@ end -- }}} --- {{{ Timer maker +-- {{{ Timer maker helpers.timer_table = {} diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index b82c97e..cd288ed 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -11,7 +11,7 @@ local tag = require("awful.tag") local beautiful = require("beautiful") local ipairs = ipairs -local math = { floor = math.floor, +local math = { floor = math.floor, max = math.max, min = math.min } local tonumber = tonumber diff --git a/util/init.lua b/util/init.lua index a44d52c..26f50ae 100644 --- a/util/init.lua +++ b/util/init.lua @@ -1,15 +1,15 @@ --[[ - - Lain - Layouts, widgets and utilities for Awesome WM - - Utilities section - - Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - + + Lain + Layouts, widgets and utilities for Awesome WM + + Utilities section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + --]] local awful = require("awful") @@ -17,7 +17,7 @@ local beautiful = require("beautiful") local math = { sqrt = math.sqrt } local mouse = mouse local pairs = pairs -local string = string +local string = { gsub = string.gsub } local client = client local screen = screen local tonumber = tonumber diff --git a/util/markup.lua b/util/markup.lua index dbb8529..d367bca 100644 --- a/util/markup.lua +++ b/util/markup.lua @@ -1,11 +1,11 @@ --[[ - - Licensed under MIT License - * (c) 2013, Luke Bonham - * (c) 2009, Uli Schlachter - * (c) 2009, Majic - + + Licensed under MIT License + * (c) 2013, Luke Bonham + * (c) 2009, Uli Schlachter + * (c) 2009, Majic + --]] local beautiful = require("beautiful") diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 3e025bb..28bb05c 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -1,10 +1,10 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - * (c) 2010, Adrian C. - + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010, Adrian C. + --]] local newtimer = require("lain.helpers").newtimer diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 8331c54..d8f1731 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -15,7 +15,7 @@ local naughty = require("naughty") local io = { popen = io.popen } local math = { modf = math.modf } -local string = { format = string.format, +local string = { format = string.format, match = string.match, rep = string.rep } local tonumber = tonumber @@ -44,7 +44,7 @@ local alsabar = font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), font_size = "11", color = beautiful.fg_focus, - bar_size = 18 + bar_size = 18 }, _current_level = 0, @@ -122,7 +122,7 @@ local function worker(args) f:close() -- Capture mixer control state: [5%] ... ... [on] - local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") + local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") if volu == nil then volu = 0 diff --git a/widgets/cpu.lua b/widgets/cpu.lua index 55a3799..0b21edc 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -58,7 +58,8 @@ local function worker(args) local dactive = active - cpu.last_active local dtotal = total - cpu.last_total - usage = tostring(math.ceil((dactive / dtotal) * 100)) + cpu_now = {} + cpu_now.usage = tostring(math.ceil((dactive / dtotal) * 100)) widget = cpu.widget settings() diff --git a/widgets/fs.lua b/widgets/fs.lua index 17037c4..b434056 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -64,7 +64,7 @@ local function worker(args) helpers.set_map("fs", false) function update() - fs_info = {} + fs_info = {} local f = io.popen("LC_ALL=C df -kP") @@ -95,7 +95,7 @@ local function worker(args) if used >= 99 and not helpers.get_map("fs") then - naughty.notify({ + naughty.notify({ title = "warning", text = partition .. " ran out!\nmake some room", timeout = 8, diff --git a/widgets/imap.lua b/widgets/imap.lua index 6574276..605c1c4 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -14,6 +14,7 @@ local wibox = require("wibox") local io = { popen = io.popen } local string = { format = string.format, gsub = string.gsub } +local tonumber = tonumber local setmetatable = setmetatable @@ -52,7 +53,7 @@ local function worker(args) icon = helpers.icons_dir .. "mail.png", position = "top_left" } - + curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%s %s -k", head_command, server, port, mail, password, request) @@ -62,6 +63,7 @@ local function worker(args) t, mailcount = string.gsub(ws, "%d", "") t = nil -- because it's useless + mailcount = tonumber(mailcount) widget = imap.widget settings() diff --git a/widgets/mem.lua b/widgets/mem.lua index 78ed3e0..986fa76 100644 --- a/widgets/mem.lua +++ b/widgets/mem.lua @@ -1,10 +1,10 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + --]] local newtimer = require("lain.helpers").newtimer diff --git a/widgets/net.lua b/widgets/net.lua index b3deca6..d79e117 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -50,7 +50,7 @@ local function worker(args) helpers.set_map(iface, true) - function update() + function update() net_now = {} if iface == "" then iface = net.get_device() end diff --git a/widgets/sysload.lua b/widgets/sysload.lua index 868398c..015573c 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -32,7 +32,7 @@ local function worker(args) local f = io.open("/proc/loadavg") local ret = f:read("*all") f:close() - + load_1, load_5, load_15 = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") widget = sysload.widget From 29ede88b15b260a0ea3fd7b20615cd1c175cdb53 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 13 Sep 2013 20:08:51 +0200 Subject: [PATCH 021/546] yawn: forecast string fix --- widgets/yawn/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 4c90df4..d37fc44 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -131,9 +131,11 @@ local function fetch_weather() yawn.icon:set_image(sky) widget = yawn.widget - forecast = weather_data:match(": %S+.-,"):gsub(": ", ""):gsub(",", "\n") + forecast = weather_data:match(": %S.-,"):gsub(": ", ""):gsub(",", "") units = units:gsub(" ", "") + naughty.notify({text=forecast, timeout=10}) + naughty.notify({text=units, timeout=10}) settings() end From 32d1dda2f0bd020d68ed86125f904f286551455e Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 13 Sep 2013 20:15:45 +0200 Subject: [PATCH 022/546] yawn: forgot to remove debug strings --- widgets/yawn/init.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index d37fc44..2306fed 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -134,8 +134,6 @@ local function fetch_weather() forecast = weather_data:match(": %S.-,"):gsub(": ", ""):gsub(",", "") units = units:gsub(" ", "") - naughty.notify({text=forecast, timeout=10}) - naughty.notify({text=units, timeout=10}) settings() end From 304773ead13e952de27ca8c27446f7d86aeb7edd Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 14 Sep 2013 00:01:00 +0200 Subject: [PATCH 023/546] mpd: cover_size option added --- scripts/mpdcover | 12 +++++------- widgets/mpd.lua | 18 ++++++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/scripts/mpdcover b/scripts/mpdcover index 38b43e9..7ba9439 100755 --- a/scripts/mpdcover +++ b/scripts/mpdcover @@ -21,9 +21,6 @@ MUSIC_DIR=$1 # Song file file=$2 -# The default cover to use (optional) -DEFAULT_ART=$3 - # Regex expression used for image search IMG_REG="(front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$" @@ -31,7 +28,11 @@ IMG_REG="(front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$" TEMP_PATH="/tmp/mpdcover.png" # Resize cover -COVER_RESIZE="100x100" +COVER_RESIZE="$3x$3" + +if [ $COVER_RESIZE == "x" ]; then + COVER_RESIZE="100x100" +fi # Thumbnail background (transparent) COVER_BACKGROUND="none" @@ -48,9 +49,6 @@ art="$MUSIC_DIR/${file%/*}" # cover. cover="$(find "$art/" -maxdepth 1 -type f | egrep -i -m1 "$IMG_REG")" -# when no cover is found, use DEFAULT_ART as cover -cover="${cover:=$DEFAULT_ART}" - # check if art is available if [[ -n $cover ]]; then if [[ -n $COVER_RESIZE ]]; then diff --git a/widgets/mpd.lua b/widgets/mpd.lua index cd97b37..82db92c 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -26,13 +26,14 @@ local setmetatable = setmetatable local mpd = {} local function worker(args) - local args = args or {} - local timeout = args.timeout or 2 - local password = args.password or "" - local host = args.host or "127.0.0.1" - local port = args.port or "6600" - local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" - local settings = args.settings or function() end + local args = args or {} + local timeout = args.timeout or 2 + local password = args.password or "" + local host = args.host or "127.0.0.1" + local port = args.port or "6600" + local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" + local cover_size = args.cover_size or 100 + local settings = args.settings or function() end local mpdcover = helpers.scripts_dir .. "mpdcover" local mpdh = "telnet://" .. host .. ":" .. port @@ -84,7 +85,8 @@ local function worker(args) then helpers.set_map("current mpd track", mpd_now.title) - os.execute(string.format("%s %q %q", mpdcover, music_dir, mpd_now.file)) + os.execute(string.format("%s %q %q %d", mpdcover, music_dir, + mpd_now.file, cover_size)) mpd.id = naughty.notify({ preset = mpd_notification_preset, From 0f92560ca1dcd8ac38ef4aa6c80d95f4484c4bf8 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 14 Sep 2013 14:15:57 +0200 Subject: [PATCH 024/546] bat: rem nil value fixed --- widgets/bat.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 09b135f..7b14a9a 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -89,7 +89,7 @@ local function worker(args) ontop = true, replaces_id = bat.id }).id - elseif bat.perc <= 15 + elseif bat_now.perc <= 15 then bat.id = naughty.notify({ text = "plug the cable", From ba8448f02b2edd7b9e199f7841687b8f44e1c757 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 15 Sep 2013 16:17:33 +0200 Subject: [PATCH 025/546] small code fixes --- layout/cascadetile.lua | 6 +----- layout/centerwork.lua | 6 +----- layout/termfair.lua | 32 ++++---------------------------- layout/uselessfair.lua | 8 ++------ layout/uselesspiral.lua | 32 ++++++++++++++------------------ layout/uselesstile.lua | 6 +----- 6 files changed, 23 insertions(+), 67 deletions(-) diff --git a/layout/cascadetile.lua b/layout/cascadetile.lua index a94bbed..98821e3 100644 --- a/layout/cascadetile.lua +++ b/layout/cascadetile.lua @@ -43,11 +43,7 @@ function cascadetile.arrange(p) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width. - local useless_gap = tonumber(beautiful.useless_gap_width) - if useless_gap == nil - then - useless_gap = 0 - end + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 -- Screen. local wa = p.workarea diff --git a/layout/centerwork.lua b/layout/centerwork.lua index 2035c65..b8175ea 100644 --- a/layout/centerwork.lua +++ b/layout/centerwork.lua @@ -24,11 +24,7 @@ local centerwork = function centerwork.arrange(p) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width . - local useless_gap = tonumber(beautiful.useless_gap_width) - if useless_gap == nil - then - useless_gap = 0 - end + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 -- Screen. local wa = p.workarea diff --git a/layout/termfair.lua b/layout/termfair.lua index 62eef9a..4beab8f 100644 --- a/layout/termfair.lua +++ b/layout/termfair.lua @@ -14,15 +14,7 @@ local math = { ceil = math.ceil, max = math.max } local tonumber = tonumber -local termfair = -{ - name = "termfair", - - -- You can set the number of columns and rows, - -- -- otherwise they are read from awful.tag - nmaster = 0, -- columns - ncol = 0 -- rows -} +local termfair = { name = "termfair" } function termfair.arrange(p) -- Layout with fixed number of vertical columns (read from nmaster). @@ -45,11 +37,7 @@ function termfair.arrange(p) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width. - local useless_gap = tonumber(beautiful.useless_gap_width) - if useless_gap == nil - then - useless_gap = 0 - end + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 -- Screen. local wa = p.workarea @@ -57,22 +45,10 @@ function termfair.arrange(p) -- How many vertical columns? local t = tag.selected(p.screen) - local num_x - if termfair.nmaster ~= 0 - then - num_x = termfair.nmaster - else - num_x = tag.getnmaster(t) - end + local num_x = termfair.nmaster or tag.getnmaster(t) -- Do at least "desired_y" rows. - local desired_y - if termfair.ncol ~= 0 - then - desired_y = termfair.ncol - else - desired_y = tag.getncol(t) - end + local desired_y = termfair.ncol or tag.getncol(t) if #cls > 0 then diff --git a/layout/uselessfair.lua b/layout/uselessfair.lua index 92e8d45..7499d91 100644 --- a/layout/uselessfair.lua +++ b/layout/uselessfair.lua @@ -18,11 +18,7 @@ local uselessfair = {} local function fair(p, orientation) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width. - local useless_gap = tonumber(beautiful.useless_gap_width) - if useless_gap == nil - then - useless_gap = 0 - end + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 local wa = p.workarea local cls = p.clients @@ -88,7 +84,7 @@ local function fair(p, orientation) g.height = g.height - 2 * useless_gap g.y = g.y + useless_gap else - g.height = g.height - useless_gap + g.height = g.height - useless_gap end end -- End of useless gap. diff --git a/layout/uselesspiral.lua b/layout/uselesspiral.lua index 695728c..ad2ba04 100644 --- a/layout/uselesspiral.lua +++ b/layout/uselesspiral.lua @@ -17,11 +17,7 @@ local uselesspiral = {} local function spiral(p, spiral) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width. - local useless_gap = tonumber(beautiful.useless_gap_width) - if useless_gap == nil - then - useless_gap = 0 - end + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 local wa = p.workarea local cls = p.clients @@ -69,26 +65,26 @@ local function spiral(p, spiral) left = false if wa2.y == static_wa.y then - top = true + top = true end if wa2.x == static_wa.x then - left = true + left = true end - if top then - wa2.height = wa2.height - 2 * useless_gap - wa2.y = wa2.y + useless_gap + if top then + wa2.height = wa2.height - 2 * useless_gap + wa2.y = wa2.y + useless_gap else - wa2.height = wa2.height - useless_gap - end + wa2.height = wa2.height - useless_gap + end - if left then - wa2.width = wa2.width - 2 * useless_gap - wa2.x = wa2.x + useless_gap - else - wa2.width = wa2.width - useless_gap - end + if left then + wa2.width = wa2.width - 2 * useless_gap + wa2.x = wa2.x + useless_gap + else + wa2.width = wa2.width - useless_gap + end end -- End of useless gap. diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index cd288ed..78f7bec 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -21,11 +21,7 @@ local uselesstile = {} local function tile_group(cls, wa, orientation, fact, group) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width . - local useless_gap = tonumber(beautiful.useless_gap_width) - if useless_gap == nil - then - useless_gap = 0 - end + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 -- get our orientation right local height = "height" From fe32af5f4343a117d6ac3553095a9c3aefb98587 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 16 Sep 2013 13:49:14 +0200 Subject: [PATCH 026/546] little fix --- widgets/mpd.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 82db92c..3ebc761 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -9,7 +9,7 @@ local helpers = require("lain.helpers") -local util = require("awful.util") +local escape_f = require("awful.util").escape local naughty = require("naughty") local wibox = require("wibox") @@ -64,10 +64,10 @@ local function worker(args) for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do if k == "state" then mpd_now.state = v elseif k == "file" then mpd_now.file = v - elseif k == "Artist" then mpd_now.artist = util.escape(v) - elseif k == "Title" then mpd_now.title = util.escape(v) - elseif k == "Album" then mpd_now.album = util.escape(v) - elseif k == "Date" then mpd_now.date = util.escape(v) + elseif k == "Artist" then mpd_now.artist = escape_f(v) + elseif k == "Title" then mpd_now.title = escape_f(v) + elseif k == "Album" then mpd_now.album = escape_f(v) + elseif k == "Date" then mpd_now.date = escape_f(v) end end end From 2f80ab93e984985ac8cc92bcfe1b51697d026c7c Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 18 Sep 2013 00:27:46 +0200 Subject: [PATCH 027/546] mpd: default art added --- scripts/mpdcover | 10 ++++++++-- widgets/mpd.lua | 21 +++++++++++---------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/scripts/mpdcover b/scripts/mpdcover index 7ba9439..f9f6577 100755 --- a/scripts/mpdcover +++ b/scripts/mpdcover @@ -11,7 +11,7 @@ # # Dependencies: imagemagick. # -# Usage: mpdcover +# Usage: mpdcover # Configuration------------------------------------------------------- @@ -22,7 +22,7 @@ MUSIC_DIR=$1 file=$2 # Regex expression used for image search -IMG_REG="(front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$" +IMG_REG="(Front|front|Cover|cover|Art|art|Folder|folder)\.(jpg|jpeg|png|gif)$" # Path of temporary resized cover TEMP_PATH="/tmp/mpdcover.png" @@ -34,6 +34,9 @@ if [ $COVER_RESIZE == "x" ]; then COVER_RESIZE="100x100" fi +# The default cover to use (optional) +DEFAULT_ART=$4 + # Thumbnail background (transparent) COVER_BACKGROUND="none" @@ -49,6 +52,9 @@ art="$MUSIC_DIR/${file%/*}" # cover. cover="$(find "$art/" -maxdepth 1 -type f | egrep -i -m1 "$IMG_REG")" +# when no cover is found, use DEFAULT_ART as cover +cover="${cover:=$DEFAULT_ART}" + # check if art is available if [[ -n $cover ]]; then if [[ -n $COVER_RESIZE ]]; then diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 3ebc761..41233cd 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -26,14 +26,15 @@ local setmetatable = setmetatable local mpd = {} local function worker(args) - local args = args or {} - local timeout = args.timeout or 2 - local password = args.password or "" - local host = args.host or "127.0.0.1" - local port = args.port or "6600" - local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" - local cover_size = args.cover_size or 100 - local settings = args.settings or function() end + local args = args or {} + local timeout = args.timeout or 2 + local password = args.password or "" + local host = args.host or "127.0.0.1" + local port = args.port or "6600" + local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" + local cover_size = args.cover_size or 100 + local default_art = args.default_art or "" + local settings = args.settings or function() end local mpdcover = helpers.scripts_dir .. "mpdcover" local mpdh = "telnet://" .. host .. ":" .. port @@ -85,8 +86,8 @@ local function worker(args) then helpers.set_map("current mpd track", mpd_now.title) - os.execute(string.format("%s %q %q %d", mpdcover, music_dir, - mpd_now.file, cover_size)) + os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir, + mpd_now.file, cover_size, default_art)) mpd.id = naughty.notify({ preset = mpd_notification_preset, From 9195e2366f030dc2d15ba9ae6f27ba250f92e375 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 18 Sep 2013 15:58:17 +0200 Subject: [PATCH 028/546] added useless gaps change on the fly --- icons/layout/default/browse.png | Bin 190 -> 0 bytes icons/layout/default/browsew.png | Bin 190 -> 0 bytes icons/layout/default/gimp.png | Bin 289 -> 0 bytes icons/layout/default/gimpw.png | Bin 289 -> 0 bytes icons/layout/zenburn/browse.png | Bin 269 -> 0 bytes icons/layout/zenburn/gimp.png | Bin 3424 -> 0 bytes util/init.lua | 8 ++++++++ 7 files changed, 8 insertions(+) delete mode 100644 icons/layout/default/browse.png delete mode 100644 icons/layout/default/browsew.png delete mode 100644 icons/layout/default/gimp.png delete mode 100644 icons/layout/default/gimpw.png delete mode 100644 icons/layout/zenburn/browse.png delete mode 100644 icons/layout/zenburn/gimp.png diff --git a/icons/layout/default/browse.png b/icons/layout/default/browse.png deleted file mode 100644 index c063ca09de3e77e8a605ab39bef9b9c21c5bacda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt&q zurz(=c_77D666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_B)KS0!qA}lg;YFU978nDC;#AQ<(bjL&g1Z*p|Q5W=z-pm6rLz^{?Ox({Zts_ XZ!gY%>+x_hP(6dEtDnm{r-UW|pPn$+ diff --git a/icons/layout/default/browsew.png b/icons/layout/default/browsew.png deleted file mode 100644 index 9b0b2b3141a857c618202685f759ee37925e4dd1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt)< z|NmclbN*eBbV-n3FoVOh8)+a;lDE4HLkFv@2av;A;1OBOz`!jG!i)^F=12eq*-Jcq zUD@w2%J6B5nRIWs3=~rFba4#PIG_B3pOt4u4?B;;hla-50;30dM^bpA%=tr)KlW2$ YkiWe+`>n^r$w2iCp00i_>zopr0ADUNL;wH) diff --git a/icons/layout/default/gimp.png b/icons/layout/default/gimp.png deleted file mode 100644 index 207ab406ffb43518ba1a537ae5c0f22cf4d97a8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF%}28J29*~C-V}>VGHmHaRt&q zurz(=c_77D666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_B)KS0xB$bW`vyt3blK>IEHAPUwUaHFS8;K>xKSx1t&Soxn{>o^ae^i^x_hE{wGzb zmBV${jw(_4TIpBK`5^^Q>|A8|*SZ9}ZHZ`5+_vE625}W7#)%dUy)PUTZhhULXwuK| zyl1VR;#0Ln)8;qS9B>lfu--3&Z_h>czQ!rC;epnI)-%o-ZNC0nrgi>hu78nFe|f~M X@LS8-mC1Vu=p+VDS3j3^P6@jRF%}28J29*~C-V}>VGHmHaRt)< z|NmclbN*eBbV-n3FoVOh8)+a;lDE4HLkFv@2av;A;1OBOz`!jG!i)^F=12eq*-Jcq zUD@w2%J6Bb{E2xO3>0ejba4#PIKTALMqXw`9@Y!}>k3YCm~+jJmFNwWc<99?^88P# zQY(k+t{qjP^0m^hn)5>np4hp_@~?FXc-s=uptxA$Qs5#&yzG1yz2H&2G?0t<>WWxik1+8bCGunLpw@mB&%Uu5=pZ@ZQ YTj95svn!ML5YR~sp00i_>zopr055%EXaE2J diff --git a/icons/layout/zenburn/browse.png b/icons/layout/zenburn/browse.png deleted file mode 100644 index f0bd177143266961916a20d295faeccc73c58ba0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 269 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 diff --git a/util/init.lua b/util/init.lua index 26f50ae..c0545b6 100644 --- a/util/init.lua +++ b/util/init.lua @@ -171,4 +171,12 @@ function util.prompt_rename_tag(mypromptbox) end) end +-- On the fly useless gaps change +function util.useless_gaps_resize(thatmuch) + if beautiful.useless_gap_width then + beautiful.useless_gap_width = tonumber(beautiful.useless_gap_width) + thatmuch + awful.layout.arrange(mouse.screen) + end +end + return setmetatable(util, { __index = wrequire }) From 206f4d0e804d12549ef06ebbe6ba979e57621f6d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 18 Sep 2013 16:56:02 +0200 Subject: [PATCH 029/546] util.magnify_client: toggle mode added --- util/init.lua | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/util/init.lua b/util/init.lua index c0545b6..4e82cd7 100644 --- a/util/init.lua +++ b/util/init.lua @@ -84,17 +84,21 @@ end -- Magnify a client: Set it to "float" and resize it. function util.magnify_client(c) - awful.client.floating.set(c, true) + if not awful.client.floating.get(c) then + awful.client.floating.set(c, true) - local mg = screen[mouse.screen].geometry - local tag = awful.tag.selected(mouse.screen) - local mwfact = awful.tag.getmwfact(tag) - local g = {} - g.width = math.sqrt(mwfact) * mg.width - g.height = math.sqrt(mwfact) * mg.height - g.x = mg.x + (mg.width - g.width) / 2 - g.y = mg.y + (mg.height - g.height) / 2 - c:geometry(g) + local mg = screen[mouse.screen].geometry + local tag = awful.tag.selected(mouse.screen) + local mwfact = awful.tag.getmwfact(tag) + local g = {} + g.width = math.sqrt(mwfact) * mg.width + g.height = math.sqrt(mwfact) * mg.height + g.x = mg.x + (mg.width - g.width) / 2 + g.y = mg.y + (mg.height - g.height) / 2 + c:geometry(g) + else + awful.client.floating.set(c, false) + end end -- Read the nice value of pid from /proc. From 2efaf86b86d966e9af365168936c929ab7d9f3f3 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 19 Sep 2013 20:51:28 +0200 Subject: [PATCH 030/546] full dynamic tagging and wiki added --- .gitmodules | 3 +++ util/init.lua | 33 ++++++++++++++++++++++++++++----- widgets/borderbox.lua | 6 +++--- wiki | 1 + 4 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 .gitmodules create mode 160000 wiki diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..350c0f8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "wiki"] + path = wiki + url = https://github.com/copycat-killer/lain.wiki.git diff --git a/util/init.lua b/util/init.lua index 4e82cd7..73818b6 100644 --- a/util/init.lua +++ b/util/init.lua @@ -163,7 +163,22 @@ function util.tag_view_nonempty(direction, sc) end end --- Dynamically rename the current tag you have focused. +-- {{{ Dynamic tagging +-- +-- Add a new tag +function util.prompt_add_tag(mypromptbox) + awful.prompt.run({prompt="New tag name: "}, mypromptbox[mouse.screen].widget, + function(text) + if text:len() > 0 then + props = { selected = true } + tag = awful.tag.add(new_name, props) + tag.name = text + tag:emit_signal("property::name") + end + end) +end + +-- Rename current tag function util.prompt_rename_tag(mypromptbox) local tag = awful.tag.selected(mouse.screen) awful.prompt.run({prompt="Rename tag: "}, mypromptbox[mouse.screen].widget, @@ -175,12 +190,20 @@ function util.prompt_rename_tag(mypromptbox) end) end +-- Delete current tag (if empty) +-- Any rule set on the tag shall be broken +function util.remove_tag() + local tag = awful.tag.selected(mouse.screen) + local prevtag = awful.tag.gettags(mouse.screen)[awful.tag.getidx(tag) - 1] + awful.tag.delete(tag, prevtag) +end +-- +-- }}} + -- On the fly useless gaps change function util.useless_gaps_resize(thatmuch) - if beautiful.useless_gap_width then - beautiful.useless_gap_width = tonumber(beautiful.useless_gap_width) + thatmuch - awful.layout.arrange(mouse.screen) - end + beautiful.useless_gap_width = tonumber(beautiful.useless_gap_width) + thatmuch + awful.layout.arrange(mouse.screen) end return setmetatable(util, { __index = wrequire }) diff --git a/widgets/borderbox.lua b/widgets/borderbox.lua index 150c1c3..c251ea8 100644 --- a/widgets/borderbox.lua +++ b/widgets/borderbox.lua @@ -15,7 +15,7 @@ local setmetatable = setmetatable local borderbox = {} local function worker(relbox, s, args) - local where = args.position or 'above' + local where = args.position or 'top' local color = args.color or '#FFFFFF' local size = args.size or 1 local box = nil @@ -24,14 +24,14 @@ local function worker(relbox, s, args) bg = color } - if where == 'above' + if where == 'top' then wiboxarg.width = relbox.width wiboxarg.height = size box = wibox(wiboxarg) box.x = relbox.x box.y = relbox.y - size - elseif where == 'below' + elseif where == 'bottom' then wiboxarg.width = relbox.width wiboxarg.height = size diff --git a/wiki b/wiki new file mode 160000 index 0000000..1368b03 --- /dev/null +++ b/wiki @@ -0,0 +1 @@ +Subproject commit 1368b031aa5d4b29a30c8f24b4bebde2f9d08ece From 17079866150227a7a12798ea97961b7f6370574b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 19 Sep 2013 21:07:17 +0200 Subject: [PATCH 031/546] wiki updated --- util/init.lua | 5 +++-- wiki | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/util/init.lua b/util/init.lua index 73818b6..06db0d4 100644 --- a/util/init.lua +++ b/util/init.lua @@ -166,7 +166,7 @@ end -- {{{ Dynamic tagging -- -- Add a new tag -function util.prompt_add_tag(mypromptbox) +function util.add_tag(mypromptbox) awful.prompt.run({prompt="New tag name: "}, mypromptbox[mouse.screen].widget, function(text) if text:len() > 0 then @@ -179,7 +179,8 @@ function util.prompt_add_tag(mypromptbox) end -- Rename current tag -function util.prompt_rename_tag(mypromptbox) +-- @author: minism +function util.rename_tag(mypromptbox) local tag = awful.tag.selected(mouse.screen) awful.prompt.run({prompt="Rename tag: "}, mypromptbox[mouse.screen].widget, function(text) diff --git a/wiki b/wiki index 1368b03..f92b3ac 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 1368b031aa5d4b29a30c8f24b4bebde2f9d08ece +Subproject commit f92b3ac0c9dec3a6c8d046ce3d97add99a3a1e5e From fdf517503f5d52f0be7760777a7db855c1ede25c Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 20 Sep 2013 03:01:04 +0200 Subject: [PATCH 032/546] alsabar: added user settings function --- widgets/alsabar.lua | 6 ++++++ widgets/sysload.lua | 2 +- wiki | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index d8f1731..b0bf150 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -92,6 +92,7 @@ end local function worker(args) local args = args or {} local timeout = args.timeout or 4 + local settings = args.settings or function() end local width = args.width or 63 local height = args.heigth or 1 local ticks = args.ticks or true @@ -142,6 +143,11 @@ local function worker(args) alsabar.tooltip:set_text(string.format(" %s:%s ", alsabar.channel, volu)) alsabar.bar:set_color(alsabar.colors.unmute) end + + volume_now = {} + volume_now.level = tonumber(volu) + volume_now.status = mute + settings() end newtimer("alsabar", timeout, alsabar.update) diff --git a/widgets/sysload.lua b/widgets/sysload.lua index 015573c..2abac33 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -11,7 +11,7 @@ local newtimer = require("lain.helpers").newtimer local wibox = require("wibox") -local io = io +local io = { open = io.open } local string = { format = string.format, match = string.match } diff --git a/wiki b/wiki index f92b3ac..36a0534 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit f92b3ac0c9dec3a6c8d046ce3d97add99a3a1e5e +Subproject commit 36a0534651749f23bf9786ba47912b498938c103 From e86539a687c66cbb637ea6b2ecfecef344c0e446 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 20 Sep 2013 03:04:17 +0200 Subject: [PATCH 033/546] alsabar: notifications.color change --- widgets/alsabar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index b0bf150..90d3a0d 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -43,7 +43,7 @@ local alsabar = { font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), font_size = "11", - color = beautiful.fg_focus, + color = beautiful.fg_normal, bar_size = 18 }, From c100dfac9c3db1c255f5e424563a899422731eca Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 20 Sep 2013 03:05:50 +0200 Subject: [PATCH 034/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 36a0534..476e9f5 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 36a0534651749f23bf9786ba47912b498938c103 +Subproject commit 476e9f57bb66cec635ce61170a57f49299e6c715 From 4060898f1b9d8ae2d3adee0dd28ebf601631c975 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 21 Sep 2013 21:59:05 +0200 Subject: [PATCH 035/546] yawn: new icon --- widgets/imap.lua | 2 +- widgets/yawn/icons/HeavyRain.png | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 120000 widgets/yawn/icons/HeavyRain.png diff --git a/widgets/imap.lua b/widgets/imap.lua index 605c1c4..b3f281d 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -62,7 +62,7 @@ local function worker(args) f:close() t, mailcount = string.gsub(ws, "%d", "") - t = nil -- because it's useless + t = nil mailcount = tonumber(mailcount) widget = imap.widget diff --git a/widgets/yawn/icons/HeavyRain.png b/widgets/yawn/icons/HeavyRain.png new file mode 120000 index 0000000..ace2a94 --- /dev/null +++ b/widgets/yawn/icons/HeavyRain.png @@ -0,0 +1 @@ +Showers.png \ No newline at end of file From f3096ba021ae4835e5626d3b20abb9bc236701a3 Mon Sep 17 00:00:00 2001 From: Jan Xie Date: Wed, 25 Sep 2013 09:35:38 +0800 Subject: [PATCH 036/546] create task widget template, based on calendar widget --- widgets/task.lua | 126 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 widgets/task.lua diff --git a/widgets/task.lua b/widgets/task.lua new file mode 100644 index 0000000..31499f1 --- /dev/null +++ b/widgets/task.lua @@ -0,0 +1,126 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Jan Xie + +--]] + +local icons_dir = require("lain.helpers").icons_dir + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") + +local io = io +local os = { date = os.date } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- task notification +-- lain.widgets.task +local task = {} +local task_notification = nil + +function task:hide() + if task_notification ~= nil then + naughty.destroy(task_notification) + task_notification = nil + end +end + +function task:show(t_out, inc_offset) + task:hide() + + local offs = inc_offset or 0 + local tims = t_out or 0 + local f, c_text + local today = tonumber(os.date('%d')) + local init_t = '/usr/bin/cal | sed -r -e "s/(^| )( ' + -- let's take font only, font size is set in task table + local font = beautiful.font:sub(beautiful.font:find(""), + beautiful.font:find(" ")) + + if offs == 0 + then -- current month showing, today highlighted + if today >= 10 + then + init_t = '/usr/bin/cal | sed -r -e "s/(^| )(' + end + + task.offset = 0 + task.notify_icon = task.icons .. today .. ".png" + + -- bg and fg inverted to highlight today + f = io.popen( init_t .. today .. + ')($| )/\\1\\2<\\/span><\\/b>\\3/"' ) + + else -- no current month showing, no day to highlight + local month = tonumber(os.date('%m')) + local year = tonumber(os.date('%Y')) + + task.offset = task.offset + offs + month = month + task.offset + + if month > 12 then + month = month % 12 + year = year + 1 + if month <= 0 then + month = 12 + end + elseif month < 1 then + month = month + 12 + year = year - 1 + if month <= 0 then + month = 1 + end + end + + task.notify_icon = nil + + f = io.popen('/usr/bin/cal ' .. month .. ' ' .. year) + end + + + --c_text = "" + --.. f:read() .. "\n\n" + --.. f:read() .. "\n" + --.. f:read("*all"):gsub("\n*$", "") + --.. "" + c_text = "hello tasks!" + f:close() + + task_notification = naughty.notify({ text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = tims }) +end + +function task:attach(widget, args) + local args = args or {} + task.icons = args.icons or icons_dir .. "cal/white/" + task.font_size = tonumber(args.font_size) or 12 + task.fg = args.fg or beautiful.fg_normal or "#FFFFFF" + task.bg = args.bg or beautiful.bg_normal or "#FFFFFF" + task.position = args.position or "top_right" + + task.offset = 0 + task.notify_icon = nil + + widget:connect_signal("mouse::enter", function () task:show() end) + widget:connect_signal("mouse::leave", function () task:hide() end) + widget:buttons(awful.util.table.join( awful.button({ }, 1, function () + task:show(0, -1) end), + awful.button({ }, 3, function () + task:show(0, 1) end) )) +end + +return setmetatable(task, { __call = function(_, ...) return create(...) end }) From 50a07a1ec18aaeeab356de56254dfdf592bd9c9b Mon Sep 17 00:00:00 2001 From: Jan Xie Date: Wed, 25 Sep 2013 10:03:11 +0800 Subject: [PATCH 037/546] clean a little bit --- widgets/task.lua | 70 +++++++++++++++--------------------------------- 1 file changed, 21 insertions(+), 49 deletions(-) diff --git a/widgets/task.lua b/widgets/task.lua index 31499f1..cf84cbc 100644 --- a/widgets/task.lua +++ b/widgets/task.lua @@ -30,10 +30,9 @@ function task:hide() end end -function task:show(t_out, inc_offset) +function task:show(t_out) task:hide() - local offs = inc_offset or 0 local tims = t_out or 0 local f, c_text local today = tonumber(os.date('%d')) @@ -42,50 +41,23 @@ function task:show(t_out, inc_offset) local font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")) - if offs == 0 - then -- current month showing, today highlighted - if today >= 10 - then - init_t = '/usr/bin/cal | sed -r -e "s/(^| )(' - end - - task.offset = 0 - task.notify_icon = task.icons .. today .. ".png" - - -- bg and fg inverted to highlight today - f = io.popen( init_t .. today .. - ')($| )/\\1\\2<\\/span><\\/b>\\3/"' ) - - else -- no current month showing, no day to highlight - local month = tonumber(os.date('%m')) - local year = tonumber(os.date('%Y')) - - task.offset = task.offset + offs - month = month + task.offset - - if month > 12 then - month = month % 12 - year = year + 1 - if month <= 0 then - month = 12 - end - elseif month < 1 then - month = month + 12 - year = year - 1 - if month <= 0 then - month = 1 - end - end - - task.notify_icon = nil - - f = io.popen('/usr/bin/cal ' .. month .. ' ' .. year) + if today >= 10 + then + init_t = '/usr/bin/cal | sed -r -e "s/(^| )(' end + task.offset = 0 + --task.notify_icon = task.icons .. today .. ".png" + + -- bg and fg inverted to highlight today + --f = io.popen( init_t .. today .. + --')($| )/\\1\\2<\\/span><\\/b>\\3/"' ) + + --c_text = "" @@ -94,13 +66,13 @@ function task:show(t_out, inc_offset) --.. f:read("*all"):gsub("\n*$", "") --.. "" c_text = "hello tasks!" - f:close() + --f:close() task_notification = naughty.notify({ text = c_text, - icon = task.notify_icon, - position = task.position, - fg = task.fg, - bg = task.bg, + --icon = task.notify_icon, + --position = task.position, + --fg = task.fg, + --bg = task.bg, timeout = tims }) end From ff61f09b6a8c0be382477f8106a5925bb7116613 Mon Sep 17 00:00:00 2001 From: Jan Xie Date: Wed, 25 Sep 2013 10:24:54 +0800 Subject: [PATCH 038/546] show next tasks --- widgets/task.lua | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/widgets/task.lua b/widgets/task.lua index cf84cbc..b313e8d 100644 --- a/widgets/task.lua +++ b/widgets/task.lua @@ -13,7 +13,6 @@ local beautiful = require("beautiful") local naughty = require("naughty") local io = io -local os = { date = os.date } local tonumber = tonumber local setmetatable = setmetatable @@ -35,38 +34,19 @@ function task:show(t_out) local tims = t_out or 0 local f, c_text - local today = tonumber(os.date('%d')) - local init_t = '/usr/bin/cal | sed -r -e "s/(^| )( ' -- let's take font only, font size is set in task table local font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")) - if today >= 10 - then - init_t = '/usr/bin/cal | sed -r -e "s/(^| )(' - end - task.offset = 0 --task.notify_icon = task.icons .. today .. ".png" - -- bg and fg inverted to highlight today - --f = io.popen( init_t .. today .. - --')($| )/\\1\\2<\\/span><\\/b>\\3/"' ) - - - - --c_text = "" - --.. f:read() .. "\n\n" - --.. f:read() .. "\n" - --.. f:read("*all"):gsub("\n*$", "") - --.. "" - c_text = "hello tasks!" - --f:close() + f = io.popen('task') + c_text = "[Next Tasks]\n" + .. f:read("*all") .. "\n" + .. "" + f:close() task_notification = naughty.notify({ text = c_text, --icon = task.notify_icon, From ed43386dda399b78bab53a45f1857e54c15bed2e Mon Sep 17 00:00:00 2001 From: Jan Xie Date: Wed, 25 Sep 2013 10:51:01 +0800 Subject: [PATCH 039/546] add icon for task widget --- icons/taskwarrior.png | Bin 0 -> 1280 bytes widgets/task.lua | 18 ++++++++---------- 2 files changed, 8 insertions(+), 10 deletions(-) create mode 100644 icons/taskwarrior.png diff --git a/icons/taskwarrior.png b/icons/taskwarrior.png new file mode 100644 index 0000000000000000000000000000000000000000..171af60260bcba14cafa18f1530935841d6f38b4 GIT binary patch literal 1280 zcmV+b1^@bqP)WFU8GbZ8()Nlj2>E@cM*00d-7L_t(I%XL&;XcSiz z{?5HSJIN&3S=Oz)M7Bw65K{%U4~A|^9$L~C3|OS-Tg`(%eJCg<_$GmZ(ozdrXi<{~ zp;%1BK&VY(=;D5Q!bZVbY1sWB9R!Zs;c@c8jUUkz{QIf z(b3TX03ZP9?d`>Z0|x*Au~_Vw<2avIRaHfp*>GJKm6eqyGb5kRt3n83X3aFsIU&UF z+qZB31po#H2C!$(9?+RHXK?iBQ2;g9i`Ng9i_e8HSMwhr=J0iD7wp`L~ggksS>U4SIcj zy*@rZ-keUSuP`&18LFzjQ(Ig6xoz8<+uPfB5fLaBiv=9V>DP6=LDRI2%nTwzI-S1T z)YSAL-h`N#m>BZ={U4VKr_<@X%pBUXWy?mfxVX4W)3mVH>s?>|PBSwz-{Sw_CK8G7 z%VRZ7+bo25e&^1eLn0Uqe(AbyR!Ui2o^|r%$-mzsh)5*z*fh=6yQ-@GbUHl~3WW~Q zZECkHD-a9@FElnbIxC5Cc6RnxpU+n#gm`U~R8@`Gww(|} z#BXbD+qP{T$z<|J0K#=$Yi@3?tGT)PE7x_a*Tyn45fKZ^vfOMoOXVaHA(2Q-u84LK zk;BaKojZ5_1OSF%Oso|&P4kJAa)U5Ua}$>?8naky#ba!_r*R-^H&SWwv$8jE)xid6PdpDIz^$6E>Z`!u~ z+%(NuA_6l*)3myW4ZUYb{=kaE;`#IEKbW4Lj_JC7SV}1Xz_Ki(P$(2$zI=Hc z0GB>POifLVEG#Tc)YaAPRTRZnwgBMudf~b*Gc!pk%ilWl^y$;SU@%D6u3h_D(==ON zy?Pb>{r$YKu+Z1u-o7`R%@!QTnfG`+>*XtyS|%wagb=W8JD161?q@QY*_xV~^ySN! zzd3Q@gn8q}jaTbyaBvX2ckf0|Pfx|xty}l{{r>NY#p0tvq3}Y}wA$+G>M#H{3}ZHz z%Pm$`R&F4o(DL%~@v*V7>z$pQ_R!D}+S=McZ<%TD=;-M2Kp@b;%swH+la<}sNJR6= qWb#5Z8vPkS@$A{NICA93YT|!n4[Next Tasks]\n" + .. task.font_size+2 .. "'>Tasks next\n" + .. "" .. f:read("*all") .. "\n" .. "" f:close() task_notification = naughty.notify({ text = c_text, - --icon = task.notify_icon, - --position = task.position, - --fg = task.fg, - --bg = task.bg, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, timeout = tims }) end function task:attach(widget, args) local args = args or {} - task.icons = args.icons or icons_dir .. "cal/white/" task.font_size = tonumber(args.font_size) or 12 task.fg = args.fg or beautiful.fg_normal or "#FFFFFF" task.bg = args.bg or beautiful.bg_normal or "#FFFFFF" task.position = args.position or "top_right" - task.offset = 0 - task.notify_icon = nil + task.notify_icon = icons_dir .. "taskwarrior.png" widget:connect_signal("mouse::enter", function () task:show() end) widget:connect_signal("mouse::leave", function () task:hide() end) From a12d360564932941f65a706aec27b32a24738af5 Mon Sep 17 00:00:00 2001 From: Jan Xie Date: Wed, 25 Sep 2013 11:20:13 +0800 Subject: [PATCH 040/546] add prompt function for task widget --- widgets/task.lua | 66 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/widgets/task.lua b/widgets/task.lua index fdf439a..f2b49f4 100644 --- a/widgets/task.lua +++ b/widgets/task.lua @@ -29,20 +29,15 @@ function task:hide() end end -function task:show(t_out) +function task:show() task:hide() - local tims = t_out or 0 local f, c_text - -- let's take font only, font size is set in task table - local font = beautiful.font:sub(beautiful.font:find(""), - beautiful.font:find(" ")) - f = io.popen('task') - c_text = "Tasks next\n" - .. "" .. f:read("*all") .. "\n" .. "" @@ -53,15 +48,68 @@ function task:show(t_out) position = task.position, fg = task.fg, bg = task.bg, - timeout = tims }) + timeout = task.timeout }) +end + +function task:add(...) + local f = io.popen("task add " .. ...) + c_text = "" + .. f:read("*all") .. "\n" + .. "" + + naughty.notify({ text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = task.timeout}) +end + +function task:prompt_add() + awful.prompt.run( { prompt = "Add task: " }, + mypromptbox[mouse.screen].widget, + function (...) + task:add(...) + end, + nil, + awful.util.getdir("cache") .. "/history_task_add") +end + +function task:execute(...) + local f = io.popen("task " .. ...) + c_text = "" + .. f:read("*all") .. "\n" + .. "" + + naughty.notify({ text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = task.timeout}) +end + +function task:prompt() + awful.prompt.run( { prompt = "Task: " }, + mypromptbox[mouse.screen].widget, + function (...) + task:execute(...) + end, + nil, + awful.util.getdir("cache") .. "/history_task") end function task:attach(widget, args) local args = args or {} task.font_size = tonumber(args.font_size) or 12 + task.font = beautiful.font:sub(beautiful.font:find(""), + beautiful.font:find(" ")) task.fg = args.fg or beautiful.fg_normal or "#FFFFFF" task.bg = args.bg or beautiful.bg_normal or "#FFFFFF" task.position = args.position or "top_right" + task.timeout = args.timeout or 7 task.notify_icon = icons_dir .. "taskwarrior.png" From 66dde90206fe181cbe49d236925a8d4e6a86ec54 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 25 Sep 2013 15:08:11 +0200 Subject: [PATCH 041/546] contrib section started\! --- README.rst | 17 +++++ icons/taskwarrior.png | Bin 1280 -> 0 bytes icons/taskwarrior/task.png | Bin 0 -> 1212 bytes icons/taskwarrior/tasksmall.png | Bin 0 -> 941 bytes widgets/calendar.lua | 1 - widgets/contrib/init.lua | 20 +++++ widgets/contrib/task.lua | 131 ++++++++++++++++++++++++++++++++ widgets/mpd.lua | 2 +- widgets/task.lua | 124 ------------------------------ wiki | 2 +- 10 files changed, 170 insertions(+), 127 deletions(-) delete mode 100644 icons/taskwarrior.png create mode 100644 icons/taskwarrior/task.png create mode 100755 icons/taskwarrior/tasksmall.png create mode 100644 widgets/contrib/init.lua create mode 100644 widgets/contrib/task.lua delete mode 100644 widgets/task.lua diff --git a/README.rst b/README.rst index 779428d..66d846c 100644 --- a/README.rst +++ b/README.rst @@ -19,6 +19,23 @@ in order to improve Awesome_ usability and configurability. Read the wiki_ for all the info. +Contributions +------------- + +Any contribution is welcome! Feel free to make a pull request. + +Just make sure that: + +- Your code fits with the general style of the module. In particular, you should use the same indentation pattern that the code uses, and also avoid adding space at the ends of lines. + +- Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions or using `lain.helpers`. If something is unclear, and you can't write it in such a way that it will be clear, explain it with a comment. + +- You test your changes before submitting to make sure that not only your code work, but have not broken other parts of the module too! + +- You update `wiki` submodule with a thorough section. + +Contributed widgets have to be put it in `lain/widget/contrib`. + Screenshots ----------- diff --git a/icons/taskwarrior.png b/icons/taskwarrior.png deleted file mode 100644 index 171af60260bcba14cafa18f1530935841d6f38b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1280 zcmV+b1^@bqP)WFU8GbZ8()Nlj2>E@cM*00d-7L_t(I%XL&;XcSiz z{?5HSJIN&3S=Oz)M7Bw65K{%U4~A|^9$L~C3|OS-Tg`(%eJCg<_$GmZ(ozdrXi<{~ zp;%1BK&VY(=;D5Q!bZVbY1sWB9R!Zs;c@c8jUUkz{QIf z(b3TX03ZP9?d`>Z0|x*Au~_Vw<2avIRaHfp*>GJKm6eqyGb5kRt3n83X3aFsIU&UF z+qZB31po#H2C!$(9?+RHXK?iBQ2;g9i`Ng9i_e8HSMwhr=J0iD7wp`L~ggksS>U4SIcj zy*@rZ-keUSuP`&18LFzjQ(Ig6xoz8<+uPfB5fLaBiv=9V>DP6=LDRI2%nTwzI-S1T z)YSAL-h`N#m>BZ={U4VKr_<@X%pBUXWy?mfxVX4W)3mVH>s?>|PBSwz-{Sw_CK8G7 z%VRZ7+bo25e&^1eLn0Uqe(AbyR!Ui2o^|r%$-mzsh)5*z*fh=6yQ-@GbUHl~3WW~Q zZECkHD-a9@FElnbIxC5Cc6RnxpU+n#gm`U~R8@`Gww(|} z#BXbD+qP{T$z<|J0K#=$Yi@3?tGT)PE7x_a*Tyn45fKZ^vfOMoOXVaHA(2Q-u84LK zk;BaKojZ5_1OSF%Oso|&P4kJAa)U5Ua}$>?8naky#ba!_r*R-^H&SWwv$8jE)xid6PdpDIz^$6E>Z`!u~ z+%(NuA_6l*)3myW4ZUYb{=kaE;`#IEKbW4Lj_JC7SV}1Xz_Ki(P$(2$zI=Hc z0GB>POifLVEG#Tc)YaAPRTRZnwgBMudf~b*Gc!pk%ilWl^y$;SU@%D6u3h_D(==ON zy?Pb>{r$YKu+Z1u-o7`R%@!QTnfG`+>*XtyS|%wagb=W8JD161?q@QY*_xV~^ySN! zzd3Q@gn8q}jaTbyaBvX2ckf0|Pfx|xty}l{{r>NY#p0tvq3}Y}wA$+G>M#H{3}ZHz z%Pm$`R&F4o(DL%~@v*V7>z$pQ_R!D}+S=McZ<%TD=;-M2Kp@b;%swH+la<}sNJR6= qWb#5Z8vPkS@$A{NICA93YT|!n4PfQfvSK1W8Fm zK~#9!?VL?k8%Gew|J9CJ+S=62!VAF(Bu=2=0!CaQA146k0ud*$IYAz|05TT{oPf~@ zA{JT9^dd4#ExNMM$QF9U8M=FVdU&dx^pLvvsj9lVs(OH(JSo)1qD7&HN?{Dhfe7^h z91`Kp)}P&rU`{0W0OiKu&ot%y#erGDkPjj>egZ-*5y1nIOpT$BO+%s(K#1^(2qT~0 zD}q}QOwyEZItNB;Jpu4r!|X4N!6Z$25j~iq&^;ndeOt+QWCkq9%fIA}O0PX?&w9Z{zYQR6ZD3zwX(7K$iOPV5BBnf}qh6iA%6b@a0Z38d{cL4J3 zf4VI7G11yuWSS(&BDlo>Uu(Tr>(|Uob**g!*xT(h4H0etnHxj%rvUu7K3X<#o-ilV zR=`yC-haNm<5p{R`;q?M2loE*p^Ni&ou<5~%)FAdRRTR2cmijY5zc-mYhCD<%yH@2od7aJ#5%yaL^9&`d zT}x~IK`Gp!esj;M3FxauD;6KCH6rFRomDprZ^U98T;mkL|0aV<;mo$S?9%sg24l=# zW81NF09CTz8ko47ZqyzaKn`NXV%vrE1cnCjT8w?C)U~PKLyNL= zuce5r1y`aDfN5b21V9JC&?qRF%6A7Huo$bUDizvy+e!4E?@rcWMCha|U_@{n1Wa|X zd*2l>L>N`6MYCX(k}*0a&(&GIbT_iq**3;x=$>Q&EC!>;O}6NR?}NzmYC2Y6(vLGj(mr8+H#Y`Z3^REm zxHblv>rGm34YxGqMUrp^;G#t?=SjlH(OoZISr4B9auPD`tk#kfW}bM*Awb_&ee zdXj`QV{nAkEUvZN7=xoE;p3(UAeGkTt588QP5FkI_l?1k2(D{>>5>B4O(ZlrW$ z&7$Dazd+Z;l~#rLV^K;#3pUO>m!Mz_lDw~rnTez3$Gn+4Ne*0?_wIY=e($^Yob#Qb zBs46>$oY9;V8FkGj=k;nkdO8Q6Q?GW6*YX;CP zUIg?LiH`v;+?N0n00arI0RG~=`+3y>=6T$iWw--iONrNBNyQQG!@aTqvy!as%`*Hg zVROlK`ho0jp4-u`F&N{2JwRm!ULou*+~gkym!CXYw{q8 zAprXUi~!gTU@L%WKo0;u0B~2rqY&I=y;Pnhd8OvB<*!pqBhPc0<>ReBzt}L#$IVP- z-YF3ztV$e<(Jr)e?qam_62~M=x233CIj^-+$4h2*f_!ttx$VWuz@~bo%AWual7NKy zZlxJD<;BBN-^&>D;T7cBs8o4P>dU4&{!v!|k_ydNB>JUnB1SvE1h~s2Zq-!GJ2GQa zay2tG^=xCM(l@iz{M;M{wrz8HQ+GHD;MS5_rYJrSAv{gSV5QP~Xoc^1e|CPkN6Bm` zaV6n_baIOTG@4i}=)071i^MmHgM?ovZpRNL188QW=z^KWZ<7EdaYjN?JyYxO^g|MW z5>Iu5L5Zgm0mS#Ue3^#Dx*yj4b`CHEcT>`_MtsRmn4(Hs< zRq5)ycV~;D*aP74;" .. f:read() .. "\n\n" diff --git a/widgets/contrib/init.lua b/widgets/contrib/init.lua new file mode 100644 index 0000000..81321c6 --- /dev/null +++ b/widgets/contrib/init.lua @@ -0,0 +1,20 @@ + +--[[ + + Lain + Layouts, widgets and utilities for Awesome WM + + User contributed widgets section + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local wrequire = require("lain.helpers").wrequire +local setmetatable = setmetatable + +local widgets = { _NAME = "lain.widgets.contrib" } + +return setmetatable(widgets, { __index = wrequire }) diff --git a/widgets/contrib/task.lua b/widgets/contrib/task.lua new file mode 100644 index 0000000..88baa71 --- /dev/null +++ b/widgets/contrib/task.lua @@ -0,0 +1,131 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2013, Jan Xie + +--]] + +local icons_dir = require("lain.helpers").icons_dir + +local awful = require("awful") +local beautiful = require("beautiful") +local naughty = require("naughty") + +local io = io +local string = { len = string.len } +local tonumber = tonumber + +local setmetatable = setmetatable + +-- Taskwarrior notification +-- lain.widgets.task +local task = {} + +local task_notification = nil + +function task:hide() + if task_notification ~= nil then + naughty.destroy(task_notification) + task_notification = nil + end +end + +function task:show() + task:hide() + + local f, c_text + + f = io.popen('task') + c_text = "" + .. f:read("*all"):gsub("\n*$", "") + .. "" + f:close() + + task_notification = naughty.notify({ title = "[task next]", + text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = task.timeout }) +end + +function task:prompt_add() + awful.prompt.run({ prompt = "Add task: " }, + mypromptbox[mouse.screen].widget, + function (...) + local f = io.popen("task add " .. ...) + c_text = "\n" + .. f:read("*all") + .. "" + + naughty.notify({ + text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = task.timeout + }) + end, + nil, + awful.util.getdir("cache") .. "/history_task_add") +end + +function task:prompt_search() + awful.prompt.run({ prompt = "Search task: " }, + mypromptbox[mouse.screen].widget, + function (...) + local f = io.popen("task " .. ...) + c_text = f:read("*all") + f:close() + + if string.len(c_text) == 0 + then + c_text = "No results found." + else + c_text = "" + .. c_text .. "\n" + .. "" + end + + naughty.notify({ + text = c_text, + icon = task.notify_icon, + position = task.position, + fg = task.fg, + bg = task.bg, + timeout = task.timeout + }) + end, + nil, + awful.util.getdir("cache") .. "/history_task") +end + +function task:attach(widget, args) + local args = args or {} + + task.font_size = tonumber(args.font_size) or 12 + task.font = beautiful.font:sub(beautiful.font:find(""), + beautiful.font:find(" ")) + task.fg = args.fg or beautiful.fg_normal or "#FFFFFF" + task.bg = args.bg or beautiful.bg_normal or "#FFFFFF" + task.position = args.position or "top_right" + task.timeout = args.timeout or 7 + + task.notify_icon = icons_dir .. "/taskwarrior/task.png" + task.notify_icon_small = icons_dir .. "/taskwarrior/tasksmall.png" + + widget:connect_signal("mouse::enter", function () task:show() end) + widget:connect_signal("mouse::leave", function () task:hide() end) +end + +return setmetatable(task, { __call = function(_, ...) return create(...) end }) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 41233cd..e3ed50d 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -28,7 +28,7 @@ local mpd = {} local function worker(args) local args = args or {} local timeout = args.timeout or 2 - local password = args.password or "" + local password = args.password or "\"\"" local host = args.host or "127.0.0.1" local port = args.port or "6600" local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" diff --git a/widgets/task.lua b/widgets/task.lua deleted file mode 100644 index f2b49f4..0000000 --- a/widgets/task.lua +++ /dev/null @@ -1,124 +0,0 @@ - ---[[ - - Licensed under GNU General Public License v2 - * (c) 2013, Jan Xie - ---]] - -local icons_dir = require("lain.helpers").icons_dir - -local awful = require("awful") -local beautiful = require("beautiful") -local naughty = require("naughty") - -local io = io -local tonumber = tonumber - -local setmetatable = setmetatable - --- task notification --- lain.widgets.task -local task = {} -local task_notification = nil - -function task:hide() - if task_notification ~= nil then - naughty.destroy(task_notification) - task_notification = nil - end -end - -function task:show() - task:hide() - - local f, c_text - - f = io.popen('task') - c_text = "Tasks next\n" - .. "" - .. f:read("*all") .. "\n" - .. "" - f:close() - - task_notification = naughty.notify({ text = c_text, - icon = task.notify_icon, - position = task.position, - fg = task.fg, - bg = task.bg, - timeout = task.timeout }) -end - -function task:add(...) - local f = io.popen("task add " .. ...) - c_text = "" - .. f:read("*all") .. "\n" - .. "" - - naughty.notify({ text = c_text, - icon = task.notify_icon, - position = task.position, - fg = task.fg, - bg = task.bg, - timeout = task.timeout}) -end - -function task:prompt_add() - awful.prompt.run( { prompt = "Add task: " }, - mypromptbox[mouse.screen].widget, - function (...) - task:add(...) - end, - nil, - awful.util.getdir("cache") .. "/history_task_add") -end - -function task:execute(...) - local f = io.popen("task " .. ...) - c_text = "" - .. f:read("*all") .. "\n" - .. "" - - naughty.notify({ text = c_text, - icon = task.notify_icon, - position = task.position, - fg = task.fg, - bg = task.bg, - timeout = task.timeout}) -end - -function task:prompt() - awful.prompt.run( { prompt = "Task: " }, - mypromptbox[mouse.screen].widget, - function (...) - task:execute(...) - end, - nil, - awful.util.getdir("cache") .. "/history_task") -end - -function task:attach(widget, args) - local args = args or {} - task.font_size = tonumber(args.font_size) or 12 - task.font = beautiful.font:sub(beautiful.font:find(""), - beautiful.font:find(" ")) - task.fg = args.fg or beautiful.fg_normal or "#FFFFFF" - task.bg = args.bg or beautiful.bg_normal or "#FFFFFF" - task.position = args.position or "top_right" - task.timeout = args.timeout or 7 - - task.notify_icon = icons_dir .. "taskwarrior.png" - - widget:connect_signal("mouse::enter", function () task:show() end) - widget:connect_signal("mouse::leave", function () task:hide() end) - widget:buttons(awful.util.table.join( awful.button({ }, 1, function () - task:show(0, -1) end), - awful.button({ }, 3, function () - task:show(0, 1) end) )) -end - -return setmetatable(task, { __call = function(_, ...) return create(...) end }) diff --git a/wiki b/wiki index 476e9f5..91217d6 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 476e9f57bb66cec635ce61170a57f49299e6c715 +Subproject commit 91217d6bad68401ee926ca79d3ef917525507321 From f4f4f1e14dae1191571893b26e9f4667d78acb5e Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 25 Sep 2013 15:21:21 +0200 Subject: [PATCH 042/546] contrib section started\! --- widgets/contrib/task.lua | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/widgets/contrib/task.lua b/widgets/contrib/task.lua index 88baa71..a6c9f31 100644 --- a/widgets/contrib/task.lua +++ b/widgets/contrib/task.lua @@ -38,11 +38,11 @@ function task:show() local f, c_text f = io.popen('task') - c_text = "" .. f:read("*all"):gsub("\n*$", "") - .. "" + .. "" f:close() task_notification = naughty.notify({ title = "[task next]", @@ -59,19 +59,20 @@ function task:prompt_add() mypromptbox[mouse.screen].widget, function (...) local f = io.popen("task add " .. ...) - c_text = "\n" .. f:read("*all") - .. "" + .. "" + f:close() naughty.notify({ - text = c_text, - icon = task.notify_icon, + text = c_text, + icon = task.notify_icon, position = task.position, - fg = task.fg, - bg = task.bg, - timeout = task.timeout + fg = task.fg, + bg = task.bg, + timeout = task.timeout }) end, nil, @@ -83,27 +84,28 @@ function task:prompt_search() mypromptbox[mouse.screen].widget, function (...) local f = io.popen("task " .. ...) - c_text = f:read("*all") + c_text = f:read("*all"):gsub(" \n*$", "") f:close() if string.len(c_text) == 0 then c_text = "No results found." else - c_text = "" - .. c_text .. "\n" - .. "" + .. c_text + .. "" end naughty.notify({ - text = c_text, - icon = task.notify_icon, + title = "[task next " .. ... .. "]", + text = c_text, + icon = task.notify_icon, position = task.position, - fg = task.fg, - bg = task.bg, - timeout = task.timeout + fg = task.fg, + bg = task.bg, + timeout = task.timeout }) end, nil, From 81b00801f182d5df20151e6a27431ca9b431e0aa Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 25 Sep 2013 15:22:41 +0200 Subject: [PATCH 043/546] readme updated --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 66d846c..7ee0025 100644 --- a/README.rst +++ b/README.rst @@ -28,7 +28,7 @@ Just make sure that: - Your code fits with the general style of the module. In particular, you should use the same indentation pattern that the code uses, and also avoid adding space at the ends of lines. -- Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions or using `lain.helpers`. If something is unclear, and you can't write it in such a way that it will be clear, explain it with a comment. +- Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions or using ``lain.helpers``. If something is unclear, and you can't write it in such a way that it will be clear, explain it with a comment. - You test your changes before submitting to make sure that not only your code work, but have not broken other parts of the module too! From dc60201567ec9bf39164d90a220cd61338ade23c Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 25 Sep 2013 15:23:50 +0200 Subject: [PATCH 044/546] readme updated --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 7ee0025..7f63942 100644 --- a/README.rst +++ b/README.rst @@ -30,7 +30,7 @@ Just make sure that: - Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions or using ``lain.helpers``. If something is unclear, and you can't write it in such a way that it will be clear, explain it with a comment. -- You test your changes before submitting to make sure that not only your code work, but have not broken other parts of the module too! +- You test your changes before submitting to make sure that not only your code works, but have not broken other parts of the module too! - You update `wiki` submodule with a thorough section. From e95d34ccd81feb097940f634f51baa3540367dd2 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 25 Sep 2013 15:24:18 +0200 Subject: [PATCH 045/546] readme updated --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 7f63942..f7e5611 100644 --- a/README.rst +++ b/README.rst @@ -32,9 +32,9 @@ Just make sure that: - You test your changes before submitting to make sure that not only your code works, but have not broken other parts of the module too! -- You update `wiki` submodule with a thorough section. +- You update ``wiki`` submodule with a thorough section. -Contributed widgets have to be put it in `lain/widget/contrib`. +Contributed widgets have to be put it in ``lain/widget/contrib``. Screenshots ----------- From 3831b4b2d32845b889858ec499dbeb9d49e88967 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 25 Sep 2013 16:36:19 +0200 Subject: [PATCH 046/546] bat: compatibility fix --- widgets/bat.lua | 33 +++++++++++++++------------------ wiki | 2 +- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 7b14a9a..0bb5eff 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -38,27 +38,24 @@ local function worker(args) watt = "N/A" } - local present = first_line("/sys/class/power_supply/" - .. battery - .. "/present") + local bstr = "/sys/class/power_supply/" .. battery + + local present = first_line(bstr .. "/present") if present == "1" then - local rate = first_line("/sys/class/power_supply/" - .. battery .. - "/power_now") - local ratev = first_line("/sys/class/power_supply/" - .. battery .. - "/voltage_now") - local rem = first_line("/sys/class/power_supply/" - .. battery .. - "/energy_now") - local tot = first_line("/sys/class/power_supply/" - .. battery .. - "/energy_full") - bat_now.status = first_line("/sys/class/power_supply/" - .. battery .. - "/status") + local rate = first_line(bstr .. "/power_now") or + first_line(bstr .. "/current_now") + + local ratev = first_line(bstr .. "/voltage_now") + + local rem = first_line(bstr .. "/energy_now") or + first_line(bstr .. "/charge_now") + + local tot = first_line(bstr .. "/energy_full") or + first_line(bstr .. "/charge_full") + + bat_now.status = first_line(bstr .. "/status") or "N/A" local time_rat = 0 if bat_now.status == "Charging" diff --git a/wiki b/wiki index 91217d6..807599b 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 91217d6bad68401ee926ca79d3ef917525507321 +Subproject commit 807599b7446b4866a8a2030b9a0fb4fd4f9ce754 From 4664741483e8c395d4e042a91552925ab63e5130 Mon Sep 17 00:00:00 2001 From: Conor Heine Date: Thu, 26 Sep 2013 01:20:29 -0400 Subject: [PATCH 047/546] added basic tp_smapi battery widget for thinkpads with hover-expandable status --- widgets/contrib/tpbat/init.lua | 152 ++++++++++++++++++++++++++++++++ widgets/contrib/tpbat/smapi.lua | 99 +++++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 widgets/contrib/tpbat/init.lua create mode 100644 widgets/contrib/tpbat/smapi.lua diff --git a/widgets/contrib/tpbat/init.lua b/widgets/contrib/tpbat/init.lua new file mode 100644 index 0000000..673b66c --- /dev/null +++ b/widgets/contrib/tpbat/init.lua @@ -0,0 +1,152 @@ +--[[ + tpbat.lua + Battery status widget for ThinkPad laptops that use SMAPI + lain.widgets.contrib.tpbat + + More on tp_smapi: http://www.thinkwiki.org/wiki/Tp_smapi + + Licensed under GNU General Public License v2 + * (c) 2013, Conor Heine + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + +--]] + +local newtimer = require("lain.helpers").newtimer +local first_line = require("lain.helpers").first_line +local beautiful = require("beautiful") +local naughty = require("naughty") +local wibox = require("wibox") +local smapi = require("lain.widgets.contrib.tpbat.smapi") -- Ugly :( + +local string = { format = string.format } +local math = { floor = math.floor } +local tostring = tostring +local setmetatable = setmetatable + +-- ThinkPad SMAPI-enabled battery info widget +local tpbat = { } + +local tpbat_notification = nil + +function tpbat:hide() + if tpbat_notification ~= nil then + naughty.destroy(tpbat_notification) + tpbat_notification = nil + end +end + +function tpbat:show(t_out) + tpbat:hide() + + local bat = self.bat + if bat == nil or not bat:installed() then return end + + local mfgr = bat:get('manufacturer') or "no_mfgr" + local model = bat:get('model') or "no_model" + local chem = bat:get('chemistry') or "no_chem" + local status = bat:get('state') or "nil" + local time = bat:remaining_time() + local msg = "\t" + + if status ~= "idle" and status ~= "nil" then + if time == "N/A" then + msg = "...Calculating time remaining..." + else + msg = time .. (status == "charging" and " until charged" or " remaining") + end + else + msg = "On AC Power" + end + + local str = string.format("%s : %s %s (%s)\n", bat.name, mfgr, model, chem) + str = str .. string.format("\n%s \t\t\t %s", status:upper(), msg) + + tpbat_notification = naughty.notify({ + preset = { fg = beautiful.fg_normal }, + text = str, + timeout = t_out + }) +end + +function tpbat.register(args) + local args = args or {} + local timeout = args.timeout or 30 + local battery = args.battery or "BAT0" + local settings = args.settings or function() end + + tpbat.bat = smapi:battery(battery) -- Create a new battery + local bat = tpbat.bat + + tpbat.widget = wibox.widget.textbox('') + + if bat:get('state') == nil then + local n = naughty.notify({ + title = "SMAPI Battery Warning: Unable to read battery state!", + text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths.", + position = "top_right", + timeout = 15, + fg="#202020", + bg="#cdcdcd", + ontop = true + }) + end + + function update() + bat_now = { + status = "Not present", + perc = "N/A", + time = "N/A", + watt = "N/A" + } + + if bat:installed() + then + bat_now.status = bat:status() + bat_now.perc = bat:percent() + bat_now.time = bat:remaining_time() + -- bat_now.watt = string.format("%.2fW", (VOLTS * AMPS) / 1e12) + + -- notifications for low and critical states + if bat_now.perc <= 5 + then + tpbat.id = naughty.notify({ + text = "shutdown imminent", + title = "battery nearly exhausted", + position = "top_right", + timeout = 15, + fg="#000000", + bg="#ffffff", + ontop = true, + replaces_id = tpbat.id + }).id + elseif bat_now.perc <= 15 + then + tpbat.id = naughty.notify({ + text = "plug the cable", + title = "battery low", + position = "top_right", + timeout = 15, + fg="#202020", + bg="#cdcdcd", + ontop = true, + replaces_id = tpbat.id + }).id + end + + bat_now.perc = tostring(bat_now.perc) + end + + widget = tpbat.widget -- 'widget' needed in rc.lua (following convention) + settings() + end + + newtimer("tpbat", timeout, update) + + widget:connect_signal('mouse::enter', function () tpbat:show(0) end) + widget:connect_signal('mouse::leave', function () tpbat:hide() end) + + return tpbat.widget +end + +return setmetatable(tpbat, { __call = function(_, ...) return tpbat.register(...) end }) diff --git a/widgets/contrib/tpbat/smapi.lua b/widgets/contrib/tpbat/smapi.lua new file mode 100644 index 0000000..6024fa9 --- /dev/null +++ b/widgets/contrib/tpbat/smapi.lua @@ -0,0 +1,99 @@ +--[[ + smapi.lua + Interface with thinkpad battery information + + Licensed under GNU General Public License v2 + * (c) 2013, Conor Heine + +--]] + +local first_line = require("lain.helpers").first_line + +local string = { format = string.format } +local tonumber = tonumber +local setmetatable = setmetatable + +local smapi = {} + +local apipath = "/sys/devices/platform/smapi" + +-- Most are readable values, but some can be written to (not implemented, yet?) +local readable = { + barcoding = true, + charging_max_current = true, + charging_max_voltage = true, + chemistry = true, + current_avg = true, + current_now = true, + cycle_count = true, + design_capacity = true, + design_voltage = true, + dump = true, + first_use_date = true, + force_discharge = false, + group0_voltage = true, + group1_voltage = true, + group2_voltage = true, + group3_voltage = true, + inhibit_charge_minutes = false, + installed = true, + last_full_capacity = true, + manufacture_date = true, + manufacturer = true, + model = true, + power_avg = true, + power_now = true, + remaining_capacity = true, + remaining_charging_time = true, + remaining_percent = true, + remaining_percent_error = true, + remaining_running_time = true, + remaining_running_time_now = true, + serial = true, + start_charge_thresh = false, + state = true, + stop_charge_thresh = false, + temperature = true, + voltage = true, +} + +function smapi:battery(name) + local bat = {} + + bat.name = name + bat.path = apipath .. "/" .. name + + function bat:get(item) + return self.path ~= nil and readable[item] and first_line(self.path .. "/" .. item) or nil + end + + function bat:installed() + return self:get("installed") == "1" + end + + function bat:status() + return self:get('state') + end + + -- Remaining time can either be time until battery dies or time until charging completes + function bat:remaining_time() + local time_val = bat_now.status == 'discharging' and 'remaining_running_time' or 'remaining_charging_time' + local mins_left = self:get(time_val) + + if mins_left:find("^%d+") == nil then + return "N/A" + end + + local hrs = mins_left / 60 + local min = mins_left % 60 + return string.format("%02d:%02d", hrs, min) + end + + function bat:percent() + return tonumber(self:get("remaining_percent")) + end + + return setmetatable(bat, {__metatable = false, __newindex = false}) +end + +return smapi \ No newline at end of file From 3192a938cb9ddf16e1d36cbd9acbe92814177987 Mon Sep 17 00:00:00 2001 From: Conor Heine Date: Thu, 26 Sep 2013 01:30:39 -0400 Subject: [PATCH 048/546] fixed formatting to follow contrib style --- widgets/contrib/tpbat/init.lua | 24 +++--- widgets/contrib/tpbat/smapi.lua | 130 ++++++++++++++++---------------- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/widgets/contrib/tpbat/init.lua b/widgets/contrib/tpbat/init.lua index 673b66c..d46697a 100644 --- a/widgets/contrib/tpbat/init.lua +++ b/widgets/contrib/tpbat/init.lua @@ -65,7 +65,7 @@ function tpbat:show(t_out) tpbat_notification = naughty.notify({ preset = { fg = beautiful.fg_normal }, text = str, - timeout = t_out + timeout = t_out }) end @@ -80,17 +80,17 @@ function tpbat.register(args) tpbat.widget = wibox.widget.textbox('') - if bat:get('state') == nil then - local n = naughty.notify({ - title = "SMAPI Battery Warning: Unable to read battery state!", - text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths.", - position = "top_right", - timeout = 15, - fg="#202020", - bg="#cdcdcd", - ontop = true - }) - end + if bat:get('state') == nil then + local n = naughty.notify({ + title = "SMAPI Battery Warning: Unable to read battery state!", + text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths.", + position = "top_right", + timeout = 15, + fg="#202020", + bg="#cdcdcd", + ontop = true + }) + end function update() bat_now = { diff --git a/widgets/contrib/tpbat/smapi.lua b/widgets/contrib/tpbat/smapi.lua index 6024fa9..3291cc2 100644 --- a/widgets/contrib/tpbat/smapi.lua +++ b/widgets/contrib/tpbat/smapi.lua @@ -19,81 +19,81 @@ local apipath = "/sys/devices/platform/smapi" -- Most are readable values, but some can be written to (not implemented, yet?) local readable = { - barcoding = true, - charging_max_current = true, - charging_max_voltage = true, - chemistry = true, - current_avg = true, - current_now = true, - cycle_count = true, - design_capacity = true, - design_voltage = true, - dump = true, - first_use_date = true, - force_discharge = false, - group0_voltage = true, - group1_voltage = true, - group2_voltage = true, - group3_voltage = true, - inhibit_charge_minutes = false, - installed = true, - last_full_capacity = true, - manufacture_date = true, - manufacturer = true, - model = true, - power_avg = true, - power_now = true, - remaining_capacity = true, - remaining_charging_time = true, - remaining_percent = true, - remaining_percent_error = true, - remaining_running_time = true, - remaining_running_time_now = true, - serial = true, - start_charge_thresh = false, - state = true, - stop_charge_thresh = false, - temperature = true, - voltage = true, + barcoding = true, + charging_max_current = true, + charging_max_voltage = true, + chemistry = true, + current_avg = true, + current_now = true, + cycle_count = true, + design_capacity = true, + design_voltage = true, + dump = true, + first_use_date = true, + force_discharge = false, + group0_voltage = true, + group1_voltage = true, + group2_voltage = true, + group3_voltage = true, + inhibit_charge_minutes = false, + installed = true, + last_full_capacity = true, + manufacture_date = true, + manufacturer = true, + model = true, + power_avg = true, + power_now = true, + remaining_capacity = true, + remaining_charging_time = true, + remaining_percent = true, + remaining_percent_error = true, + remaining_running_time = true, + remaining_running_time_now = true, + serial = true, + start_charge_thresh = false, + state = true, + stop_charge_thresh = false, + temperature = true, + voltage = true, } function smapi:battery(name) - local bat = {} + local bat = {} - bat.name = name - bat.path = apipath .. "/" .. name - - function bat:get(item) - return self.path ~= nil and readable[item] and first_line(self.path .. "/" .. item) or nil - end + bat.name = name + bat.path = apipath .. "/" .. name + + function bat:get(item) + return self.path ~= nil and readable[item] and first_line(self.path .. "/" .. item) or nil + end - function bat:installed() - return self:get("installed") == "1" - end + function bat:installed() + return self:get("installed") == "1" + end - function bat:status() - return self:get('state') - end + function bat:status() + return self:get('state') + end - -- Remaining time can either be time until battery dies or time until charging completes - function bat:remaining_time() - local time_val = bat_now.status == 'discharging' and 'remaining_running_time' or 'remaining_charging_time' - local mins_left = self:get(time_val) + -- Remaining time can either be time until battery dies or time until charging completes + function bat:remaining_time() + local time_val = bat_now.status == 'discharging' and 'remaining_running_time' or 'remaining_charging_time' + local mins_left = self:get(time_val) - if mins_left:find("^%d+") == nil then - return "N/A" - end - - local hrs = mins_left / 60 - local min = mins_left % 60 - return string.format("%02d:%02d", hrs, min) - end + if mins_left:find("^%d+") == nil then + return "N/A" + end + + local hrs = mins_left / 60 + local min = mins_left % 60 + return string.format("%02d:%02d", hrs, min) + end - function bat:percent() - return tonumber(self:get("remaining_percent")) - end + function bat:percent() + return tonumber(self:get("remaining_percent")) + end - return setmetatable(bat, {__metatable = false, __newindex = false}) + return setmetatable(bat, {__metatable = false, __newindex = false}) end return smapi \ No newline at end of file From 68037080cd50887746db0529e20c4bd1f8c404d4 Mon Sep 17 00:00:00 2001 From: Conor Heine Date: Thu, 26 Sep 2013 01:49:37 -0400 Subject: [PATCH 049/546] fixed brace style to match project's --- widgets/contrib/tpbat/init.lua | 12 ++++++++---- widgets/contrib/tpbat/smapi.lua | 5 +++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/widgets/contrib/tpbat/init.lua b/widgets/contrib/tpbat/init.lua index d46697a..1bb6a9b 100644 --- a/widgets/contrib/tpbat/init.lua +++ b/widgets/contrib/tpbat/init.lua @@ -30,7 +30,8 @@ local tpbat = { } local tpbat_notification = nil function tpbat:hide() - if tpbat_notification ~= nil then + if tpbat_notification ~= nil + then naughty.destroy(tpbat_notification) tpbat_notification = nil end @@ -49,8 +50,10 @@ function tpbat:show(t_out) local time = bat:remaining_time() local msg = "\t" - if status ~= "idle" and status ~= "nil" then - if time == "N/A" then + if status ~= "idle" and status ~= "nil" + then + if time == "N/A" + then msg = "...Calculating time remaining..." else msg = time .. (status == "charging" and " until charged" or " remaining") @@ -80,7 +83,8 @@ function tpbat.register(args) tpbat.widget = wibox.widget.textbox('') - if bat:get('state') == nil then + if bat:get('state') == nil + then local n = naughty.notify({ title = "SMAPI Battery Warning: Unable to read battery state!", text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths.", diff --git a/widgets/contrib/tpbat/smapi.lua b/widgets/contrib/tpbat/smapi.lua index 3291cc2..59b916b 100644 --- a/widgets/contrib/tpbat/smapi.lua +++ b/widgets/contrib/tpbat/smapi.lua @@ -80,8 +80,9 @@ function smapi:battery(name) local time_val = bat_now.status == 'discharging' and 'remaining_running_time' or 'remaining_charging_time' local mins_left = self:get(time_val) - if mins_left:find("^%d+") == nil then - return "N/A" + if mins_left:find("^%d+") == nil + then + return "N/A" end local hrs = mins_left / 60 From b963bb6bde2b708e6f01b8a9d469d960501a2e0a Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 26 Sep 2013 11:35:59 +0200 Subject: [PATCH 050/546] thinkpad bat widget integrated --- widgets/contrib/init.lua | 2 +- widgets/contrib/tpbat/init.lua | 55 +++++++++++--------- widgets/contrib/tpbat/smapi.lua | 92 +++++++++++++++++---------------- 3 files changed, 79 insertions(+), 70 deletions(-) diff --git a/widgets/contrib/init.lua b/widgets/contrib/init.lua index 81321c6..9a9fa63 100644 --- a/widgets/contrib/init.lua +++ b/widgets/contrib/init.lua @@ -4,7 +4,7 @@ Lain Layouts, widgets and utilities for Awesome WM - User contributed widgets section + Users contributed widgets section Licensed under GNU General Public License v2 * (c) 2013, Luke Bonham diff --git a/widgets/contrib/tpbat/init.lua b/widgets/contrib/tpbat/init.lua index 1bb6a9b..206fd38 100644 --- a/widgets/contrib/tpbat/init.lua +++ b/widgets/contrib/tpbat/init.lua @@ -1,36 +1,41 @@ + --[[ - tpbat.lua - Battery status widget for ThinkPad laptops that use SMAPI - lain.widgets.contrib.tpbat - - More on tp_smapi: http://www.thinkwiki.org/wiki/Tp_smapi - - Licensed under GNU General Public License v2 - * (c) 2013, Conor Heine - * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann - + + tpbat.lua + Battery status widget for ThinkPad laptops that use SMAPI + lain.widgets.contrib.tpbat + + More on tp_smapi: http://www.thinkwiki.org/wiki/Tp_smapi + + Licensed under GNU General Public License v2 + * (c) 2013, Conor Heine + * (c) 2013, Luke Bonham + * (c) 2010-2012, Peter Hofmann + --]] +local debug = { getinfo = debug.getinfo } local newtimer = require("lain.helpers").newtimer local first_line = require("lain.helpers").first_line local beautiful = require("beautiful") local naughty = require("naughty") local wibox = require("wibox") -local smapi = require("lain.widgets.contrib.tpbat.smapi") -- Ugly :( local string = { format = string.format } local math = { floor = math.floor } local tostring = tostring local setmetatable = setmetatable --- ThinkPad SMAPI-enabled battery info widget -local tpbat = { } +package.path = debug.getinfo(1,"S").source:match[[^@?(.*[\/])[^\/]-$]] .. "?.lua;" .. package.path +local smapi = require("smapi") +-- ThinkPad SMAPI-enabled battery info widget +-- lain.widgets.contrib.tpbat +local tpbat = { } local tpbat_notification = nil function tpbat:hide() - if tpbat_notification ~= nil + if tpbat_notification ~= nil then naughty.destroy(tpbat_notification) tpbat_notification = nil @@ -39,8 +44,10 @@ end function tpbat:show(t_out) tpbat:hide() - - local bat = self.bat + + local bat = self.bat + local t_out = t_out or 0 + if bat == nil or not bat:installed() then return end local mfgr = bat:get('manufacturer') or "no_mfgr" @@ -50,9 +57,9 @@ function tpbat:show(t_out) local time = bat:remaining_time() local msg = "\t" - if status ~= "idle" and status ~= "nil" + if status ~= "idle" and status ~= "nil" then - if time == "N/A" + if time == "N/A" then msg = "...Calculating time remaining..." else @@ -63,7 +70,7 @@ function tpbat:show(t_out) end local str = string.format("%s : %s %s (%s)\n", bat.name, mfgr, model, chem) - str = str .. string.format("\n%s \t\t\t %s", status:upper(), msg) + .. string.format("\n%s \t\t\t %s", status:upper(), msg) tpbat_notification = naughty.notify({ preset = { fg = beautiful.fg_normal }, @@ -80,10 +87,10 @@ function tpbat.register(args) tpbat.bat = smapi:battery(battery) -- Create a new battery local bat = tpbat.bat - + tpbat.widget = wibox.widget.textbox('') - if bat:get('state') == nil + if bat:get('state') == nil then local n = naughty.notify({ title = "SMAPI Battery Warning: Unable to read battery state!", @@ -141,13 +148,13 @@ function tpbat.register(args) bat_now.perc = tostring(bat_now.perc) end - widget = tpbat.widget -- 'widget' needed in rc.lua (following convention) + widget = tpbat.widget settings() end newtimer("tpbat", timeout, update) - widget:connect_signal('mouse::enter', function () tpbat:show(0) end) + widget:connect_signal('mouse::enter', function () tpbat:show() end) widget:connect_signal('mouse::leave', function () tpbat:hide() end) return tpbat.widget diff --git a/widgets/contrib/tpbat/smapi.lua b/widgets/contrib/tpbat/smapi.lua index 59b916b..862d4cd 100644 --- a/widgets/contrib/tpbat/smapi.lua +++ b/widgets/contrib/tpbat/smapi.lua @@ -1,9 +1,11 @@ ---[[ - smapi.lua - Interface with thinkpad battery information +--[[ + + smapi.lua + Interface with thinkpad battery information + Licensed under GNU General Public License v2 - * (c) 2013, Conor Heine + * (c) 2013, Conor Heine --]] @@ -19,42 +21,42 @@ local apipath = "/sys/devices/platform/smapi" -- Most are readable values, but some can be written to (not implemented, yet?) local readable = { - barcoding = true, - charging_max_current = true, - charging_max_voltage = true, - chemistry = true, - current_avg = true, - current_now = true, - cycle_count = true, - design_capacity = true, - design_voltage = true, - dump = true, - first_use_date = true, - force_discharge = false, - group0_voltage = true, - group1_voltage = true, - group2_voltage = true, - group3_voltage = true, - inhibit_charge_minutes = false, - installed = true, - last_full_capacity = true, - manufacture_date = true, - manufacturer = true, - model = true, - power_avg = true, - power_now = true, - remaining_capacity = true, - remaining_charging_time = true, - remaining_percent = true, - remaining_percent_error = true, - remaining_running_time = true, + barcoding = true, + charging_max_current = true, + charging_max_voltage = true, + chemistry = true, + current_avg = true, + current_now = true, + cycle_count = true, + design_capacity = true, + design_voltage = true, + dump = true, + first_use_date = true, + force_discharge = false, + group0_voltage = true, + group1_voltage = true, + group2_voltage = true, + group3_voltage = true, + inhibit_charge_minutes = false, + installed = true, + last_full_capacity = true, + manufacture_date = true, + manufacturer = true, + model = true, + power_avg = true, + power_now = true, + remaining_capacity = true, + remaining_charging_time = true, + remaining_percent = true, + remaining_percent_error = true, + remaining_running_time = true, remaining_running_time_now = true, - serial = true, - start_charge_thresh = false, - state = true, - stop_charge_thresh = false, - temperature = true, - voltage = true, + serial = true, + start_charge_thresh = false, + state = true, + stop_charge_thresh = false, + temperature = true, + voltage = true, } function smapi:battery(name) @@ -62,7 +64,7 @@ function smapi:battery(name) bat.name = name bat.path = apipath .. "/" .. name - + function bat:get(item) return self.path ~= nil and readable[item] and first_line(self.path .. "/" .. item) or nil end @@ -80,11 +82,11 @@ function smapi:battery(name) local time_val = bat_now.status == 'discharging' and 'remaining_running_time' or 'remaining_charging_time' local mins_left = self:get(time_val) - if mins_left:find("^%d+") == nil - then - return "N/A" + if mins_left:find("^%d+") == nil + then + return "N/A" end - + local hrs = mins_left / 60 local min = mins_left % 60 return string.format("%02d:%02d", hrs, min) @@ -97,4 +99,4 @@ function smapi:battery(name) return setmetatable(bat, {__metatable = false, __newindex = false}) end -return smapi \ No newline at end of file +return smapi From 2bf4d81b5a4e4dc53f86255b5605937ffb6f1173 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 26 Sep 2013 11:54:30 +0200 Subject: [PATCH 051/546] tpbat wiki entry added --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 807599b..4a81ad4 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 807599b7446b4866a8a2030b9a0fb4fd4f9ce754 +Subproject commit 4a81ad47d143e42e8b9de92ebb8cd963d5bd6515 From 5ebdab637085b1fbf20e47aba6c04f04191bf0ce Mon Sep 17 00:00:00 2001 From: Conor Heine Date: Thu, 26 Sep 2013 16:01:09 -0400 Subject: [PATCH 052/546] silence warnings when battery is <15%, but charging --- widgets/bat.lua | 49 ++++++++++++++++--------------- widgets/contrib/tpbat/init.lua | 53 ++++++++++++++++++---------------- 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 0bb5eff..789c694 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -74,30 +74,33 @@ local function worker(args) bat_now.watt = string.format("%.2fW", (rate * ratev) / 1e12) -- notifications for low and critical states - if bat_now.perc <= 5 + if bat_new.status == "Discharging" then - bat.id = naughty.notify({ - text = "shutdown imminent", - title = "battery nearly exhausted", - position = "top_right", - timeout = 15, - fg="#000000", - bg="#ffffff", - ontop = true, - replaces_id = bat.id - }).id - elseif bat_now.perc <= 15 - then - bat.id = naughty.notify({ - text = "plug the cable", - title = "battery low", - position = "top_right", - timeout = 15, - fg="#202020", - bg="#cdcdcd", - ontop = true, - replaces_id = bat.id - }).id + if bat_now.perc <= 5 + then + bat.id = naughty.notify({ + text = "shutdown imminent", + title = "battery nearly exhausted", + position = "top_right", + timeout = 15, + fg="#000000", + bg="#ffffff", + ontop = true, + replaces_id = bat.id + }).id + elseif bat_now.perc <= 15 + then + bat.id = naughty.notify({ + text = "plug the cable", + title = "battery low", + position = "top_right", + timeout = 15, + fg="#202020", + bg="#cdcdcd", + ontop = true, + replaces_id = bat.id + }).id + end end bat_now.perc = string.format("%d", bat_now.perc) diff --git a/widgets/contrib/tpbat/init.lua b/widgets/contrib/tpbat/init.lua index 206fd38..dbf90aa 100644 --- a/widgets/contrib/tpbat/init.lua +++ b/widgets/contrib/tpbat/init.lua @@ -113,36 +113,39 @@ function tpbat.register(args) if bat:installed() then - bat_now.status = bat:status() + bat_now.status = bat:status() or "N/A" bat_now.perc = bat:percent() bat_now.time = bat:remaining_time() -- bat_now.watt = string.format("%.2fW", (VOLTS * AMPS) / 1e12) - -- notifications for low and critical states - if bat_now.perc <= 5 + -- notifications for low and critical states (when discharging) + if bat_now.status == "discharging" then - tpbat.id = naughty.notify({ - text = "shutdown imminent", - title = "battery nearly exhausted", - position = "top_right", - timeout = 15, - fg="#000000", - bg="#ffffff", - ontop = true, - replaces_id = tpbat.id - }).id - elseif bat_now.perc <= 15 - then - tpbat.id = naughty.notify({ - text = "plug the cable", - title = "battery low", - position = "top_right", - timeout = 15, - fg="#202020", - bg="#cdcdcd", - ontop = true, - replaces_id = tpbat.id - }).id + if bat_now.perc <= 5 + then + tpbat.id = naughty.notify({ + text = "shutdown imminent", + title = "battery nearly exhausted", + position = "top_right", + timeout = 15, + fg="#000000", + bg="#ffffff", + ontop = true, + replaces_id = tpbat.id + }).id + elseif bat_now.perc <= 15 + then + tpbat.id = naughty.notify({ + text = "plug the cable", + title = "battery low", + position = "top_right", + timeout = 15, + fg="#202020", + bg="#cdcdcd", + ontop = true, + replaces_id = tpbat.id + }).id + end end bat_now.perc = tostring(bat_now.perc) From 94a9ebeca1febbf8e9aa395803ee175ccfbd6319 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 27 Sep 2013 13:09:29 +0200 Subject: [PATCH 053/546] counterfix on pull #6 --- widgets/bat.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 789c694..fd99e4d 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -74,7 +74,7 @@ local function worker(args) bat_now.watt = string.format("%.2fW", (rate * ratev) / 1e12) -- notifications for low and critical states - if bat_new.status == "Discharging" + if bat_now.status == "Discharging" then if bat_now.perc <= 5 then From 0be3219868cd77cad70bb81b4ebe3bbc65e92cf5 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 28 Sep 2013 11:50:08 +0200 Subject: [PATCH 054/546] cal: changed default font_size --- README.rst | 2 +- widgets/calendar.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index f7e5611..75ed867 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ Description ----------- Successor of awesome-vain_, this costantly evolving module -provides new layouts, a set of widgets and utility functions +provides new layouts, a set of widgets and utility functions, in order to improve Awesome_ usability and configurability. Read the wiki_ for all the info. diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 8c707c8..f684fd7 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -105,7 +105,7 @@ end function calendar:attach(widget, args) local args = args or {} calendar.icons = args.icons or icons_dir .. "cal/white/" - calendar.font_size = tonumber(args.font_size) or 12 + calendar.font_size = tonumber(args.font_size) or 11 calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF" calendar.position = args.position or "top_right" From 7ab34da1e4e7846b02841461b8fc6c11f4fbf3ff Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 28 Sep 2013 13:05:05 +0200 Subject: [PATCH 055/546] dynamic tagging: move_tag added --- util/init.lua | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/util/init.lua b/util/init.lua index 06db0d4..e380cbb 100644 --- a/util/init.lua +++ b/util/init.lua @@ -191,6 +191,18 @@ function util.rename_tag(mypromptbox) end) end +-- Move current tag +-- pos in {-1, 1} <-> {previous, next} tag position +function util.move_tag(pos) + local tag = awful.tag.selected(mouse.screen) + local idx = awful.tag.getidx(tag) + if tonumber(pos) <= -1 then + awful.tag.move(idx - 1, tag) + else + awful.tag.move(idx + 1, tag) + end +end + -- Delete current tag (if empty) -- Any rule set on the tag shall be broken function util.remove_tag() From 73e43b92fd96fbe3d778479307ee243953b32750 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 28 Sep 2013 13:06:35 +0200 Subject: [PATCH 056/546] dynamic tagging: move_tag added --- util/init.lua | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/util/init.lua b/util/init.lua index e380cbb..cd1ac5d 100644 --- a/util/init.lua +++ b/util/init.lua @@ -38,10 +38,7 @@ function util.menu_clients_current_tags(menu, args) -- Final list of menu items. local cls_t = {} - if cls_tags == nil - then - return nil - end + if cls_tags == nil then return nil end -- For each selected tag get all clients of that tag and add them to -- the menu. A click on a menu item will raise that client. @@ -63,17 +60,11 @@ function util.menu_clients_current_tags(menu, args) end -- No clients? Then quit. - if #cls_t <= 0 - then - return nil - end + if #cls_t <= 0 then return nil end -- menu may contain some predefined values, otherwise start with a -- fresh menu. - if not menu - then - menu = {} - end + if not menu then menu = {} end -- Set the list of items and show the menu. menu.items = cls_t From a071d3989ac6712a75ca3eebf3d45f840773c309 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 29 Sep 2013 17:06:28 +0200 Subject: [PATCH 057/546] awesome-copycats: issue #16 fix --- widgets/bat.lua | 16 ++++++++++------ wiki | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index fd99e4d..c5279bd 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -15,6 +15,7 @@ local wibox = require("wibox") local math = { floor = math.floor } local string = { format = string.format } +local tonumber = tonumber local setmetatable = setmetatable @@ -57,6 +58,11 @@ local function worker(args) bat_now.status = first_line(bstr .. "/status") or "N/A" + rate = tonumber(rate) + ratev = tonumber(ratev) + rem = tonumber(rem) + tot = tonumber(tot) + local time_rat = 0 if bat_now.status == "Charging" then @@ -67,16 +73,16 @@ local function worker(args) end local hrs = math.floor(time_rat) - local min = (time_rat - hrs) * 60 + local min = math.floor((time_rat - hrs) * 60) bat_now.time = string.format("%02d:%02d", hrs, min) - bat_now.perc = (rem / tot) * 100 + bat_now.perc = string.format("%d", (rem / tot) * 100) bat_now.watt = string.format("%.2fW", (rate * ratev) / 1e12) -- notifications for low and critical states if bat_now.status == "Discharging" then - if bat_now.perc <= 5 + if tonumber(bat_now.perc) <= 5 then bat.id = naughty.notify({ text = "shutdown imminent", @@ -88,7 +94,7 @@ local function worker(args) ontop = true, replaces_id = bat.id }).id - elseif bat_now.perc <= 15 + elseif tonumber(bat_now.perc) <= 15 then bat.id = naughty.notify({ text = "plug the cable", @@ -102,8 +108,6 @@ local function worker(args) }).id end end - - bat_now.perc = string.format("%d", bat_now.perc) end widget = bat.widget diff --git a/wiki b/wiki index 4a81ad4..089c10d 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 4a81ad47d143e42e8b9de92ebb8cd963d5bd6515 +Subproject commit 089c10dff4317654c8436ddef408d993d617e202 From 033e2f4a499cb5e4db2af05832bc59834845eced Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 30 Sep 2013 16:29:18 +0200 Subject: [PATCH 058/546] awesome-copycats issue #16 fix --- widgets/bat.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/widgets/bat.lua b/widgets/bat.lua index c5279bd..aa89640 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -73,7 +73,10 @@ local function worker(args) end local hrs = math.floor(time_rat) + if hrs < 0 then hrs = 0 elseif hrs > 23 then hrs = 23 end + local min = math.floor((time_rat - hrs) * 60) + if min < 0 then min = 0 elseif min > 59 then min = 59 end bat_now.time = string.format("%02d:%02d", hrs, min) bat_now.perc = string.format("%d", (rem / tot) * 100) From 54f0b460c532eb43190314bab457f12f60c807a8 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 1 Oct 2013 13:45:07 +0200 Subject: [PATCH 059/546] yawn: bad connectivity fix --- widgets/yawn/init.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 2306fed..ecd1314 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -72,6 +72,14 @@ local function fetch_weather() -- Processing raw data weather_data = text:gsub("<.->", "") weather_data = weather_data:match("Current Conditions:.-Full") + + -- may still happens in case of bad connectivity + if weather_data == nil then + yawn.icon:set_image(icon_path .. "na.png") + yawn.widget:set_text("?") + return + end + weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ") weather_data = weather_data:gsub("Forecast:.-\n", "") weather_data = weather_data:gsub("\nFull", "") From 4a37fd29e977db1c45c3a76ed8f4a14d4cbc6f36 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 1 Oct 2013 13:47:37 +0200 Subject: [PATCH 060/546] yawn: bad connectivity fix --- widgets/yawn/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index ecd1314..38b741a 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -71,10 +71,10 @@ local function fetch_weather() -- Processing raw data weather_data = text:gsub("<.->", "") - weather_data = weather_data:match("Current Conditions:.-Full") + weather_data = weather_data:match("Current Conditions:.-Full") or "" -- may still happens in case of bad connectivity - if weather_data == nil then + if weather_data == "" then yawn.icon:set_image(icon_path .. "na.png") yawn.widget:set_text("?") return From d4c3ced229f7ef0c25258b70e5f30ba1ad99f99d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 2 Oct 2013 16:24:55 +0200 Subject: [PATCH 061/546] issue #7 fix --- widgets/fs.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/widgets/fs.lua b/widgets/fs.lua index b434056..7406e05 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -65,6 +65,7 @@ local function worker(args) function update() fs_info = {} + fs_now = {} local f = io.popen("LC_ALL=C df -kP") @@ -85,15 +86,15 @@ local function worker(args) -- chosen partition easy stuff -- you can however check whatever partition else - used = tonumber(fs_info[partition .. " used_p"]) - available = tonumber(fs_info[partition .. " avail_p"]) - size_mb = tonumber(fs_info[partition .. " size_mb"]) - size_gb = tonumber(fs_info[partition .. " size_gb"]) + fs_now.used = tonumber(fs_info[partition .. " used_p"]) or 0 + fs_now.available = tonumber(fs_info[partition .. " avail_p"]) or 0 + fs_now.size_mb = tonumber(fs_info[partition .. " size_mb"]) or 0 + fs_now.size_gb = tonumber(fs_info[partition .. " size_gb"]) or 0 widget = fs.widget settings() - if used >= 99 and not helpers.get_map("fs") + if fs_now.used >= 99 and not helpers.get_map("fs") then naughty.notify({ title = "warning", From 09c71d8ee60e3779b31aa3c9e7af8db7c9602a73 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 4 Oct 2013 18:53:33 +0200 Subject: [PATCH 062/546] issue #2 fix attempt; centerfair added; small fixes --- icons/layout/default/centerfair.png | Bin 0 -> 169 bytes icons/layout/default/centerfairw.png | Bin 0 -> 169 bytes icons/layout/zenburn/centerfair.png | Bin 0 -> 399 bytes layout/centerfair.lua | 147 +++++++++++++++++++++++++++ layout/termfair.lua | 13 ++- layout/uselessfair.lua | 11 +- layout/uselesspiral.lua | 10 +- layout/uselesstile.lua | 10 +- wiki | 2 +- 9 files changed, 176 insertions(+), 17 deletions(-) create mode 100644 icons/layout/default/centerfair.png create mode 100644 icons/layout/default/centerfairw.png create mode 100644 icons/layout/zenburn/centerfair.png create mode 100644 layout/centerfair.lua diff --git a/icons/layout/default/centerfair.png b/icons/layout/default/centerfair.png new file mode 100644 index 0000000000000000000000000000000000000000..188c24348eee1dd1efcc5beb7c2c72ff7f5320f0 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB_V)Sem}`Jdk263GxeO zaCmkj4a7+(lKOItEWyKbLh*2~7Yr Chb7ej literal 0 HcmV?d00001 diff --git a/icons/layout/default/centerfairw.png b/icons/layout/default/centerfairw.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4bcf5cd63ef3f1f3d7df24d941648ac1856f48 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@hljQC0!qCAg>jC6&7I;J!Gca%qgD@k*tT_@uLG}_)Usv|KTr2{-W(TJv zfsB^%ba4#PIG_B3pOt4u4?9l{k3&=K6vIoBJA^qIjz-K9mWjKl3RK77>FVdQ&MBb@ E00x{Y4FCWD literal 0 HcmV?d00001 diff --git a/icons/layout/zenburn/centerfair.png b/icons/layout/zenburn/centerfair.png new file mode 100644 index 0000000000000000000000000000000000000000..01cda8e89c14980825199778ed2c5defea611305 GIT binary patch literal 399 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmP)7mI+hilvrRIs*fvjHioZNX4zUw{7{F3?z zR>3q~ZsF$bA6CR2n5q1Qi%-q1x4|M}5}%O(m*>O(dRjBuKV9C}ATQ*qyKB>j#$s1v zlM52FSu3YYG@BfgYd$l1$?*dximTJ-KIkr+e&q<)X`%ThoMV2*KS5pE?%3B;LX5MPGS^t}1D%ZylES|D zx6aj`;-vN-T?&=oz@qhPd*tGOLbrD&J)by#QdnKJ{@;J^f_^W*dN9IllGpypp}X%% zM6=J_dn}=6uHWbL$MR)Yuj+fcbbqZetJ*649WM=Y<-6Xl2AS&V>gTe~DWM4flk|#Z literal 0 HcmV?d00001 diff --git a/layout/centerfair.lua b/layout/centerfair.lua new file mode 100644 index 0000000..d9ea677 --- /dev/null +++ b/layout/centerfair.lua @@ -0,0 +1,147 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Luke Bonham + * (c) 2012, Nicolas Estibals + * (c) 2010-2012, Peter Hofmann + +--]] + +local tag = require("awful.tag") +local beautiful = require("beautiful") +local math = { ceil = math.ceil, + floor = math.floor, + max = math.max } +local tonumber = tonumber + +local centerfair = { name = "centerfair" } + +function centerfair.arrange(p) + -- Layout with fixed number of vertical columns (read from nmaster). + -- Cols are centerded until there is nmaster columns, then windows + -- are stacked in the slave columns, with at most ncol clients per + -- column if possible. + + -- with nmaster=3 and ncol=1 you'll have + -- (1) (2) (3) + -- +---+---+---+ +-+---+---+-+ +---+---+---+ + -- | | | | | | | | | | | | | + -- | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | -> + -- | | | | | | | | | | | | | + -- +---+---+---+ +-+---+---+-+ +---+---+---+ + + -- (4) (5) + -- +---+---+---+ +---+---+---+ + -- | | | 3 | | | 2 | 4 | + -- + 1 + 2 +---+ -> + 1 +---+---+ + -- | | | 4 | | | 3 | 5 | + -- +---+---+---+ +---+---+---+ + + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width . + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + + -- Screen. + local wa = p.workarea + local cls = p.clients + + -- How many vertical columns? Read from nmaster on the tag. + local t = tag.selected(p.screen) + local num_x = centerfair.nmaster or tag.getnmaster(t) + local ncol = centerfair.ncol or tag.getncol(t) + + local width = math.floor((wa.width-(num_x+1)*useless_gap) / num_x) + + local offset_y = wa.y + useless_gap + if #cls < num_x + then + -- Less clients than the number of columns, let's center it! + local offset_x = wa.x + useless_gap + (wa.width - #cls*width - (#cls+1)*useless_gap) / 2 + local g = {} + g.width = width + g.height = wa.height - 2*useless_gap - 2 + g.y = offset_y + for i = 1, #cls do + g.x = offset_x + (i - 1) * (width + useless_gap + 2) + cls[i]:geometry(g) + end + else + -- More clients than the number of columns, let's arrange it! + local offset_x = wa.x + if useless_gap > 0 then + offset_x = offset_x + end + + -- Master client deserves a special treatement + local g = {} + g.width = wa.width - (num_x-1)*width -num_x*useless_gap - 2 + g.height = wa.height - 2*useless_gap - 2 + g.x = offset_x + useless_gap + g.y = offset_y + cls[1]:geometry(g) + + -- Treat the other clients + + -- Compute distribution of clients among columns + local num_y ={} + do + local remaining_clients = #cls-1 + local ncol_min = math.ceil(remaining_clients/(num_x-1)) + if ncol >= ncol_min + then + for i = (num_x-1), 1, -1 do + if (remaining_clients-i+1) < ncol + then + num_y[i] = remaining_clients-i + 1 + else + num_y[i] = ncol + end + remaining_clients = remaining_clients - num_y[i] + end + else + local rem = remaining_clients % (num_x-1) + if rem ==0 + then + for i = 1, num_x-1 do + num_y[i] = ncol_min + end + else + for i = 1, num_x-1 do + num_y[i] = ncol_min - 1 + end + for i = 0, rem-1 do + num_y[num_x-1-i] = num_y[num_x-1-i] + 1 + end + end + end + end + + -- Compute geometry of the other clients + local nclient = 2 + g.x = g.x + g.width+useless_gap + 2 + g.width = width + + if useless_gap > 0 then + g.width = g.width - useless_gap/2 - 2 + end + + for i = 1, (num_x-1) do + to_remove = 2 + g.height = math.floor((wa.height-useless_gap)/num_y[i]) + g.y = offset_y + for j = 0, (num_y[i]-2) do + cls[nclient]:geometry(g) + nclient = nclient + 1 + g.y = g.y + g.height+useless_gap + 2 + to_remove = to_remove + 2 + end + g.height = wa.height - num_y[i]*useless_gap - (num_y[i]-1)*g.height - useless_gap - to_remove + cls[nclient]:geometry(g) + nclient = nclient + 1 + g.x = g.x+g.width+useless_gap + 2 + end + end +end + +return centerfair diff --git a/layout/termfair.lua b/layout/termfair.lua index 4beab8f..89a44bb 100644 --- a/layout/termfair.lua +++ b/layout/termfair.lua @@ -89,27 +89,32 @@ function termfair.arrange(p) else g.height = height end + g.x = wa.x + this_x * width g.y = wa.y + this_y * height + if useless_gap > 0 then -- Top and left clients are shrinked by two steps and -- get moved away from the border. Other clients just -- get shrinked in one direction. + + gap_factor = (useless_gap / 100) * 2 + if this_x == 0 then - g.width = g.width - 2 * useless_gap + g.width = g.width - (2 + gap_factor) * useless_gap g.x = g.x + useless_gap else - g.width = g.width - useless_gap + g.width = g.width - (1 + gap_factor) * useless_gap end if this_y == 0 then - g.height = g.height - 2 * useless_gap + g.height = g.height - (2 + gap_factor) * useless_gap g.y = g.y + useless_gap else - g.height = g.height - useless_gap + g.height = g.height - (1 + gap_factor) * useless_gap end end c:geometry(g) diff --git a/layout/uselessfair.lua b/layout/uselessfair.lua index 7499d91..6aa6666 100644 --- a/layout/uselessfair.lua +++ b/layout/uselessfair.lua @@ -71,20 +71,23 @@ local function fair(p, orientation) -- Top and left clients are shrinked by two steps and -- get moved away from the border. Other clients just -- get shrinked in one direction. + + gap_factor = (useless_gap / 100) * 2 + if this_x == 0 then - g.width = g.width - 2 * useless_gap + g.width = g.width - (2 + gap_factor) * useless_gap g.x = g.x + useless_gap else - g.width = g.width - useless_gap + g.width = g.width - (1 + gap_factor) * useless_gap end if this_y == 0 then - g.height = g.height - 2 * useless_gap + g.height = g.height - (2 + gap_factor) * useless_gap g.y = g.y + useless_gap else - g.height = g.height - useless_gap + g.height = g.height - (1 + gap_factor) * useless_gap end end -- End of useless gap. diff --git a/layout/uselesspiral.lua b/layout/uselesspiral.lua index ad2ba04..3164c75 100644 --- a/layout/uselesspiral.lua +++ b/layout/uselesspiral.lua @@ -64,6 +64,8 @@ local function spiral(p, spiral) top = false left = false + gap_factor = (useless_gap / 100) * 2 + if wa2.y == static_wa.y then top = true end @@ -73,17 +75,17 @@ local function spiral(p, spiral) end if top then - wa2.height = wa2.height - 2 * useless_gap + wa2.height = wa2.height - (2 + gap_factor) * useless_gap wa2.y = wa2.y + useless_gap else - wa2.height = wa2.height - useless_gap + wa2.height = wa2.height - (1 + gap_factor) * useless_gap end if left then - wa2.width = wa2.width - 2 * useless_gap + wa2.width = wa2.width - (2 + gap_factor) * useless_gap wa2.x = wa2.x + useless_gap else - wa2.width = wa2.width - useless_gap + wa2.width = wa2.width - (1 + gap_factor) * useless_gap end end -- End of useless gap. diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index 78f7bec..e496500 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -88,6 +88,8 @@ local function tile_group(cls, wa, orientation, fact, group) top = false left = false + gap_factor = (useless_gap / 100) * 2 + if geom[y] == wa[y] then top = true end @@ -97,17 +99,17 @@ local function tile_group(cls, wa, orientation, fact, group) end if top then - geom[height] = geom[height] - 2 * useless_gap + geom[height] = geom[height] - (2 + gap_factor) * useless_gap geom[y] = geom[y] + useless_gap else - geom[height] = geom[height] - useless_gap + geom[height] = geom[height] - (1 + gap_factor) * useless_gap end if left then - geom[width] = geom[width] - 2 * useless_gap + geom[width] = geom[width] - (2 + gap_factor) * useless_gap geom[x] = geom[x] + useless_gap else - geom[width] = geom[width] - useless_gap + geom[width] = geom[width] - (1 + gap_factor) * useless_gap end end -- End of useless gap. diff --git a/wiki b/wiki index 089c10d..e85974a 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 089c10dff4317654c8436ddef408d993d617e202 +Subproject commit e85974ae28dda46d1f1ad1d5985269ea50ce5e83 From f8b37d508879c92d5184394a660c440899ccce03 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 6 Oct 2013 21:16:25 +0200 Subject: [PATCH 063/546] bat: fix issue #17 --- layout/centerfair.lua | 2 +- widgets/bat.lua | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/layout/centerfair.lua b/layout/centerfair.lua index d9ea677..49b4a14 100644 --- a/layout/centerfair.lua +++ b/layout/centerfair.lua @@ -3,7 +3,7 @@ Licensed under GNU General Public License v2 * (c) 2013, Luke Bonham - * (c) 2012, Nicolas Estibals + * (c) 2010, Nicolas Estibals * (c) 2010-2012, Peter Hofmann --]] diff --git a/widgets/bat.lua b/widgets/bat.lua index aa89640..a064e30 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -79,8 +79,21 @@ local function worker(args) if min < 0 then min = 0 elseif min > 59 then min = 59 end bat_now.time = string.format("%02d:%02d", hrs, min) - bat_now.perc = string.format("%d", (rem / tot) * 100) - bat_now.watt = string.format("%.2fW", (rate * ratev) / 1e12) + + local perc = (rem / tot) * 100 + if perc <= 100 then + bat_now.perc = string.format("%d", perc) + elseif perc > 100 then + bat_now.perc = "100" + elseif perc < 0 then + bat_now.perc = "0" + end + + if rate ~= nil and ratev ~= nil then + bat_now.watt = string.format("%.2fW", (rate * ratev) / 1e12) + else + bat_not.watt = "N/A" + end -- notifications for low and critical states if bat_now.status == "Discharging" From 5d6e2fa3d1bb8ce7a5af5543ba073f0aefd6b8a6 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 7 Oct 2013 00:26:26 +0200 Subject: [PATCH 064/546] little fix --- widgets/bat.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index a064e30..2906de2 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -92,7 +92,7 @@ local function worker(args) if rate ~= nil and ratev ~= nil then bat_now.watt = string.format("%.2fW", (rate * ratev) / 1e12) else - bat_not.watt = "N/A" + bat_now.watt = "N/A" end -- notifications for low and critical states From b0a71baeb5eeb8101a620b3558008038d487b3f7 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 23 Oct 2013 11:32:34 +0200 Subject: [PATCH 065/546] yawn: localizations and icons updated --- helpers.lua | 2 +- scripts/mpdcover | 2 +- widgets/yawn/icons/Fog.png | 1 + widgets/yawn/localizations/it_IT | 3 ++- widgets/yawn/localizations/localization_template | 1 + 5 files changed, 6 insertions(+), 3 deletions(-) create mode 120000 widgets/yawn/icons/Fog.png diff --git a/helpers.lua b/helpers.lua index 97cb797..c42ce61 100644 --- a/helpers.lua +++ b/helpers.lua @@ -30,7 +30,7 @@ end -- }}} --- {{{ Read the first line of a file or return nil. +-- {{{ Read the first line of a file or return nil function helpers.first_line(f) local fp = io.open(f) diff --git a/scripts/mpdcover b/scripts/mpdcover index f9f6577..20525fd 100755 --- a/scripts/mpdcover +++ b/scripts/mpdcover @@ -1,4 +1,4 @@ -#!/bin/bash +!/bin/bash # # A simple cover fetcher script for current playing song on mpd. # diff --git a/widgets/yawn/icons/Fog.png b/widgets/yawn/icons/Fog.png new file mode 120000 index 0000000..b615645 --- /dev/null +++ b/widgets/yawn/icons/Fog.png @@ -0,0 +1 @@ +Foggy.png \ No newline at end of file diff --git a/widgets/yawn/localizations/it_IT b/widgets/yawn/localizations/it_IT index 2276e4b..688e769 100644 --- a/widgets/yawn/localizations/it_IT +++ b/widgets/yawn/localizations/it_IT @@ -53,6 +53,7 @@ Sleet|Nevischio Drizzle|Pioggerella Freezing Drizzle|Pioggerella Congelantesi Hail|Grandine -Foggy|Nebbia +Fog|Nebbia +Foggy|Nebbioso Haze|Nebbia Light|Leggere diff --git a/widgets/yawn/localizations/localization_template b/widgets/yawn/localizations/localization_template index fd28868..e3a948f 100644 --- a/widgets/yawn/localizations/localization_template +++ b/widgets/yawn/localizations/localization_template @@ -53,6 +53,7 @@ Sleet| Drizzle| Freezing Drizzle| Hail| +Fog| Foggy| Haze| Light| From bda7673ada27c8eed27064775ffd0e4c863a6648 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 1 Nov 2013 11:09:20 +0100 Subject: [PATCH 066/546] issue #9 fix attempt --- init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/init.lua b/init.lua index 155d6cc..5086435 100644 --- a/init.lua +++ b/init.lua @@ -9,6 +9,8 @@ --]] +package.loaded.lain = nil + local lain = { layout = require("lain.layout"), From 165c5a17f468d6a2c7f5d2b61b6b2ce1f11d3970 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 1 Nov 2013 13:17:31 +0100 Subject: [PATCH 067/546] issue #9 2nd attempt fix --- widgets/mpd.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index e3ed50d..58d9430 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -59,7 +59,7 @@ local function worker(args) date = "N/A" } - local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 1 " .. mpdh) + local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh) for line in f:lines() do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do From 0eb2084a3ac0e352d2a401869b4f8a73229af0ba Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 1 Nov 2013 19:27:49 +0100 Subject: [PATCH 068/546] issue #9 semi-fix --- widgets/mpd.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 58d9430..4ee922f 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -42,6 +42,15 @@ local function worker(args) mpd.widget = wibox.widget.textbox('') + mpd_now = { + state = "N/A", + file = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", + date = "N/A" + } + mpd_notification_preset = { title = "Now playing", timeout = 6 @@ -50,15 +59,6 @@ local function worker(args) helpers.set_map("current mpd track", nil) function mpd.update() - mpd_now = { - state = "N/A", - file = "N/A", - artist = "N/A", - title = "N/A", - album = "N/A", - date = "N/A" - } - local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh) for line in f:lines() do From a4e5b806f176c8599c6423ebc2ceb3e6c1aa2be4 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 2 Nov 2013 21:05:25 +0100 Subject: [PATCH 069/546] issue #9 fix --- scripts/mpdcover | 4 ++-- widgets/mpd.lua | 38 +++++++++++++++++++++++++------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/scripts/mpdcover b/scripts/mpdcover index 20525fd..f6cf0d6 100755 --- a/scripts/mpdcover +++ b/scripts/mpdcover @@ -1,4 +1,4 @@ -!/bin/bash +#!/bin/bash # # A simple cover fetcher script for current playing song on mpd. # @@ -58,7 +58,7 @@ cover="${cover:=$DEFAULT_ART}" # check if art is available if [[ -n $cover ]]; then if [[ -n $COVER_RESIZE ]]; then - convert "$cover" -thumbnail $COVER_RESIZE -gravity center -background "$COVER_BACKGROUND" -extent $COVER_RESIZE "$TEMP_PATH" + convert "$cover" -thumbnail $COVER_RESIZE -gravity "center" -background "$COVER_BACKGROUND" -extent $COVER_RESIZE "$TEMP_PATH" cover="$TEMP_PATH" fi else diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 4ee922f..36c3ed7 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -16,7 +16,7 @@ local wibox = require("wibox") local io = { popen = io.popen } local os = { execute = os.execute, getenv = os.getenv } -local string = { format = string.format, +local string = { format = string.format, gmatch = string.gmatch } local setmetatable = setmetatable @@ -28,7 +28,7 @@ local mpd = {} local function worker(args) local args = args or {} local timeout = args.timeout or 2 - local password = args.password or "\"\"" + local password = args.password or "" local host = args.host or "127.0.0.1" local port = args.port or "6600" local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" @@ -38,19 +38,22 @@ local function worker(args) local mpdcover = helpers.scripts_dir .. "mpdcover" local mpdh = "telnet://" .. host .. ":" .. port - local echo = "echo 'password " .. password .. "\nstatus\ncurrentsong\nclose'" + + local echo = nil + + if password == "" then + echo = "(echo -e 'status'; sleep 0.1;" .. + "echo -e 'currentsong'; sleep 0.1;" .. + "echo -e 'close')" + else + echo = "(echo -e 'password " .. password .. "'" .. + "echo -e 'status'; sleep 0.1;" .. + "echo -e 'currentsong'; sleep 0.1;" .. + "echo -e 'close')" + end mpd.widget = wibox.widget.textbox('') - mpd_now = { - state = "N/A", - file = "N/A", - artist = "N/A", - title = "N/A", - album = "N/A", - date = "N/A" - } - mpd_notification_preset = { title = "Now playing", timeout = 6 @@ -59,7 +62,16 @@ local function worker(args) helpers.set_map("current mpd track", nil) function mpd.update() - local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh) + mpd_now = { + state = "N/A", + file = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", + date = "N/A" + } + + local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 1 " .. mpdh) for line in f:lines() do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do From 5894811766b560695f8fe6dac9a8e3bd07024510 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 12 Nov 2013 10:41:04 +0100 Subject: [PATCH 070/546] issue #11 typos fixed --- util/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/init.lua b/util/init.lua index cd1ac5d..1dfff65 100644 --- a/util/init.lua +++ b/util/init.lua @@ -194,7 +194,7 @@ function util.move_tag(pos) end end --- Delete current tag (if empty) +-- Remove current tag (if empty) -- Any rule set on the tag shall be broken function util.remove_tag() local tag = awful.tag.selected(mouse.screen) From 2151e99477925744d22c8ac1da9bb371217ed5f2 Mon Sep 17 00:00:00 2001 From: kurumushi Date: Tue, 19 Nov 2013 01:16:36 +0900 Subject: [PATCH 071/546] Change io.popen to io.open so we don't execute image files. --- widgets/yawn/init.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 38b741a..e7aa75d 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -1,4 +1,3 @@ - --[[ Licensed under GNU General Public License v2 @@ -115,7 +114,7 @@ local function fetch_weather() sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png" -- In case there's no defined icon for current forecast - f = io.popen(sky) + f = io.open(sky) if f == nil then sky = icon_path .. "na.png" else From ac6615db205af4ac3679b1cd87941fa2b32306bf Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 18 Nov 2013 20:27:48 +0100 Subject: [PATCH 072/546] wiki updated --- widgets/maildir.lua | 1 - widgets/yawn/init.lua | 3 +-- widgets/yawn/localizations/it_IT | 2 +- wiki | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/widgets/maildir.lua b/widgets/maildir.lua index d460881..5cb6840 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -1,4 +1,3 @@ - --[[ Licensed under GNU General Public License v2 diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index e7aa75d..e7953e1 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -114,8 +114,7 @@ local function fetch_weather() sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png" -- In case there's no defined icon for current forecast - f = io.open(sky) - if f == nil then + if io.open(sky) == nil then sky = icon_path .. "na.png" else io.close(f) diff --git a/widgets/yawn/localizations/it_IT b/widgets/yawn/localizations/it_IT index 688e769..f1bfbe2 100644 --- a/widgets/yawn/localizations/it_IT +++ b/widgets/yawn/localizations/it_IT @@ -14,7 +14,7 @@ Isolated Thunderstorms|Temporali Isolati Scattered Thunderstorms|Temporali Sparsi Thundershowers|Rovesci Temporaleschi Thunderstorms|Temporali -Thunder in the Vicinity|Tuoni in avvicinamento +Thunder in the Vicinity|Tuoni in prossimità Thunder|Temporale AM|In Mattinata PM|Nel Pomeriggio diff --git a/wiki b/wiki index e85974a..a7b1e7e 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit e85974ae28dda46d1f1ad1d5985269ea50ce5e83 +Subproject commit a7b1e7e0db5db914d519bbe8135f7e29cadfb8b7 From 6accb3a2a99d959e3eec9204727e43eb789320a7 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 18 Nov 2013 20:30:43 +0100 Subject: [PATCH 073/546] wiki updated --- widgets/yawn/init.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index e7953e1..7ab76fe 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -116,8 +116,6 @@ local function fetch_weather() -- In case there's no defined icon for current forecast if io.open(sky) == nil then sky = icon_path .. "na.png" - else - io.close(f) end -- Localization From 7b48c7b50e82837a17a999aa782c21219419850b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 28 Nov 2013 09:56:18 +0100 Subject: [PATCH 074/546] wiki updated --- README.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 75ed867..8eba2fb 100644 --- a/README.rst +++ b/README.rst @@ -13,9 +13,7 @@ Layouts, widgets and utilities for Awesome WM Description ----------- -Successor of awesome-vain_, this costantly evolving module -provides new layouts, a set of widgets and utility functions, -in order to improve Awesome_ usability and configurability. +Successor of awesome-vain_, this module provides new layouts, a set of widgets and utility functions, in order to improve Awesome_ usability and configurability. Read the wiki_ for all the info. From 06f6d81e741765310641a1d6f7747237ea76a434 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 28 Nov 2013 09:57:16 +0100 Subject: [PATCH 075/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index a7b1e7e..65c1a3a 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit a7b1e7e0db5db914d519bbe8135f7e29cadfb8b7 +Subproject commit 65c1a3ab6e411aec30c3145178fac9f7fdbab87f From a4e789e05bfad0bb9a364e1b95e924a0de160857 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 30 Nov 2013 10:19:52 +0100 Subject: [PATCH 076/546] added icon for #13 --- widgets/yawn/icons/LightSnow.png | 1 + widgets/yawn/icons/Mist.png | 1 + 2 files changed, 2 insertions(+) create mode 120000 widgets/yawn/icons/LightSnow.png create mode 120000 widgets/yawn/icons/Mist.png diff --git a/widgets/yawn/icons/LightSnow.png b/widgets/yawn/icons/LightSnow.png new file mode 120000 index 0000000..aa8b28e --- /dev/null +++ b/widgets/yawn/icons/LightSnow.png @@ -0,0 +1 @@ +LightSnowShowers.png \ No newline at end of file diff --git a/widgets/yawn/icons/Mist.png b/widgets/yawn/icons/Mist.png new file mode 120000 index 0000000..b615645 --- /dev/null +++ b/widgets/yawn/icons/Mist.png @@ -0,0 +1 @@ +Foggy.png \ No newline at end of file From 4a29739e79486a5003218341a6bd10fa5df4cb8b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 2 Dec 2013 16:25:59 +0100 Subject: [PATCH 077/546] satisfied 'issue' #14 --- widgets/yawn/init.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 7ab76fe..a2f756e 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -46,8 +46,7 @@ yawn_notification_preset = {} local function fetch_weather() local url = api_url .. units_set .. city_id - local f = io.popen("curl --connect-timeout 1 -fsm 1 '" - .. url .. "'" ) + local f = io.popen("curl --connect-timeout 1 -fsm 1 '" .. url .. "'" ) local text = f:read("*all") f:close() @@ -58,12 +57,12 @@ local function fetch_weather() yawn.icon:set_image(icon_path .. "na.png") if text == "" then weather_data = "Service not available at the moment." - yawn.widget:set_text("N/A") + yawn.widget:set_text(" N/A") else weather_data = "City not found!\n" .. "Are you sure " .. city_id .. " is your Yahoo city ID?" - yawn.widget:set_text("?") + yawn.widget:set_text(" ?") end return end @@ -75,7 +74,7 @@ local function fetch_weather() -- may still happens in case of bad connectivity if weather_data == "" then yawn.icon:set_image(icon_path .. "na.png") - yawn.widget:set_text("?") + yawn.widget:set_text(" ?") return end @@ -149,7 +148,7 @@ function yawn.hide() end function yawn.show(t_out) - if yawn.widget._layout.text == "?" + if yawn.widget._layout.text:match("?") then fetch_weather(settings) end From 4c7c9454a36a9dfd5338384f0ca9691790f01c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20G=C3=B6rlich?= Date: Wed, 4 Dec 2013 13:30:29 +0100 Subject: [PATCH 078/546] Count id tokens instead of every single diget --- widgets/imap.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/widgets/imap.lua b/widgets/imap.lua index b3f281d..87a9e61 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -61,9 +61,7 @@ local function worker(args) ws = f:read("*all") f:close() - t, mailcount = string.gsub(ws, "%d", "") - t = nil - mailcount = tonumber(mailcount) + _, mailcount = string.gsub(ws, "%d+", "") widget = imap.widget settings() From 3c0179a6ba2edbc20aeca6d21bee9b287781b1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20G=C3=B6rlich?= Date: Wed, 4 Dec 2013 18:52:40 +0100 Subject: [PATCH 079/546] Fix unread count in imap widget --- widgets/imap.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/widgets/imap.lua b/widgets/imap.lua index 87a9e61..39518bd 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -62,6 +62,7 @@ local function worker(args) f:close() _, mailcount = string.gsub(ws, "%d+", "") + _ = nil widget = imap.widget settings() From 0adb7f6e37fe7c6878cf487cb18b3f7280542273 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 5 Dec 2013 10:19:16 +0100 Subject: [PATCH 080/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 65c1a3a..7b6d89c 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 65c1a3ab6e411aec30c3145178fac9f7fdbab87f +Subproject commit 7b6d89cd4ff2b84fd333c8f6a5f0ef079b845f48 From 5a297dcfbb75e732671988a049095772fc2fdd76 Mon Sep 17 00:00:00 2001 From: yawnt Date: Mon, 23 Dec 2013 17:19:25 +0100 Subject: [PATCH 081/546] contrib-widget: brightness --- widgets/contrib/brightness.lua | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 widgets/contrib/brightness.lua diff --git a/widgets/contrib/brightness.lua b/widgets/contrib/brightness.lua new file mode 100644 index 0000000..bf14baf --- /dev/null +++ b/widgets/contrib/brightness.lua @@ -0,0 +1,46 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, yawnt + +--]] + +local newtimer = require("lain.helpers").newtimer + +local wibox = require("wibox") +local io = { popen = io.popen } +local string = { match = string.match } + +local setmetatable = setmetatable + +-- Brightness +-- lain.widgets.contrib.brightness +local brightness = {} + +local function worker(args) + local args = args or {} + local backlight = args.backlight or "acpi_video0" + local timeout = args.timeout or 5 + local settings = args.settings or function() end + + brightness.widget = wibox.widget.textbox('') + + function brightness.update() + local f = assert(io.popen('cat /sys/class/backlight/' .. backlight .. "/brightness")) + + brightness_now = { + level = f:read("*a") + } + f:close() + + widget = brightness.widget + settings() + end + + newtimer("brightness", timeout, brightness.update) + + return setmetatable(brightness, { __index = brightness.widget }) +end + +return setmetatable(brightness, { __call = function(_, ...) return worker(...) end }) From df19c9176e403345ffee13523d708cfebb761517 Mon Sep 17 00:00:00 2001 From: yawnt Date: Mon, 23 Dec 2013 18:04:06 +0100 Subject: [PATCH 082/546] fix: better code --- widgets/contrib/brightness.lua | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/widgets/contrib/brightness.lua b/widgets/contrib/brightness.lua index bf14baf..6967572 100644 --- a/widgets/contrib/brightness.lua +++ b/widgets/contrib/brightness.lua @@ -1,9 +1,9 @@ --[[ - - Licensed under GNU General Public License v2 + + Licensed under GNU General Public License v2 * (c) 2013, yawnt - + --]] local newtimer = require("lain.helpers").newtimer @@ -14,7 +14,7 @@ local string = { match = string.match } local setmetatable = setmetatable --- Brightness +-- Brightness -- lain.widgets.contrib.brightness local brightness = {} @@ -28,12 +28,9 @@ local function worker(args) function brightness.update() local f = assert(io.popen('cat /sys/class/backlight/' .. backlight .. "/brightness")) - - brightness_now = { - level = f:read("*a") - } + brightness_now = f:read("*a") f:close() - + widget = brightness.widget settings() end From a56c60dacef900097509cfa8f36d4a76952a69f8 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 23 Dec 2013 18:18:33 +0100 Subject: [PATCH 083/546] wiki: new commit --- README.rst | 6 +++--- widgets/contrib/brightness.lua | 10 +++++----- wiki | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index 8eba2fb..07f4ee7 100644 --- a/README.rst +++ b/README.rst @@ -28,11 +28,11 @@ Just make sure that: - Your code its easy to understand, maintainable, and modularized. You should also avoid code duplication wherever possible by adding functions or using ``lain.helpers``. If something is unclear, and you can't write it in such a way that it will be clear, explain it with a comment. -- You test your changes before submitting to make sure that not only your code works, but have not broken other parts of the module too! +- You test your changes before submitting to make sure that not only your code works, but did not break other parts of the module too! -- You update ``wiki`` submodule with a thorough section. +- You eventually update ``wiki`` submodule with a thorough section. -Contributed widgets have to be put it in ``lain/widget/contrib``. +Contributed widgets have to be put in ``lain/widget/contrib``. Screenshots ----------- diff --git a/widgets/contrib/brightness.lua b/widgets/contrib/brightness.lua index 6967572..0ba2f45 100644 --- a/widgets/contrib/brightness.lua +++ b/widgets/contrib/brightness.lua @@ -1,9 +1,9 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2013, yawnt - + + Licensed under GNU General Public License v2 + * (c) 2013, yawnt + --]] local newtimer = require("lain.helpers").newtimer @@ -14,7 +14,7 @@ local string = { match = string.match } local setmetatable = setmetatable --- Brightness +-- Brightness level -- lain.widgets.contrib.brightness local brightness = {} diff --git a/wiki b/wiki index 7b6d89c..e379b96 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 7b6d89cd4ff2b84fd333c8f6a5f0ef079b845f48 +Subproject commit e379b9649b88e4e88a95731565e65d92c86b2824 From e0107d771057dbb3ca178a81a32e28fbb6467431 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 24 Dec 2013 12:29:37 +0100 Subject: [PATCH 084/546] wiki: some typos fixed --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index e379b96..9f6ff05 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit e379b9649b88e4e88a95731565e65d92c86b2824 +Subproject commit 9f6ff057f4b99704d9396a66c4f2896954541d2e From 8bda449c576a9ca1d4f88a82d999f95e9de6e203 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 30 Dec 2013 19:18:01 +0100 Subject: [PATCH 085/546] yawn: new localization word --- widgets/yawn/localizations/it_IT | 3 ++- widgets/yawn/localizations/localization_template | 3 ++- wiki | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/widgets/yawn/localizations/it_IT b/widgets/yawn/localizations/it_IT index f1bfbe2..70b0eef 100644 --- a/widgets/yawn/localizations/it_IT +++ b/widgets/yawn/localizations/it_IT @@ -50,7 +50,8 @@ Windy|Ventoso Wind|Ventoso Snow|Neve Sleet|Nevischio -Drizzle|Pioggerella +Light Drizzle|Pioggia Leggera +Drizzle|Pioggia Leggera Freezing Drizzle|Pioggerella Congelantesi Hail|Grandine Fog|Nebbia diff --git a/widgets/yawn/localizations/localization_template b/widgets/yawn/localizations/localization_template index e3a948f..453807e 100644 --- a/widgets/yawn/localizations/localization_template +++ b/widgets/yawn/localizations/localization_template @@ -50,8 +50,9 @@ Windy| Wind| Snow| Sleet| -Drizzle| Freezing Drizzle| +Light Drizzle| +Drizzle| Hail| Fog| Foggy| diff --git a/wiki b/wiki index 9f6ff05..c8e07d2 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 9f6ff057f4b99704d9396a66c4f2896954541d2e +Subproject commit c8e07d2ec34cfb12907e4ccb5f29908aa8c98f5a From af7888d3b398e22ecc2322f833827f068ad87941 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 4 Jan 2014 12:23:24 +0100 Subject: [PATCH 086/546] #18 fixed --- widgets/temp.lua | 10 ++++++++-- wiki | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/widgets/temp.lua b/widgets/temp.lua index b57c477..b55d52f 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -28,8 +28,14 @@ local function worker(args) function update() local f = io.open("/sys/class/thermal/thermal_zone0/temp") - coretemp_now = tonumber(f:read("*all")) / 1000 - f:close() + if f ~= nil + then + coretemp_now = tonumber(f:read("*all")) / 1000 + f:close() + else + coretemp_now = "N/A" + end + widget = temp.widget settings() end diff --git a/wiki b/wiki index c8e07d2..07a230f 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit c8e07d2ec34cfb12907e4ccb5f29908aa8c98f5a +Subproject commit 07a230fb1654cc6abc1bd1ea8b36d8dcb3c1ad62 From 13bdc435952fd58f00de64c59524af6c3f4f8de7 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 4 Jan 2014 12:35:16 +0100 Subject: [PATCH 087/546] wiki updated --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 07f4ee7..f59c04d 100644 --- a/README.rst +++ b/README.rst @@ -6,7 +6,7 @@ Layouts, widgets and utilities for Awesome WM --------------------------------------------- :Author: Luke Bonham -:Version: 1.0-git +:Version: git :License: GNU-GPLv2_ :Source: https://github.com/copycat-killer/lain From f8734babc551421c842522dd86ad70bbaddd021d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 9 Jan 2014 14:33:18 +0100 Subject: [PATCH 088/546] brigthness: unused lib removed --- widgets/contrib/brightness.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/widgets/contrib/brightness.lua b/widgets/contrib/brightness.lua index 0ba2f45..04b8d2b 100644 --- a/widgets/contrib/brightness.lua +++ b/widgets/contrib/brightness.lua @@ -10,7 +10,6 @@ local newtimer = require("lain.helpers").newtimer local wibox = require("wibox") local io = { popen = io.popen } -local string = { match = string.match } local setmetatable = setmetatable From 0ad1d66d7276b3bb67bae5dd71ae318e14be820f Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 13 Jan 2014 13:03:21 +0100 Subject: [PATCH 089/546] pull #19 satisfaction --- widgets/bat.lua | 3 ++- wiki | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 2906de2..b3f91dd 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -27,6 +27,7 @@ local function worker(args) local args = args or {} local timeout = args.timeout or 30 local battery = args.battery or "BAT0" + local notify = args.notify or true local settings = args.settings or function() end bat.widget = wibox.widget.textbox('') @@ -96,7 +97,7 @@ local function worker(args) end -- notifications for low and critical states - if bat_now.status == "Discharging" + if bat_now.status == "Discharging" and notify then if tonumber(bat_now.perc) <= 5 then diff --git a/wiki b/wiki index 07a230f..780ce12 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 07a230fb1654cc6abc1bd1ea8b36d8dcb3c1ad62 +Subproject commit 780ce12033c8aa90c5060280cfbdfd6fddc7584f From a71b796ac8ade0d1743d82ede1a929bfa9ad3c9b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 14 Jan 2014 09:46:06 +0100 Subject: [PATCH 090/546] revert to original pull request #19 --- widgets/bat.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index b3f91dd..48a14fb 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -27,7 +27,7 @@ local function worker(args) local args = args or {} local timeout = args.timeout or 30 local battery = args.battery or "BAT0" - local notify = args.notify or true + local notify = args.notify or "on" local settings = args.settings or function() end bat.widget = wibox.widget.textbox('') @@ -97,7 +97,7 @@ local function worker(args) end -- notifications for low and critical states - if bat_now.status == "Discharging" and notify + if bat_now.status == "Discharging" and notify == "on" then if tonumber(bat_now.perc) <= 5 then From 0ef9d8c78f37353f96ab90e4f19ebb8341811b1d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 14 Jan 2014 10:09:57 +0100 Subject: [PATCH 091/546] alsabar: fixed 'ticks' boolean issue; wiki updated --- widgets/alsabar.lua | 5 ++--- wiki | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 90d3a0d..365ac2d 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -95,7 +95,7 @@ local function worker(args) local settings = args.settings or function() end local width = args.width or 63 local height = args.heigth or 1 - local ticks = args.ticks or true + local ticks = args.ticks or false local ticks_size = args.ticks_size or 7 local vertical = args.vertical or false @@ -113,8 +113,7 @@ local function worker(args) alsabar.bar:set_height(height) alsabar.bar:set_ticks(ticks) alsabar.bar:set_ticks_size(ticks_size) - - if vertical then alsabar.bar:set_vertical(true) end + alsabar.bar:set_vertical(vertical) function alsabar.update() -- Get mixer control contents diff --git a/wiki b/wiki index 780ce12..41d28b9 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 780ce12033c8aa90c5060280cfbdfd6fddc7584f +Subproject commit 41d28b93ebbeb7e51584032e88c748426ea6cd82 From 14705ce911ab9a2cca59de6bfbe9dacd3a0ca90d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 20 Jan 2014 19:12:00 +0100 Subject: [PATCH 092/546] wiki: improved imap widget section --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 41d28b9..ecf143b 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 41d28b93ebbeb7e51584032e88c748426ea6cd82 +Subproject commit ecf143be0d664ce754edeb1ed0ead3bd1104c7e6 From 8dab1614a3e0c0c905c370acbef9015f985f9263 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 20 Jan 2014 19:15:19 +0100 Subject: [PATCH 093/546] wiki: improved imap widget section --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index ecf143b..f996cdb 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit ecf143be0d664ce754edeb1ed0ead3bd1104c7e6 +Subproject commit f996cdb74e7583534256d82706ef63d2b9811b42 From a33a8afae0460b1c15526372cdb41fdaf4ebe647 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 21 Jan 2014 15:42:33 +0100 Subject: [PATCH 094/546] revert #9; discouraging #21 and #22 situations --- widgets/mpd.lua | 16 ++-------------- widgets/yawn/init.lua | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 36c3ed7..1749b57 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -38,19 +38,7 @@ local function worker(args) local mpdcover = helpers.scripts_dir .. "mpdcover" local mpdh = "telnet://" .. host .. ":" .. port - - local echo = nil - - if password == "" then - echo = "(echo -e 'status'; sleep 0.1;" .. - "echo -e 'currentsong'; sleep 0.1;" .. - "echo -e 'close')" - else - echo = "(echo -e 'password " .. password .. "'" .. - "echo -e 'status'; sleep 0.1;" .. - "echo -e 'currentsong'; sleep 0.1;" .. - "echo -e 'close')" - end + local echo = "echo 'password " .. password .. "\nstatus\ncurrentsong\nclose'" mpd.widget = wibox.widget.textbox('') @@ -71,7 +59,7 @@ local function worker(args) date = "N/A" } - local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 1 " .. mpdh) + local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh) for line in f:lines() do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index a2f756e..36cdf54 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -46,7 +46,7 @@ yawn_notification_preset = {} local function fetch_weather() local url = api_url .. units_set .. city_id - local f = io.popen("curl --connect-timeout 1 -fsm 1 '" .. url .. "'" ) + local f = io.popen("curl --connect-timeout 1 -fsm 3 '" .. url .. "'" ) local text = f:read("*all") f:close() From a2d553c9b6f59e3da9f25221dfb42ba4053acb44 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 21 Jan 2014 16:01:28 +0100 Subject: [PATCH 095/546] simple fix to #20 --- widgets/temp.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/widgets/temp.lua b/widgets/temp.lua index b55d52f..61a9aa5 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -22,12 +22,13 @@ local temp = {} local function worker(args) local args = args or {} local timeout = args.timeout or 5 + local tempfile = args.tempfile or "/sys/class/thermal/thermal_zone0/temp" local settings = args.settings or function() end temp.widget = wibox.widget.textbox('') function update() - local f = io.open("/sys/class/thermal/thermal_zone0/temp") + local f = io.open(tempfile) if f ~= nil then coretemp_now = tonumber(f:read("*all")) / 1000 From 9ec8af2c6f2d4b5c94949aa0502ab994f120d0af Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:05:00 -0700 Subject: [PATCH 096/546] Initial Commit --- Home.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 Home.md diff --git a/Home.md b/Home.md new file mode 100644 index 0000000..a520d81 --- /dev/null +++ b/Home.md @@ -0,0 +1 @@ +Welcome to the lain wiki! \ No newline at end of file From 00cd5d9e596528c808ffec67df7cb726dff6ffe9 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:10:58 -0700 Subject: [PATCH 097/546] Created To start (markdown) --- To-start.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 To-start.md diff --git a/To-start.md b/To-start.md new file mode 100644 index 0000000..9135be2 --- /dev/null +++ b/To-start.md @@ -0,0 +1,26 @@ +All you have to do is to include the module: + + local lain = require("lain") + +Some widgets require a terminal, lain default is `xterm`, but can be changed: + + lain.widgets.terminal = "urxvtc" + +or + + lain.widgets.terminal = terminal + +providing you have something like this: + + terminal = "urxvtc" + +in your `rc.lua`. + +`terminal` may also be a lua function that accepts one parameter. +Something like this: + + function footerm(cmd) + -- elaborate cmd + end + + lain.widgets.terminal = footerm \ No newline at end of file From 8c213f95cf9beebd872fc3116380053a0f0334a6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:11:44 -0700 Subject: [PATCH 098/546] Created mem (markdown) --- mem.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 mem.md diff --git a/mem.md b/mem.md new file mode 100644 index 0000000..58ccf72 --- /dev/null +++ b/mem.md @@ -0,0 +1,19 @@ +Show used memory and total memory in MiB. + + mymem = lain.widgets.mem() + + +The function takes a table as an optional argument. That table may +contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`refresh_timeout` | Refresh timeout seconds | int | 10 +`show_swap` | Show amount of used swap space? | boolean | false +`show_total` | Show amout of total memory? | boolean | false +`header` | Text to show before value | string | " Vol " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to show after value | string | "MB" + +**Note**: `footer` color is `color`. \ No newline at end of file From f7dc89c8fdb9eba9ce2ce4743f52b6f19874fcf0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:12:36 -0700 Subject: [PATCH 099/546] Created maildir (markdown) --- maildir.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 maildir.md diff --git a/maildir.md b/maildir.md new file mode 100644 index 0000000..df5f6fe --- /dev/null +++ b/maildir.md @@ -0,0 +1,37 @@ +Checks your maildirs. + +Maildirs are structured as follows: + + ~/Mail + . + |-- arch + | |-- cur + | |-- new + | `-- tmp + |-- gmail + | |-- cur + | |-- new + | `-- tmp + . + . + . + +therefore the widget checks whether there are files in the `new` directories. +If there's new mail, the textbox will say something like "mail: bugs(3), system(1)", otherwise it says +"no mail". + + mymaildir= lain.widgets.maildir("/path/to/my/maildir") + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`mailpath` | Path to your maildir | string | "~/Mail" +`ignore_boxes` | A list of boxes to ignore | table | empty table +`refresh_timeout` | Refresh timeout seconds | int | 60 +`header` | Text to show before value | string | " Mail " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color_newmail` | New mail value color | string | `beautiful.fg_focus` or "#FFFFFF" +`color_nomail` | No mail value color | string | `beautiful.fg_normal` or "#FFFFFF" +`app` | Mail program to spawn on click | string | "mutt"| boolean | false +`shadow` | Hide widget when there are no mails | boolean | false \ No newline at end of file From 877e48a7a9f1db1d8ef773bcb0b6a7c728ef2858 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:16:55 -0700 Subject: [PATCH 100/546] Created Layouts (markdown) --- Layouts.md | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 Layouts.md diff --git a/Layouts.md b/Layouts.md new file mode 100644 index 0000000..b5aacc5 --- /dev/null +++ b/Layouts.md @@ -0,0 +1,271 @@ +Currently, there are **7** layouts. + + lain/layout + . + |-- cascade + |-- cascadetile + |-- centerwork + |-- termfair + |-- uselessfair + |-- uselesspiral + `-- uselesstile + +Just add your favourites to ``layouts`` table: + + layouts = + { + ... + lain.layout.termfair, + lain.layout.uselesstile, + ... + } + +Or set them on specific tags like this: + + awful.layout.set(lain.layout.uselessfair, tags[1][7]) + +How do layouts work? +========================= + +cascade +------- + +Cascade all windows of a tag. + +You can control the offsets by setting those two variables: + + lain.layout.cascade.cascade_offset_x = 64 + lain.layout.cascade.cascade_offset_y = 16 + +The following reserves space for 5 windows: + + lain.layout.cascade.nmaster = 5 + +That is, no window will get resized upon the creation of a new window, +unless there's more than 5 windows. + +cascadetile +----------- + +Similar to `awful.layout.suit.tile` layout, however, clients in the slave +column are cascaded instead of tiled. + +Left column size can be set, otherwise is controlled by `mwfact` of the +tag. Additional windows will be opened in another column on the right. +New windows are placed above old windows. + +Whether the slave column is placed on top of the master window or not is +controlled by the value of `ncol`. A value of 1 means "overlapping slave column" +and anything else means "don't overlap windows". + +Usage example: + + lain.layout.cascadetile.cascade_offset_x = 2 + lain.layout.cascadetile.cascade_offset_y = 32 + lain.layout.cascadetile.extra_padding = 5 + lain.layout.cascadetile.nmaster = 5 + lain.layout.ncol = 1 + +`extra_padding` reduces the size of the master window if "overlapping +slave column" is activated. This allows you to see if there are any +windows in your slave column. + +Setting `cascade_offset_x` to a very small value or even 0 is reccommended to avoid wasting space. + +centerwork +---------- + +You start with one window, centered horizontally: + + +--------------------------+ + | +----------+ | + | | | | + | | | | + | | | | + | | MAIN | | + | | | | + | | | | + | | | | + | | | | + | +----------+ | + +--------------------------+ + +This is your main working window. You do most of the work right here. +Sometimes, you may want to open up additional windows. They're put in +the following four slots: + + +--------------------------+ + | +---+ +----------+ +---+ | + | | | | | | | | + | | 0 | | | | 1 | | + | | | | | | | | + | +---+ | MAIN | +---+ | + | +---+ | | +---+ | + | | | | | | | | + | | 2 | | | | 3 | | + | | | | | | | | + | +---+ +----------+ +---+ | + +--------------------------+ + +Yes, the number "four" is fixed. In total, you can only have five open +windows with this layout. Additional windows are not managed and set to +floating mode. **This is intentional**. + +You can set the order of the four auxiliary windows. This is the default +configuration: + + lain.layout.centerwork.top_left = 0 + lain.layout.centerwork.top_right = 1 + lain.layout.centerwork.bottom_left = 2 + lain.layout.centerwork.bottom_right = 3 + +This means: The bottom left slot will be occupied by the third window +(not counting the main window). Suppose you want your windows to appear +in this order: + + +--------------------------+ + | +---+ +----------+ +---+ | + | | | | | | | | + | | 3 | | | | 0 | | + | | | | | | | | + | +---+ | MAIN | +---+ | + | +---+ | | +---+ | + | | | | | | | | + | | 2 | | | | 1 | | + | | | | | | | | + | +---+ +----------+ +---+ | + +--------------------------+ + +This would require you to use these settings: + + lain.layout.centerwork.top_left = 3 + lain.layout.centerwork.top_right = 0 + lain.layout.centerwork.bottom_left = 2 + lain.layout.centerwork.bottom_right = 1 + +*Please note:* If you use Awesome's default configuration, navigation in +this layout may be very confusing. How do you get from the main window +to satellite ones depends on the order in which the windows are opened. +Thus, use of `awful.client.focus.bydirection()` is suggested. +Here's an example: + + globalkeys = awful.util.table.join( + ... + awful.key({ modkey }, "j", + function() + awful.client.focus.bydirection("down") + if client.focus then client.focus:raise() end + end), + awful.key({ modkey }, "k", + function() + awful.client.focus.bydirection("up") + if client.focus then client.focus:raise() end + end), + awful.key({ modkey }, "h", + function() + awful.client.focus.bydirection("left") + if client.focus then client.focus:raise() end + end), + awful.key({ modkey }, "l", + function() + awful.client.focus.bydirection("right") + if client.focus then client.focus:raise() end + end), + ... + ) + +termfair +-------- + +I do a lot of work on terminals. The common tiling algorithms usually +maximize windows, so you'll end up with a terminal that has about 200 +columns or more. That's way too much. Have you ever read a manpage in a +terminal of this size? + +This layout restricts the size of each window. Each window will have the +same width but is variable in height. Furthermore, windows are +left-aligned. The basic workflow is as follows (the number above the +screen is the number of open windows, the number in a cell is the fixed +number of a client): + + (1) (2) (3) + +---+---+---+ +---+---+---+ +---+---+---+ + | | | | | | | | | | | | + | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> + | | | | | | | | | | | | + +---+---+---+ +---+---+---+ +---+---+---+ + + (4) (5) (6) + +---+---+---+ +---+---+---+ +---+---+---+ + | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | + +---+---+---+ -> +---+---+---+ -> +---+---+---+ + | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | + +---+---+---+ +---+---+---+ +---+---+---+ + +The first client will be located in the left column. When opening +another window, this new window will be placed in the left column while +moving the first window into the middle column. Once a row is full, +another row above it will be created. + +Default number of columns and rows are respectively taken from `nmaster` +and `ncol` values in `awful.tag`, but you can set your own. + +For example, this sets `termfair` to 3 columns and at least 1 row: + + lain.layout.termfair.nmaster = 3 + lain.layout.termfair.ncol = 1 + +uselessfair, uselesspiral & uselesstile +--------------------------------------- +These are duplicates of the stock `fair`, `spiral` and `tile` layouts. +However, "useless gaps" (see below) have been added. + +Useless gaps +============ + +Useless gaps are gaps between windows. They are "useless" because they +serve no special purpose despite increasing overview. I find it easier +to recognize window boundaries if windows are set apart a little bit. + +The `uselessfair` layout, for example, looks like this: + + +================+ + # # + # +---+ +---+ # + # | 1 | | | # + # +---+ | | # + # | 3 | # + # +---+ | | # + # | 2 | | | # + # +---+ +---+ # + # # + +================+ + +All of lain layouts provide useless gaps. To set the width of the gaps, +you have to add an item called `useless_gap_width` in your `theme.lua`. +If it doesn't exist, the width will default to 0. +Example: + + ... + theme.useless_gap_width = "5" + ... + +What about layout icons? +======================== + +They are located in ``lain/icons/layout``. + +To use them, add lines to your ``theme.lua`` like this: + + ... + theme.lain_icons = os.getenv("HOME") .. "/.config/awesome/lain/icons/layout/default/" + theme.layout_termfair = theme.lain_icons .. "termfairw.png" + theme.layout_cascade = theme.lain_icons .. "cascadew.png" + theme.layout_cascadetile = theme.lain_icons .. "cascadetilew.png" + theme.layout_centerwork = theme.lain_icons .. "centerworkw.png" + ... + +Credits goes to [Nicolas Estibals](https://github.com/nestibal) for creating +layout icons for default theme. + +You can use them as a template for your custom versions. \ No newline at end of file From 0c3c9e43f01a7d6987528f5fbebd5e54861aab54 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:20:25 -0700 Subject: [PATCH 101/546] Updated Layouts (markdown) --- Layouts.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Layouts.md b/Layouts.md index b5aacc5..7f50efe 100644 --- a/Layouts.md +++ b/Layouts.md @@ -63,8 +63,8 @@ Usage example: lain.layout.cascadetile.cascade_offset_x = 2 lain.layout.cascadetile.cascade_offset_y = 32 lain.layout.cascadetile.extra_padding = 5 - lain.layout.cascadetile.nmaster = 5 - lain.layout.ncol = 1 + lain.layout.cascadetile.nmaster = 5 + lain.layout.ncol = 1 `extra_padding` reduces the size of the master window if "overlapping slave column" is activated. This allows you to see if there are any @@ -150,7 +150,7 @@ Thus, use of `awful.client.focus.bydirection()` is suggested. Here's an example: globalkeys = awful.util.table.join( - ... + ... awful.key({ modkey }, "j", function() awful.client.focus.bydirection("down") @@ -218,6 +218,7 @@ For example, this sets `termfair` to 3 columns and at least 1 row: uselessfair, uselesspiral & uselesstile --------------------------------------- These are duplicates of the stock `fair`, `spiral` and `tile` layouts. + However, "useless gaps" (see below) have been added. Useless gaps @@ -246,9 +247,7 @@ you have to add an item called `useless_gap_width` in your `theme.lua`. If it doesn't exist, the width will default to 0. Example: - ... theme.useless_gap_width = "5" - ... What about layout icons? ======================== @@ -257,13 +256,11 @@ They are located in ``lain/icons/layout``. To use them, add lines to your ``theme.lua`` like this: - ... theme.lain_icons = os.getenv("HOME") .. "/.config/awesome/lain/icons/layout/default/" theme.layout_termfair = theme.lain_icons .. "termfairw.png" theme.layout_cascade = theme.lain_icons .. "cascadew.png" theme.layout_cascadetile = theme.lain_icons .. "cascadetilew.png" theme.layout_centerwork = theme.lain_icons .. "centerworkw.png" - ... Credits goes to [Nicolas Estibals](https://github.com/nestibal) for creating layout icons for default theme. From 8e95f5d3e4b682c23cb618f7ebdb2b746a9eccf3 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:24:05 -0700 Subject: [PATCH 102/546] Created imap (markdown) --- imap.md | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 imap.md diff --git a/imap.md b/imap.md new file mode 100644 index 0000000..f12a1e7 --- /dev/null +++ b/imap.md @@ -0,0 +1,64 @@ +Check new mails over IMAP protocol. + +Dependencies: + +- Python3 + +New mails are notified through a notification like this: + + +---------------------------------------------------+ + | +---+ | + | |\ /| donald@disney.org has 3 new messages | + | +---+ | + | Latest From: Mickey Mouse | + | Subject: Re: pay raise | + | | + | Not after what you did yesterday. | + | Daisy told me everything [...] | + | | + +---------------------------------------------------+ + +Text will be cut if the mail is too long. + + myimapcheck = lain.widgets.imap(args) + +The function takes a table as argument. Required table parameters are: + +Variable | Type +--- | --- +`server` | string +`mail` | string +`password` | string + +while the optional are: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`port` | IMAP port | int | 993 +`refresh_timeout` | Refresh timeout seconds | int | 60 +`header` | Text to show before value | string | " Mail " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color_newmail` | New mail value color | string | `beautiful.fg_focus` or "#FFFFFF" +`color_nomail` | No mail value color | string | `beautiful.fg_normal` or "#FFFFFF" +`mail_encoding` | Mail character encoding | string | autodetected +`maxlen` | Maximum chars to display in notification | int | 200 +`app` | Mail program to spawn on click | string | "mutt" +`shadow` | Hide widget when there are no mails | boolean | false +`is_plain` | Define whether `password` is a plain password (true) or a function that retrieves it (false) | boolean | false + +Let's focus better on `is_plain`. + +You can just set your password like this: + + args.is_plain = false + args.password = "mypassword" + +and you'll have the same security provided by `~/.netrc` + +**Or** you can use a keyring, like [python keyring](https://pypi.python.org/pypi/keyring): + + args.password = "keyring get password" + +When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. + +You can also define your custom icon for the naughty notification. Just set `lain_mail_notify` into `theme.lua`. \ No newline at end of file From 211e7a5ec6905372bc9f1a3ee9a79fda54d53056 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:25:06 -0700 Subject: [PATCH 103/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index f12a1e7..3c049dd 100644 --- a/imap.md +++ b/imap.md @@ -53,7 +53,7 @@ You can just set your password like this: args.is_plain = false args.password = "mypassword" -and you'll have the same security provided by `~/.netrc` +and you'll have the same security provided by `~/.netrc`. **Or** you can use a keyring, like [python keyring](https://pypi.python.org/pypi/keyring): From 47cfa9550bd383d7c0b08af262d589bc98d9d5d8 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:26:19 -0700 Subject: [PATCH 104/546] Updated imap (markdown) --- imap.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 3c049dd..5f8ce30 100644 --- a/imap.md +++ b/imap.md @@ -61,4 +61,6 @@ and you'll have the same security provided by `~/.netrc`. When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. -You can also define your custom icon for the naughty notification. Just set `lain_mail_notify` into `theme.lua`. \ No newline at end of file +You can also define your custom icon for the naughty notification. Just set `lain_mail_notify` into `theme.lua`: + + theme.lain_mail_notify = "/path/to/my/icon" \ No newline at end of file From d2900b69c87bbb4c6322fdf18bf3052998ee1430 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:27:10 -0700 Subject: [PATCH 105/546] Created fs (markdown) --- fs.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 fs.md diff --git a/fs.md b/fs.md new file mode 100644 index 0000000..98016fb --- /dev/null +++ b/fs.md @@ -0,0 +1,32 @@ +Shows disk space usage for a set partition. + +Displays a notification when the partition is full or has low space. + + mypartition = lain.widgets.fs() + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`partition` | Partition to monitor | string | "/" +`refresh_timeout` | Refresh timeout seconds | int | 600 +`header` | Text to show before value | string | " Hdd " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to show after value | string | "%" +`shadow` | Hide the widget if `partition` < 90 | boolean | false + +**Note**: `footer` color is `color`. + +`lain.widgets.fs` outputs the following table: + +Variable | Type +--- | --- +`widget` | `wibox.widget.textbox` +`show` | function + +You can display a notification of current disk space usage with the following key binding: + + awful.key({ altkey }, "h", function () mypartition.show(7) end), + +where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds. \ No newline at end of file From 635448d56488c84f861a11e9e4d9b513b779b5fd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:28:21 -0700 Subject: [PATCH 106/546] Created cpu (markdown) --- cpu.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 cpu.md diff --git a/cpu.md b/cpu.md new file mode 100644 index 0000000..bdcc128 --- /dev/null +++ b/cpu.md @@ -0,0 +1,15 @@ +Shows the average CPU usage percent for a given amount of time. + + mycpuusage = lain.widgets.cpu() + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`refresh_timeout` | Refresh timeout seconds | int | 10 +`header` | Text to show before value | string | " Vol " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to add after value | string | "%" + +**Note**: `footer` color is `color`. \ No newline at end of file From 15aea13b584b1e3d4d48567c633bc5a76c821dcb Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:28:39 -0700 Subject: [PATCH 107/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index bdcc128..ce59a15 100644 --- a/cpu.md +++ b/cpu.md @@ -7,7 +7,7 @@ The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- `refresh_timeout` | Refresh timeout seconds | int | 10 -`header` | Text to show before value | string | " Vol " +`header` | Text to show before value | string | " Cpu " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `footer` | Text to add after value | string | "%" From 9989559ca469ba4de79dbaff71b2ec68bf2d5cdd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:30:54 -0700 Subject: [PATCH 108/546] Created calendar (markdown) --- calendar.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 calendar.md diff --git a/calendar.md b/calendar.md new file mode 100644 index 0000000..06e1b48 --- /dev/null +++ b/calendar.md @@ -0,0 +1,35 @@ +Attaches a calendar to a ``widget``. Example: + + lain.widgets.calendar:attach(mytextclock) + +- Left click: switch to previous month. +- Right click: switch to next month. + +Optionally you can call the function with background and foreground colors arguments, both or just one: + + lain.widgets.calendar:attach(mytextclock, "#FFFFFF", "#000000") + -- or + lain.widgets.calendar:attach(mytextclock, "#FFFFFF") + -- or + lain.widgets.calendar:attach(mytextclock, nil, "#000000") + +Notification will show an icon displaying current day, and formatted output +from ``cal`` with current day highlighted. + +Calendar icons are placed in [lain/icons/cal](https://github.com/copycat-killer/lain/tree/master/icons/cal), default set being ``white``. + +You can add your own set, and tell lain to use it like this: + + lain.widgets.calendar.icons_dir = lain.widgets.icons_dir .. "cal/myicons" + +also, you can set notification font size: + + lain.widgets.calendar.font_size = 14 + +default is 12. + +Finally, you can call the notification with a key binding like this: + + awful.key({ altkey }, "c", function () lain.widgets.calendar:show(7) end), + +where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds. \ No newline at end of file From 62acc707f6daaccedeab99426875e81c3eaf5c11 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:33:28 -0700 Subject: [PATCH 109/546] Created borderbox (markdown) --- borderbox.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 borderbox.md diff --git a/borderbox.md b/borderbox.md new file mode 100644 index 0000000..cdeece2 --- /dev/null +++ b/borderbox.md @@ -0,0 +1,47 @@ +Creates a thin wibox at a position relative to another wibox. + +This allows to create "borders" for your wiboxes. + + lain.widget.borderbox(relbox, s, args) + +`relbox` and `s` (an integer being screen number) are required arguments, `args` is an optional table +which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`position` | Position of the additional box | string | "above" +`color` | Color of the additional box | string | `#FFFFFF` +`size` | Size in pixels of the additional box | int | 1 + +Possible values for `.position`: `above`, `below`, `left` and `right`. + +### Example usage + +Think of this as a wibox: + + [======================] + +If `args.position = "above"`, then you'll get an additional wibox below +the existing one: + + ________________________ + [======================] + +It'll match position and size of the existing wibox. + +If your main wiboxes are stored in a table called `mywibox` (one wibox +for each screen) and are located at the bottom of your screen, then this +adds a borderbox on top of them: + + -- Layout section + for s = 1, screen.count() do + ... + + -- Most likely, you'll want to do this as well: + awful.screen.padding(screen[s], { bottom = 1 }) + + -- Create the box and place it above the existing box. + lain.widgets.borderbox(mywibox[s], s, { position = "above" } ) + + ... + end \ No newline at end of file From ceb0fa244ceba0f503dd1aae8cbe48fcda47c11a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:34:00 -0700 Subject: [PATCH 110/546] Created bat (markdown) --- bat.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 bat.md diff --git a/bat.md b/bat.md new file mode 100644 index 0000000..9e2d8c5 --- /dev/null +++ b/bat.md @@ -0,0 +1,18 @@ +Shows the remaining time and percentage capacity of your laptop battery, as well as +the current wattage. + +Displays a notification when battery is low or critical. + + mybattery = lain.widgets.bat() + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`battery` | Identifier of the battery | string | "BAT0" +`show_all` | Show all values (true), or only remaining capacity (false) | boolean | false +`refresh_timeout` | Refresh timeout seconds | int | 30 +`header` | Text to show before value | string | " Vol " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`shadow` | Hide the widget when battery is not present | boolean | false \ No newline at end of file From 72c66149c4f140a2b1b4bc8af49fcc5ee82f8ad1 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:37:03 -0700 Subject: [PATCH 111/546] Created alsabar (markdown) --- alsabar.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 alsabar.md diff --git a/alsabar.md b/alsabar.md new file mode 100644 index 0000000..a4d1768 --- /dev/null +++ b/alsabar.md @@ -0,0 +1,81 @@ +Shows and controls alsa volume with a progressbar. + +Dependencies: + +- alsa-utils + +Plus tooltips, notifications, and color changes at mute/unmute switch. + + myvolumebar = lain.widgets.alsabar() + +* Left click: Launch `alsamixer` in your `terminal`. +* Right click: Mute/unmute. +* Scroll wheel: Increase/decrase volume. + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`width` | Bar width | int | 63 +`height` | Bar height | int | 1 +`ticks` | Set bar ticks on | boolean | true +`ticks_size` | Ticks size | int | 7 +`vertical` | Set the bar vertical | boolean | false +`channel` | Mixer channel | string | "Master" +`step` | Step at which volume is increased/decreased | string | "5%" +`colors` | Bar colors | table | see **colors** +`notifications` | Notifications settings | table | see **notifications** + +### colors + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`background` | Bar backgrund color | string | `beautiful.bg_normal` +`mute` | Bar mute color | string | "#EB8F8F" +`unmute` | Bar unmute color | string | "#A4CE8A" + +### notifications + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`font` | Notifications font | string | The one defined in `beautiful.font` +`font_size` | Notifications font size | string | "11" +`bar_size` | Wibox height | int | 18 + +It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height, +**if** you have set it different than default (18). + +`lain.widgets.alsabar` outputs the following table: + +Variable | Type +--- | --- +`widget` | `awful.widget.progressbar` +`channel` | string +`step` | string +`notify` | function + +Finally, you can control the widget with the following key bindings: + + -- Volume control + awful.key({ altkey }, "Up", + function () + awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "+") + volume.notify() + end), + awful.key({ altkey }, "Down", + function () + awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "-") + volume.notify() + end), + awful.key({ altkey }, "m", + function () + awful.util.spawn("amixer set Master playback toggle") + volume.notify() + end), + awful.key({ altkey, "Control" }, "m", + function () + awful.util.spawn("amixer set Master playback 100%", false ) + volume.notify() + end), + +where `altkey = "Mod1"`. \ No newline at end of file From cfef77b46de4f24c8a6673bac0fae018b808deb4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:37:23 -0700 Subject: [PATCH 112/546] Updated alsabar (markdown) --- alsabar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsabar.md b/alsabar.md index a4d1768..76e1205 100644 --- a/alsabar.md +++ b/alsabar.md @@ -2,7 +2,7 @@ Shows and controls alsa volume with a progressbar. Dependencies: -- alsa-utils +- alsa-utils (of course) Plus tooltips, notifications, and color changes at mute/unmute switch. From 8ab16023e0b52a864ec47cd9366e82f5ab8f48cd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:38:35 -0700 Subject: [PATCH 113/546] Updated alsabar (markdown) --- alsabar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsabar.md b/alsabar.md index 76e1205..53c49b4 100644 --- a/alsabar.md +++ b/alsabar.md @@ -54,7 +54,7 @@ Variable | Type `step` | string `notify` | function -Finally, you can control the widget with the following key bindings: +Finally, you can control the widget with key bindings like these: -- Volume control awful.key({ altkey }, "Up", From ab333a27fe771e9ce70ed6896a6b3e2cfd9c3074 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:39:52 -0700 Subject: [PATCH 114/546] Created alsa (markdown) --- alsa.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 alsa.md diff --git a/alsa.md b/alsa.md new file mode 100644 index 0000000..5a3497b --- /dev/null +++ b/alsa.md @@ -0,0 +1,52 @@ +Shows and controls alsa volume with a textbox. + + myvolume = lain.widgets.alsa() + +* Left click: Launch `alsamixer` in your `terminal`. +* Right click: Mute/unmute. +* Scroll wheel: Increase/decrase volume. + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`channel` | Mixer channel | string | "Master" +`step` | Step at which volume is increased/decreased | string | "1%" +`header` | Text to show before value | string | " Vol " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" + +and outputs the following table: + +Variable | Type +--- | --- +`widget` | `awful.widget.textbox` +`channel` | string +`step` | string +`notify` | function + +Finally, you can control the widget with key bindings like these: + + -- Volume control + awful.key({ altkey }, "Up", + function () + awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "+") + volume.notify() + end), + awful.key({ altkey }, "Down", + function () + awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "-") + volume.notify() + end), + awful.key({ altkey }, "m", + function () + awful.util.spawn("amixer set Master playback toggle") + volume.notify() + end), + awful.key({ altkey, "Control" }, "m", + function () + awful.util.spawn("amixer set Master playback 100%", false ) + volume.notify() + end), + +where `altkey = "Mod1"`. \ No newline at end of file From 8291632c2a2cb6f7fb9bf329891643ff2846c7c7 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:40:38 -0700 Subject: [PATCH 115/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 98016fb..0659682 100644 --- a/fs.md +++ b/fs.md @@ -25,7 +25,7 @@ Variable | Type `widget` | `wibox.widget.textbox` `show` | function -You can display a notification of current disk space usage with the following key binding: +You can display a notification of current disk space usage with a key binding like this: awful.key({ altkey }, "h", function () mypartition.show(7) end), From 2cc273cb7178340c257f237245c4c5bc2f5a72de Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 03:41:20 -0700 Subject: [PATCH 116/546] Created Widgets (markdown) --- Widgets.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Widgets.md diff --git a/Widgets.md b/Widgets.md new file mode 100644 index 0000000..cbf3fb9 --- /dev/null +++ b/Widgets.md @@ -0,0 +1,9 @@ +### Foreword + +Every widget is output by a `function`. + +Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. + +We say this because, for some widget, `function` return a table to be used for notification and update purposes. + +### Index \ No newline at end of file From 292dde8d6e38f1d8a6fe471a184e83d7bd4aef28 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:10:14 -0700 Subject: [PATCH 117/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 5f8ce30..085cb8d 100644 --- a/imap.md +++ b/imap.md @@ -2,7 +2,7 @@ Check new mails over IMAP protocol. Dependencies: -- Python3 +- python3 New mails are notified through a notification like this: From 02dcebd0de7bcddcb64a857607c0259f6db9fbf2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:18:36 -0700 Subject: [PATCH 118/546] Updated alsa (markdown) --- alsa.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/alsa.md b/alsa.md index 5a3497b..3b485c2 100644 --- a/alsa.md +++ b/alsa.md @@ -18,12 +18,12 @@ Variable | Meaning | Type | Default and outputs the following table: -Variable | Type ---- | --- -`widget` | `awful.widget.textbox` -`channel` | string -`step` | string -`notify` | function +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget | `wibox.widget.textbox` +`channel` | Alsa channel | string +`step` | Increase/decrease step | string +`notify` | The notification | function Finally, you can control the widget with key bindings like these: From de3844ebb91785807c592f3094f62142e8deb615 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:19:48 -0700 Subject: [PATCH 119/546] Updated alsabar (markdown) --- alsabar.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/alsabar.md b/alsabar.md index 53c49b4..8275101 100644 --- a/alsabar.md +++ b/alsabar.md @@ -47,12 +47,12 @@ It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height, `lain.widgets.alsabar` outputs the following table: -Variable | Type ---- | --- -`widget` | `awful.widget.progressbar` -`channel` | string -`step` | string -`notify` | function +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget | `awful.widget.progressbar` +`channel` | Alsa channel | string +`step` | Increase/decrease step | string +`notify` | The notification | function Finally, you can control the widget with key bindings like these: From b66251c1c0b6ce671d3e910e820607ecdff27c77 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:21:12 -0700 Subject: [PATCH 120/546] Updated fs (markdown) --- fs.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs.md b/fs.md index 0659682..951f73b 100644 --- a/fs.md +++ b/fs.md @@ -20,10 +20,10 @@ Variable | Meaning | Type | Default `lain.widgets.fs` outputs the following table: -Variable | Type ---- | --- -`widget` | `wibox.widget.textbox` -`show` | function +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget | `wibox.widget.textbox` +`show` | The notification | function You can display a notification of current disk space usage with a key binding like this: From cdcd4064b8f00147020e3a491a15b92c41ecb24f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:21:34 -0700 Subject: [PATCH 121/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 951f73b..3b43d8c 100644 --- a/fs.md +++ b/fs.md @@ -25,7 +25,7 @@ Variable | Meaning | Type `widget` | The widget | `wibox.widget.textbox` `show` | The notification | function -You can display a notification of current disk space usage with a key binding like this: +You can display the notification with a key binding like this: awful.key({ altkey }, "h", function () mypartition.show(7) end), From f4adc5c667ff0f5b87016faee7fd4520dd4096bd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:22:29 -0700 Subject: [PATCH 122/546] Updated calendar (markdown) --- calendar.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/calendar.md b/calendar.md index 06e1b48..9330df7 100644 --- a/calendar.md +++ b/calendar.md @@ -1,6 +1,6 @@ -Attaches a calendar to a ``widget``. Example: +Attaches a calendar to a ``widget``. - lain.widgets.calendar:attach(mytextclock) + lain.widgets.calendar:attach(mywidget) - Left click: switch to previous month. - Right click: switch to next month. From b31fd2ec56cff3d3c9dc657b811ec53be6cff65a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:22:53 -0700 Subject: [PATCH 123/546] Updated calendar (markdown) --- calendar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calendar.md b/calendar.md index 9330df7..bfceac9 100644 --- a/calendar.md +++ b/calendar.md @@ -1,4 +1,4 @@ -Attaches a calendar to a ``widget``. +Attaches a calendar to a widget. lain.widgets.calendar:attach(mywidget) From ed18660087836a09bd47bb6b308d15a822c69673 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:25:10 -0700 Subject: [PATCH 124/546] Updated alsa (markdown) --- alsa.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index 3b485c2..7500bf8 100644 --- a/alsa.md +++ b/alsa.md @@ -23,7 +23,7 @@ Variable | Meaning | Type `widget` | The widget | `wibox.widget.textbox` `channel` | Alsa channel | string `step` | Increase/decrease step | string -`notify` | The notification | function +`notify` | Update `widget` | function Finally, you can control the widget with key bindings like these: From e9eb20ed177b799a1cf353e0180c835a396c9be2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:30:54 -0700 Subject: [PATCH 125/546] Created mpd (markdown) --- mpd.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 mpd.md diff --git a/mpd.md b/mpd.md new file mode 100644 index 0000000..17acab8 --- /dev/null +++ b/mpd.md @@ -0,0 +1,67 @@ +Shows mpd status in a textbox. + + mympd = lain.widgets.mpd() + +Now playing songs are notified like this: + + +--------------------------------------------------------+ + | +-------+ | + | |/^\_/^\| Now playing | + | |\ O O /| Cannibal Corpse (Hammer Smashed Face) - 1993 | + | | '.o.' | Hammer Smashed Face (Radio Disney Version) | + | +-------+ | + +--------------------------------------------------------+ + +Dependencies + +- imagemagick + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`password` | Mpd password | string | "" +`host` | Mpd server | string | "127.0.0.1" +`port` | Mpd port | string | "6600" +`music_dir` | Music directory | string | "~/Music" +`refresh_timeout` | Refresh timeout seconds | int | 1 +`color_artist` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" +`color_song` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" +`spr` | Separator text between artist and song values | string | " " +`app` | Music program to spawn on click | string | "ncmpcpp" +`shadow` | Hide widget when there are no songs playing | boolean | false + +**Note**: `spr` can be a markup text. + +`lain.widgets.mpd` outputs the following table: + +Variable | Meaning | Type +--- | --- | --- +`widget` | The textbox | `wibox.widget.textbox` +`notify` | The notification | function + +Finally, you can control the widget with key bindings like these: + + -- MPD control + awful.key({ altkey, "Control" }, "Up", + function () + awful.util.spawn_with_shell( "mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle", false ) + mympd.notify() + end), + awful.key({ altkey, "Control" }, "Down", + function () + awful.util.spawn_with_shell( "mpc stop || ncmpcpp stop || ncmpc stop || pms stop", false ) + mympd.notify() + end), + awful.key({ altkey, "Control" }, "Left", + function () + awful.util.spawn_with_shell( "mpc prev || ncmpcpp prev || ncmpc prev || pms prev", false ) + mympd.notify() + end), + awful.key({ altkey, "Control" }, "Right", + function () + awful.util.spawn_with_shell( "mpc next || ncmpcpp next || ncmpc next || pms next", false ) + mympd.notify() + end), + +where `altkey = "Mod1"`. \ No newline at end of file From 77bc9494c6b16bb3c81782a9a40f497245d323e0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:34:31 -0700 Subject: [PATCH 126/546] Updated alsabar (markdown) --- alsabar.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/alsabar.md b/alsabar.md index 8275101..52fa417 100644 --- a/alsabar.md +++ b/alsabar.md @@ -56,26 +56,26 @@ Variable | Meaning | Type Finally, you can control the widget with key bindings like these: - -- Volume control - awful.key({ altkey }, "Up", - function () - awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "+") - volume.notify() - end), - awful.key({ altkey }, "Down", - function () - awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "-") - volume.notify() - end), - awful.key({ altkey }, "m", - function () - awful.util.spawn("amixer set Master playback toggle") - volume.notify() - end), - awful.key({ altkey, "Control" }, "m", - function () - awful.util.spawn("amixer set Master playback 100%", false ) - volume.notify() - end), + -- Volume control + awful.key({ altkey }, "Up", + function () + awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "+") + volume.notify() + end), + awful.key({ altkey }, "Down", + function () + awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "-") + volume.notify() + end), + awful.key({ altkey }, "m", + function () + awful.util.spawn("amixer set Master playback toggle") + volume.notify() + end), + awful.key({ altkey, "Control" }, "m", + function () + awful.util.spawn("amixer set Master playback 100%", false ) + volume.notify() + end), where `altkey = "Mod1"`. \ No newline at end of file From b23721b66d3c5bfd7105d1bacbf5643910a171a0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:34:48 -0700 Subject: [PATCH 127/546] Updated alsabar (markdown) --- alsabar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsabar.md b/alsabar.md index 52fa417..c9e3b49 100644 --- a/alsabar.md +++ b/alsabar.md @@ -76,6 +76,6 @@ Finally, you can control the widget with key bindings like these: function () awful.util.spawn("amixer set Master playback 100%", false ) volume.notify() - end), + end), where `altkey = "Mod1"`. \ No newline at end of file From b2014a69099c2419ccfef611e772514bd86ace9c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:35:37 -0700 Subject: [PATCH 128/546] Updated alsa (markdown) --- alsa.md | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/alsa.md b/alsa.md index 7500bf8..fb9b28f 100644 --- a/alsa.md +++ b/alsa.md @@ -27,26 +27,26 @@ Variable | Meaning | Type Finally, you can control the widget with key bindings like these: - -- Volume control - awful.key({ altkey }, "Up", - function () - awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "+") - volume.notify() - end), - awful.key({ altkey }, "Down", - function () - awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "-") - volume.notify() - end), - awful.key({ altkey }, "m", - function () - awful.util.spawn("amixer set Master playback toggle") - volume.notify() - end), - awful.key({ altkey, "Control" }, "m", - function () - awful.util.spawn("amixer set Master playback 100%", false ) - volume.notify() - end), + -- Volume control + awful.key({ altkey }, "Up", + function () + awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "+") + volume.notify() + end), + awful.key({ altkey }, "Down", + function () + awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "-") + volume.notify() + end), + awful.key({ altkey }, "m", + function () + awful.util.spawn("amixer set Master playback toggle") + volume.notify() + end), + awful.key({ altkey, "Control" }, "m", + function () + awful.util.spawn("amixer set Master playback 100%", false ) + volume.notify() + end), where `altkey = "Mod1"`. \ No newline at end of file From c7b41d9529f4fac35999f97b1af66674d1e170bf Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:37:51 -0700 Subject: [PATCH 129/546] Updated mpd (markdown) --- mpd.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mpd.md b/mpd.md index 17acab8..d86b2c6 100644 --- a/mpd.md +++ b/mpd.md @@ -1,4 +1,4 @@ -Shows mpd status in a textbox. +Shows MPD status in a textbox. mympd = lain.widgets.mpd() @@ -20,9 +20,9 @@ The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- -`password` | Mpd password | string | "" -`host` | Mpd server | string | "127.0.0.1" -`port` | Mpd port | string | "6600" +`password` | MPD password | string | "" +`host` | MPD server | string | "127.0.0.1" +`port` | MPD port | string | "6600" `music_dir` | Music directory | string | "~/Music" `refresh_timeout` | Refresh timeout seconds | int | 1 `color_artist` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" From 163e0c27693a1e765132c6368a2b38e9f840e4b8 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:55:46 -0700 Subject: [PATCH 130/546] Created net (markdown) --- net.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 net.md diff --git a/net.md b/net.md new file mode 100644 index 0000000..58b27e3 --- /dev/null +++ b/net.md @@ -0,0 +1,30 @@ +Monitors network interfaces and shows current traffic in a textbox. + + mynet = lain.widgets.net() + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`iface` | Network device | string | autodetected +`refresh_timeout` | Refresh timeout seconds | int | 2 +`units` | Units | int | 1024 (kilobytes) +`spr` | Separator text between download and upload values | string | " " +`header` | Text to show before value | string | `iface` +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color_up` | Upload value color | string | `beautiful.fg_focus` or "#FFFFFF" +`color_down` | Download value color | string | `beautiful.fg_focus` or "#FFFFFF" +`app` | Net program to spawn on click | string | "sudo wifi-menu" + +**Note**: `spr` can be a markup text. + +Possible value for `units` are stored in table `lain.widgets.net.units`, which contains: + + { + ["b"] = 1, + ["kb"] = 1024, + ["mb"] = 1024^2, + ["gb"] = 1024^3 + } + + From 17e84dc2f7af8aae99a7912b9d31c0e28d338d22 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:56:53 -0700 Subject: [PATCH 131/546] Updated net (markdown) --- net.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/net.md b/net.md index 58b27e3..868fb68 100644 --- a/net.md +++ b/net.md @@ -20,11 +20,7 @@ Variable | Meaning | Type | Default Possible value for `units` are stored in table `lain.widgets.net.units`, which contains: - { - ["b"] = 1, - ["kb"] = 1024, - ["mb"] = 1024^2, - ["gb"] = 1024^3 - } - - + ["b"] = 1, + ["kb"] = 1024, + ["mb"] = 1024^2, + ["gb"] = 1024^3 \ No newline at end of file From ea45c499c8a88fbacc43b76e743a713e8e23d85f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:57:14 -0700 Subject: [PATCH 132/546] Updated net (markdown) --- net.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net.md b/net.md index 868fb68..c3a635c 100644 --- a/net.md +++ b/net.md @@ -20,7 +20,7 @@ Variable | Meaning | Type | Default Possible value for `units` are stored in table `lain.widgets.net.units`, which contains: - ["b"] = 1, - ["kb"] = 1024, + ["b"] = 1, + ["kb"] = 1024, ["mb"] = 1024^2, ["gb"] = 1024^3 \ No newline at end of file From 97e3e0ac9bf8b72a8d8afa27d84bdb19acc7fe9d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 04:57:32 -0700 Subject: [PATCH 133/546] Updated net (markdown) --- net.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net.md b/net.md index c3a635c..59390dc 100644 --- a/net.md +++ b/net.md @@ -22,5 +22,5 @@ Possible value for `units` are stored in table `lain.widgets.net.units`, which c ["b"] = 1, ["kb"] = 1024, - ["mb"] = 1024^2, - ["gb"] = 1024^3 \ No newline at end of file + ["mb"] = 1024^2, + ["gb"] = 1024^3 \ No newline at end of file From 4460c5da4b01fad8e5acec0a645852a822244480 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:03:04 -0700 Subject: [PATCH 134/546] Created sysload (markdown) --- sysload.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 sysload.md diff --git a/sysload.md b/sysload.md new file mode 100644 index 0000000..5b925b1 --- /dev/null +++ b/sysload.md @@ -0,0 +1,14 @@ +Show the current system load in a textbox. + + mysysload = lain.widgets.systemload() + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`show_all` | Show all the three values (true), or only the first one (false) | boolean | false +`refresh_timeout` | Refresh timeout seconds | int | 5 +`header` | Text to show before value | string | " Load " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`app` | Proc program to spawn on click | string | "top" \ No newline at end of file From 3e465b38765d8014a9ced65ef22085f7ea15cc24 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:03:21 -0700 Subject: [PATCH 135/546] Updated sysload (markdown) --- sysload.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysload.md b/sysload.md index 5b925b1..0e57a8f 100644 --- a/sysload.md +++ b/sysload.md @@ -1,6 +1,6 @@ Show the current system load in a textbox. - mysysload = lain.widgets.systemload() + mysysload = lain.widgets.sysload() The function takes a table as optional argument, which can contain: From f17dab83cc635d13cac4b35934597665a47ce130 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:07:01 -0700 Subject: [PATCH 136/546] Created temp (markdown) --- temp.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 temp.md diff --git a/temp.md b/temp.md new file mode 100644 index 0000000..60d03e2 --- /dev/null +++ b/temp.md @@ -0,0 +1,13 @@ +Show the current core temperature in a textbox. Reads from `/sys/class/thermal`, so value is expressed in Celsius. + + mytemp = lain.widgets.temp() + +The function takes a table as optional argument, which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`refresh_timeout` | Refresh timeout seconds | int | 5 +`header` | Text to show before value | string | " Temp " +`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to show after value | string | "C " \ No newline at end of file From e193d724e991ec0af63d786674e280444b9e289c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:07:17 -0700 Subject: [PATCH 137/546] Updated temp (markdown) --- temp.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/temp.md b/temp.md index 60d03e2..11a8aa1 100644 --- a/temp.md +++ b/temp.md @@ -1,4 +1,6 @@ -Show the current core temperature in a textbox. Reads from `/sys/class/thermal`, so value is expressed in Celsius. +Show the current core temperature in a textbox. + +Reads from `/sys/class/thermal`, so value is expressed in Celsius. mytemp = lain.widgets.temp() From 6a74f4b2823c91f89be60dc6d2f8a0056141aae4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:08:42 -0700 Subject: [PATCH 138/546] Updated mem (markdown) --- mem.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mem.md b/mem.md index 58ccf72..1efdb3a 100644 --- a/mem.md +++ b/mem.md @@ -1,4 +1,4 @@ -Show used memory and total memory in MiB. +Shows memory status (in MiB) in a textbox. mymem = lain.widgets.mem() @@ -11,7 +11,7 @@ Variable | Meaning | Type | Default `refresh_timeout` | Refresh timeout seconds | int | 10 `show_swap` | Show amount of used swap space? | boolean | false `show_total` | Show amout of total memory? | boolean | false -`header` | Text to show before value | string | " Vol " +`header` | Text to show before value | string | " Mem " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `footer` | Text to show after value | string | "MB" From 672a961cc7a37472ff0f506a4bc09dfa6e9b6e7d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:09:48 -0700 Subject: [PATCH 139/546] Updated maildir (markdown) --- maildir.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maildir.md b/maildir.md index df5f6fe..28de551 100644 --- a/maildir.md +++ b/maildir.md @@ -17,10 +17,10 @@ Maildirs are structured as follows: . therefore the widget checks whether there are files in the `new` directories. -If there's new mail, the textbox will say something like "mail: bugs(3), system(1)", otherwise it says +If there's new mails, the textbox will say something like "mail: bugs(3), system(1)", otherwise it says "no mail". - mymaildir= lain.widgets.maildir("/path/to/my/maildir") + mymaildir = lain.widgets.maildir("/path/to/my/maildir") The function takes a table as optional argument, which can contain: From 9a44e9e1d9cb4eede11914e7ef4f75b01c5beb81 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:10:43 -0700 Subject: [PATCH 140/546] Updated maildir (markdown) --- maildir.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maildir.md b/maildir.md index 28de551..c35b2f9 100644 --- a/maildir.md +++ b/maildir.md @@ -1,4 +1,4 @@ -Checks your maildirs. +Shows maildirs status in a textbox. Maildirs are structured as follows: From a899e34790f3408c0067bfafa0604fafb256226b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:11:28 -0700 Subject: [PATCH 141/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 085cb8d..a11759a 100644 --- a/imap.md +++ b/imap.md @@ -1,4 +1,4 @@ -Check new mails over IMAP protocol. +Show mail status in a textbox over IMAP protocol. Dependencies: From b6c95bf9fcb2594ed83cfcc0d3709e8a43f919fd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:11:42 -0700 Subject: [PATCH 142/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index a11759a..2a70a4c 100644 --- a/imap.md +++ b/imap.md @@ -1,4 +1,4 @@ -Show mail status in a textbox over IMAP protocol. +Shows mail status in a textbox over IMAP protocol. Dependencies: From b9966b88effe133345227c6793446f7e99620fa9 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:12:13 -0700 Subject: [PATCH 143/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index ce59a15..01af669 100644 --- a/cpu.md +++ b/cpu.md @@ -1,4 +1,4 @@ -Shows the average CPU usage percent for a given amount of time. +Shows in a textbox the average CPU usage percent for a given amount of time. mycpuusage = lain.widgets.cpu() From b96c57eced572d4783d106ee3a4ebeb831be4303 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:12:52 -0700 Subject: [PATCH 144/546] Updated calendar (markdown) --- calendar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calendar.md b/calendar.md index bfceac9..182c805 100644 --- a/calendar.md +++ b/calendar.md @@ -1,4 +1,4 @@ -Attaches a calendar to a widget. +Attaches a calendar notification to a widget. lain.widgets.calendar:attach(mywidget) From 59e4ab9457b66124403afee78685b9282c1aea1f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:13:26 -0700 Subject: [PATCH 145/546] Updated bat (markdown) --- bat.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bat.md b/bat.md index 9e2d8c5..3ff9e65 100644 --- a/bat.md +++ b/bat.md @@ -1,4 +1,4 @@ -Shows the remaining time and percentage capacity of your laptop battery, as well as +Shows in a textbox the remaining time and percentage capacity of your laptop battery, as well as the current wattage. Displays a notification when battery is low or critical. @@ -12,7 +12,7 @@ Variable | Meaning | Type | Default `battery` | Identifier of the battery | string | "BAT0" `show_all` | Show all values (true), or only remaining capacity (false) | boolean | false `refresh_timeout` | Refresh timeout seconds | int | 30 -`header` | Text to show before value | string | " Vol " +`header` | Text to show before value | string | " Bat " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `shadow` | Hide the widget when battery is not present | boolean | false \ No newline at end of file From 5d3ed5d054442e2c2d3c46941bbc3f029d2337ae Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:14:53 -0700 Subject: [PATCH 146/546] Updated alsa (markdown) --- alsa.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index fb9b28f..f978bce 100644 --- a/alsa.md +++ b/alsa.md @@ -1,4 +1,4 @@ -Shows and controls alsa volume with a textbox. +Shows and controls alsa volume. myvolume = lain.widgets.alsa() From 5ee0d86b58eb23370f76e2a4039657bb80041033 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:15:53 -0700 Subject: [PATCH 147/546] Updated alsa (markdown) --- alsa.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index f978bce..fb9b28f 100644 --- a/alsa.md +++ b/alsa.md @@ -1,4 +1,4 @@ -Shows and controls alsa volume. +Shows and controls alsa volume with a textbox. myvolume = lain.widgets.alsa() From a7135944e2698660fa289ea993161d5401302433 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:18:02 -0700 Subject: [PATCH 148/546] Updated Home (markdown) --- Home.md | 1 - Index.md | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 Home.md create mode 100644 Index.md diff --git a/Home.md b/Home.md deleted file mode 100644 index a520d81..0000000 --- a/Home.md +++ /dev/null @@ -1 +0,0 @@ -Welcome to the lain wiki! \ No newline at end of file diff --git a/Index.md b/Index.md new file mode 100644 index 0000000..e14945d --- /dev/null +++ b/Index.md @@ -0,0 +1,3 @@ +- [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts) +- [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets) +- Utilities \ No newline at end of file From 7f46337293d0fc354a391ea5270c3df2b397bfb4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:19:32 -0700 Subject: [PATCH 149/546] Updated Index (markdown) --- Index.md => Home.md | 2 ++ 1 file changed, 2 insertions(+) rename Index.md => Home.md (85%) diff --git a/Index.md b/Home.md similarity index 85% rename from Index.md rename to Home.md index e14945d..434dfdc 100644 --- a/Index.md +++ b/Home.md @@ -1,3 +1,5 @@ +### Index + - [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts) - [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - Utilities \ No newline at end of file From b7b7f9ab80c28e30c2f0445e27430a2243d1f5f9 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:20:29 -0700 Subject: [PATCH 150/546] Updated Home (markdown) --- Home.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Home.md b/Home.md index 434dfdc..f8b1142 100644 --- a/Home.md +++ b/Home.md @@ -1,5 +1,10 @@ +### Installation + +Simply clone this repository into your Awesome directory. + ### Index +- [To start](https://github.com/copycat-killer/lain/wiki/To-start) - [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts) - [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - Utilities \ No newline at end of file From ada338f4db16cb69f2510c057b4535e0738dfff6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:27:01 -0700 Subject: [PATCH 151/546] Updated Widgets (markdown) --- Widgets.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Widgets.md b/Widgets.md index cbf3fb9..7c1349e 100644 --- a/Widgets.md +++ b/Widgets.md @@ -1,4 +1,5 @@ -### Foreword +[<- home](https://github.com/copycat-killer/lain/wiki) + Every widget is output by a `function`. @@ -6,4 +7,19 @@ Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. We say this because, for some widget, `function` return a table to be used for notification and update purposes. -### Index \ No newline at end of file +------- + +- [alsa](https://github.com/copycat-killer/lain/wiki/alsa) +- [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) +- [bat](https://github.com/copycat-killer/lain/wiki/bat) +- [borderbox](https://github.com/copycat-killer/lain/wiki/borderbox) +- [calendar](https://github.com/copycat-killer/lain/wiki/caldendar) +- [cpu](https://github.com/copycat-killer/lain/wiki/cpu) +- [fs](https://github.com/copycat-killer/lain/wiki/fs) +- [imap](https://github.com/copycat-killer/lain/wiki/imap) +- [maildir](https://github.com/copycat-killer/lain/wiki/maildir) +- [mem](https://github.com/copycat-killer/lain/wiki/mem) +- [mpd](https://github.com/copycat-killer/lain/wiki/mpd) +- [net](https://github.com/copycat-killer/lain/wiki/net) +- [sysload](https://github.com/copycat-killer/lain/wiki/sysload) +- [temp](https://github.com/copycat-killer/lain/wiki/temp) \ No newline at end of file From e187c6d9853fe09d023066daa1a03ec85cc5be5c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:27:20 -0700 Subject: [PATCH 152/546] Updated Widgets (markdown) --- Widgets.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/Widgets.md b/Widgets.md index 7c1349e..f6fde73 100644 --- a/Widgets.md +++ b/Widgets.md @@ -1,14 +1,11 @@ [<- home](https://github.com/copycat-killer/lain/wiki) - Every widget is output by a `function`. Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. We say this because, for some widget, `function` return a table to be used for notification and update purposes. -------- - - [alsa](https://github.com/copycat-killer/lain/wiki/alsa) - [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) - [bat](https://github.com/copycat-killer/lain/wiki/bat) From 16b2d796d069afb2ca5d405eaedb00ee9325fd80 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:28:39 -0700 Subject: [PATCH 153/546] Updated To start (markdown) --- To-start.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/To-start.md b/To-start.md index 9135be2..5a3f3db 100644 --- a/To-start.md +++ b/To-start.md @@ -1,3 +1,5 @@ +[<- home](https://github.com/copycat-killer/lain/wiki) + All you have to do is to include the module: local lain = require("lain") From 81b985db46ed6d465dfec620fd0d9be5544428cf Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:28:58 -0700 Subject: [PATCH 154/546] Updated Layouts (markdown) --- Layouts.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Layouts.md b/Layouts.md index 7f50efe..cc5b75d 100644 --- a/Layouts.md +++ b/Layouts.md @@ -1,3 +1,5 @@ +[<- home](https://github.com/copycat-killer/lain/wiki) + Currently, there are **7** layouts. lain/layout From b044036e24748c2582f01c73c1af9bc2790e5ab1 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:29:27 -0700 Subject: [PATCH 155/546] Created Utilities (markdown) --- Utilities.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 Utilities.md diff --git a/Utilities.md b/Utilities.md new file mode 100644 index 0000000..7bf82a0 --- /dev/null +++ b/Utilities.md @@ -0,0 +1 @@ +[<- home](https://github.com/copycat-killer/lain/wiki) \ No newline at end of file From d83966b518792efede931b337313991180056f9a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:30:13 -0700 Subject: [PATCH 156/546] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index f8b1142..5dfbd14 100644 --- a/Home.md +++ b/Home.md @@ -7,4 +7,4 @@ Simply clone this repository into your Awesome directory. - [To start](https://github.com/copycat-killer/lain/wiki/To-start) - [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts) - [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -- Utilities \ No newline at end of file +- [Utilities](https://github.com/copycat-killer/lain/wiki/Utilities) \ No newline at end of file From 8e42c94062506dd240f9c5ded44bf1a43610dc3c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:30:47 -0700 Subject: [PATCH 157/546] Updated To start (markdown) --- To-start.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/To-start.md b/To-start.md index 5a3f3db..309e09b 100644 --- a/To-start.md +++ b/To-start.md @@ -25,4 +25,6 @@ Something like this: -- elaborate cmd end - lain.widgets.terminal = footerm \ No newline at end of file + lain.widgets.terminal = footerm + +[<- home](https://github.com/copycat-killer/lain/wiki) \ No newline at end of file From 1b6649b1051106d43ce183ff0535bc5defed551d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:31:05 -0700 Subject: [PATCH 158/546] Updated Utilities (markdown) --- Utilities.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Utilities.md b/Utilities.md index 7bf82a0..c3bbf8b 100644 --- a/Utilities.md +++ b/Utilities.md @@ -1 +1,3 @@ +[<- home](https://github.com/copycat-killer/lain/wiki) + [<- home](https://github.com/copycat-killer/lain/wiki) \ No newline at end of file From b52f0747fd96aaa4ced67c800bd28c0253ad6a93 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:31:25 -0700 Subject: [PATCH 159/546] Updated Layouts (markdown) --- Layouts.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Layouts.md b/Layouts.md index cc5b75d..f9dd490 100644 --- a/Layouts.md +++ b/Layouts.md @@ -267,4 +267,6 @@ To use them, add lines to your ``theme.lua`` like this: Credits goes to [Nicolas Estibals](https://github.com/nestibal) for creating layout icons for default theme. -You can use them as a template for your custom versions. \ No newline at end of file +You can use them as a template for your custom versions. + +[<- home](https://github.com/copycat-killer/lain/wiki) \ No newline at end of file From 620bc5b57f40296fccfe6e714416fe5541b6fd15 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:31:49 -0700 Subject: [PATCH 160/546] Updated To start (markdown) --- To-start.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/To-start.md b/To-start.md index 309e09b..36f32a0 100644 --- a/To-start.md +++ b/To-start.md @@ -26,5 +26,3 @@ Something like this: end lain.widgets.terminal = footerm - -[<- home](https://github.com/copycat-killer/lain/wiki) \ No newline at end of file From ac046b943f5e8594b9dad1709d0b543a23eb696c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:33:08 -0700 Subject: [PATCH 161/546] Updated temp (markdown) --- temp.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/temp.md b/temp.md index 11a8aa1..92d7d06 100644 --- a/temp.md +++ b/temp.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Show the current core temperature in a textbox. Reads from `/sys/class/thermal`, so value is expressed in Celsius. From 97bbc2021d7c4fb51a167e9752cc1477e2ed4156 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:33:23 -0700 Subject: [PATCH 162/546] Updated sysload (markdown) --- sysload.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sysload.md b/sysload.md index 0e57a8f..65b5eec 100644 --- a/sysload.md +++ b/sysload.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Show the current system load in a textbox. mysysload = lain.widgets.sysload() From 1eda4c6c1a32ada1c66785ef59fc0a9bd425424e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:33:41 -0700 Subject: [PATCH 163/546] Updated net (markdown) --- net.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net.md b/net.md index 59390dc..b02c239 100644 --- a/net.md +++ b/net.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Monitors network interfaces and shows current traffic in a textbox. mynet = lain.widgets.net() From a5ebcbb89a533b33f1e1d13f8d9df462577fa1a5 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:33:53 -0700 Subject: [PATCH 164/546] Updated mpd (markdown) --- mpd.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mpd.md b/mpd.md index d86b2c6..27f3faf 100644 --- a/mpd.md +++ b/mpd.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows MPD status in a textbox. mympd = lain.widgets.mpd() From ecdc9a993b1e2d618161e4bc562540920aaa1240 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:34:12 -0700 Subject: [PATCH 165/546] Updated mem (markdown) --- mem.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mem.md b/mem.md index 1efdb3a..173452d 100644 --- a/mem.md +++ b/mem.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows memory status (in MiB) in a textbox. mymem = lain.widgets.mem() From 9eb1daba9889c2bce76bdf3d88a4595f4ad27771 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:34:27 -0700 Subject: [PATCH 166/546] Updated imap (markdown) --- imap.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imap.md b/imap.md index 2a70a4c..d7e68b4 100644 --- a/imap.md +++ b/imap.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows mail status in a textbox over IMAP protocol. Dependencies: From 2d469360e72a9e9561589ae9ed3776bc9e727cf0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:34:38 -0700 Subject: [PATCH 167/546] Updated fs (markdown) --- fs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs.md b/fs.md index 3b43d8c..4946fe7 100644 --- a/fs.md +++ b/fs.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows disk space usage for a set partition. Displays a notification when the partition is full or has low space. From 55e66744a3ce0f8ca79421f3ae2dcb620fcb91e2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:34:51 -0700 Subject: [PATCH 168/546] Updated cpu (markdown) --- cpu.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpu.md b/cpu.md index 01af669..9dcc894 100644 --- a/cpu.md +++ b/cpu.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows in a textbox the average CPU usage percent for a given amount of time. mycpuusage = lain.widgets.cpu() From eaf20781fb76ea536f0d8e5bf84efb0bf949b263 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:35:10 -0700 Subject: [PATCH 169/546] Updated borderbox (markdown) --- borderbox.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/borderbox.md b/borderbox.md index cdeece2..e4d7afb 100644 --- a/borderbox.md +++ b/borderbox.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Creates a thin wibox at a position relative to another wibox. This allows to create "borders" for your wiboxes. From b7c7e112110785966e45ab8d0475f32278046e13 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:35:22 -0700 Subject: [PATCH 170/546] Updated bat (markdown) --- bat.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bat.md b/bat.md index 3ff9e65..79c17da 100644 --- a/bat.md +++ b/bat.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows in a textbox the remaining time and percentage capacity of your laptop battery, as well as the current wattage. From 1db513aa20604693d67850861389f598de271b5c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:35:32 -0700 Subject: [PATCH 171/546] Updated alsabar (markdown) --- alsabar.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/alsabar.md b/alsabar.md index c9e3b49..9338ff8 100644 --- a/alsabar.md +++ b/alsabar.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows and controls alsa volume with a progressbar. Dependencies: From b7e11ca57eece06f8edc222bb0d928a6a16c1aeb Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:35:43 -0700 Subject: [PATCH 172/546] Updated alsa (markdown) --- alsa.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/alsa.md b/alsa.md index fb9b28f..4cfa8f3 100644 --- a/alsa.md +++ b/alsa.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows and controls alsa volume with a textbox. myvolume = lain.widgets.alsa() From 08511a5949b664ed52da6c936a3c332ef9b407c7 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 05:36:42 -0700 Subject: [PATCH 173/546] Updated Utilities (markdown) --- Utilities.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Utilities.md b/Utilities.md index c3bbf8b..45fd0fa 100644 --- a/Utilities.md +++ b/Utilities.md @@ -1,3 +1 @@ [<- home](https://github.com/copycat-killer/lain/wiki) - -[<- home](https://github.com/copycat-killer/lain/wiki) \ No newline at end of file From bbe3f997e64ee6fd9c61fffdd4a833cf728bf722 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 06:27:18 -0700 Subject: [PATCH 174/546] Updated Utilities (markdown) --- Utilities.md | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/Utilities.md b/Utilities.md index 45fd0fa..d9790da 100644 --- a/Utilities.md +++ b/Utilities.md @@ -1 +1,86 @@ [<- home](https://github.com/copycat-killer/lain/wiki) + +menu\_clients\_current\_tags +---------------------------- + +Similar to `awful.menu.clients()`, but this menu only shows the clients +of currently visible tags. Use it with a key binding like this: + + awful.key({ "Mod1" }, "Tab", function() + awful.menu.menu_keys.down = { "Down", "Alt_L", "Tab", "j" } + awful.menu.menu_keys.up = { "Up", "k" } + lain.util.menu_clients_current_tags({ width = 350 }, { keygrabber = true }) + end), + +magnify\_client +--------------- + +Set a client to floating and resize it in the same way the "magnifier" +layout does it. Place it on the "current" screen (derived from the mouse +position). This allows you to magnify any client you wish, regardless of +the currently used layout. Use it with a client keybinding like this: + + clientkeys = awful.util.table.join( + ... + awful.key({ modkey, "Control" }, "m", lain.util.magnify_client), + ... + ) + +If you want to "de-magnify" it, just reset the clients floating state to +`false` (hit `Mod4`+`CTRL`+`Space`, for example). + +niceborder\_{focus, unfocus} +---------------------------- + +By default, your `rc.lua` contains something like this: + + client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) + client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) + +You can change it to this: + + client.connect_signal("focus", lain.util.niceborder_focus(c)) + client.connect_signal("unfocus", lain.util.niceborder_unfocus(c)) + +Now, when a client is focused or unfocused, Awesome will look up its +nice value in `/proc//stat`. If it's less than 0, the client is +classified as "high priority"; if it's greater than 0, the client is +classified as "low priority". If it's equal to 0, nothing special +happens. + +This requires to define additional colors in your `theme.lua`. For example: + + theme.border_focus_highprio = "#FF0000" + theme.border_normal_highprio = "#A03333" + + theme.border_focus_lowprio = "#3333FF" + theme.border_normal_lowprio = "#333366" + +tag\_view\_nonempty +------------------- + +This function lets you jump to the next/previous non-empty tag. +It takes two arguments: + +* `direction`: `1` for next non-empty tag, `-1` for previous. +* `sc`: Screen which the taglist is in. Default is `mouse.screen` or `1`. This + argument is optional. + +You can use it with key bindings like these: + + -- Non-empty tag browsing + awful.key({ altkey }, "Left", function () lain.util.tag_view_nonempty(-1) end), + awful.key({ altkey }, "Right", function () lain.util.tag_view_nonempty(1) end), + +where `altkey = "Mod1"`. + +prompt\_rename\_tag +------------------- + +This function enables you to dynamically rename the current tag you have focused. + +You can use it with a key binding like this: + + awful.key({ modkey, "Shift" }, "r", function () lain.util.prompt_rename_tag(mypromptbox) end) + +Credits goes to [minism](https://bbs.archlinux.org/viewtopic.php?pid=1315135#p1315135). \ No newline at end of file From 63c18e957fc52e16cc47541a274a707c49399929 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 06:35:52 -0700 Subject: [PATCH 175/546] Updated Utilities (markdown) --- Utilities.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/Utilities.md b/Utilities.md index d9790da..4fc80e4 100644 --- a/Utilities.md +++ b/Utilities.md @@ -1,5 +1,45 @@ [<- home](https://github.com/copycat-killer/lain/wiki) +markup +------ + +This is a submodule which helps you markupping your text. + +First, call it like this: + + local markup = require("lain.util.markup") + +then you can call its functions: + + +-- markup + | + |`-- bold() Set bold. + |`-- italic() Set italicized text. + |`-- strike() Set strikethrough text. + |`-- underline() Set underlined text. + |`-- monospace() Set monospaced text. + |`-- big() Set bigger text. + |`-- small() Set smaller text. + |`-- font() Set the font of the text. + | + |`--+ bg + | | + | |`-- color() Set background color. + | |`-- focus() Set focus background color. + | |`-- normal() Set normal background color. + | `-- urgent() Set urgent background color. + | + |`--+ fg + | | + | |`-- color() Set foreground color. + | |`-- focus() Set focus foreground color. + | |`-- normal() Set normal foreground color. + | `-- urgent() Set urgent foreground color. + | + |`-- focus() Set both foreground and background focus colors. + |`-- normal() Set both foreground and background normal colors. + `-- urgent() Set both foreground and background urgent colors. + menu\_clients\_current\_tags ---------------------------- From 7024730f8ffe06bdc66294a85f362444b371f9b0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 06:42:07 -0700 Subject: [PATCH 176/546] Updated Utilities (markdown) --- Utilities.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Utilities.md b/Utilities.md index 4fc80e4..168d95f 100644 --- a/Utilities.md +++ b/Utilities.md @@ -5,7 +5,7 @@ markup This is a submodule which helps you markupping your text. -First, call it like this: +First, require it like this: local markup = require("lain.util.markup") @@ -40,6 +40,11 @@ then you can call its functions: |`-- normal() Set both foreground and background normal colors. `-- urgent() Set both foreground and background urgent colors. +they all take one argument, which is the text to markup, except `fg.color()` and `bg.color()`: + + markup.fg.color(text, color) + markup.bg.color(text, color) + menu\_clients\_current\_tags ---------------------------- From e0832541cf30fb31f7a9c45e1d1075b61b78ed21 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 06:42:31 -0700 Subject: [PATCH 177/546] Updated Utilities (markdown) --- Utilities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utilities.md b/Utilities.md index 168d95f..8bb7597 100644 --- a/Utilities.md +++ b/Utilities.md @@ -40,7 +40,7 @@ then you can call its functions: |`-- normal() Set both foreground and background normal colors. `-- urgent() Set both foreground and background urgent colors. -they all take one argument, which is the text to markup, except `fg.color()` and `bg.color()`: +they all take one argument, which is the text to markup, except `fg.color` and `bg.color`: markup.fg.color(text, color) markup.bg.color(text, color) From 82331e767e60643c9f634ffbae80588ad071ffd6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 06:43:33 -0700 Subject: [PATCH 178/546] Updated Home (markdown) --- Home.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Home.md b/Home.md index 5dfbd14..b98a1dd 100644 --- a/Home.md +++ b/Home.md @@ -1,3 +1,5 @@ +Welcome to the Lain wiki! + ### Installation Simply clone this repository into your Awesome directory. From ba12d39379e0400a746b918173af635aaf78c747 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 08:02:39 -0700 Subject: [PATCH 179/546] Created yawn (rest) --- yawn.rest | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 yawn.rest diff --git a/yawn.rest b/yawn.rest new file mode 100644 index 0000000..f8fc130 --- /dev/null +++ b/yawn.rest @@ -0,0 +1,133 @@ +========================================= +Yahoo's Awesome (WM) Weather Notification +========================================= + +---------------- +Lain integration +---------------- + +:Author: Luke Bonham +:License: WTFPLv2_ +:Version: 2.0-git + +Description +----------- + +Yawn is a module for Awesome WM providing brief and compact +weather notification via Naughty and Yahoo! Weather API. + +Originally a port of perceptive_, it became a completely new module after various improvements and style changes. + +----- +Usage +----- + +You can ``register`` Yawn to get a set of widgets, or ``attach`` it to +an existent widget. + +register +^^^^^^^^ + +Call: :: + + lain.widgets.yawn(id, args) + +Arguments: + +``id`` + An integer that defines the WOEID code of your city. + To obtain it you can google 'yahoo weather %CITYNAME%' and follow the first link. + It will look like:: + + http://weather.yahoo.com/united-states/california/san-diego-2487889/ + + and the last number in that link will be the ID you need. +``args`` + An optional table which can contain the following settings: + ``u`` + Units. Type: string. Possible values: "c" (Celsius), "f" (Fahrenheit). Default: "c". + + ``toshow`` + What to show. Type: string. Possible values: "units", "forecast", "both". + Default: "forecast". + + ``units_color`` + Color of units text. Type: string. Possible values: hexadecimal color + codes. + + ``forecast_color`` + Color of forecast text. Type: string. Possible values: hexadecimal color + codes. + + ``notification_color`` + Color of notification text. Type: string. Possible values: hexadecimal color + codes. + + ``spr`` + A separator. Type: string. You can define it when ``toshow`` is set to "both". + + ``footer`` + A footer. Type: string. You can define it when ``toshow`` is set to + "both". + +The function creates an imagebox icon and a textbox widget. Add them to you wibox like this: :: + + right_layout:add(lain.widgets.yawn.icon) + right_layout:add(lain.widgets.yawn.widget) + +Hovering over ``yawn.icon`` will display the notification. + +attach +^^^^^^ + +Call: :: + + lain.widgets.yawn.attach(widget, id, args) + +Arguments: + +``widget`` + The widget which you want to attach yawn to. +``id`` + same as in ``register`` +``args`` + same as in ``register`` + +Hovering over ``widget`` will display the notification. + +-------------- +Popup shortcut +-------------- + +You can also create a keybinding for the weather popup like this: :: + + globalkeys = awful.util.table.join( + ... + awful.key( { "Mod1" }, "w", function () lain.widgets.yawn.show(5) end ) + ... + +where ``show`` argument is an integer defining timeout seconds. + +------------ +Localization +------------ + +Default language is English, but Yawn can be localized. +Move to ``localizations`` subdirectory and fill ``localization_template``. + +Once you're done, rename it like your locale id. In my case: :: + + $ lua + Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio + > print(os.getenv("LANG"):match("(%S*$*)[.]")) + it_IT + > + +hence I named my file "it_IT" (Italian localization). + +**NOTE:** If you create a localization, feel free to send me! I will add it. + +.. _WTFPLv2: http://www.wtfpl.net +.. _perceptive: https://github.com/ioga/perceptive +.. _Tamsyn: http://www.fial.com/~scott/tamsyn-font/ +.. _Rainbow: https://github.com/copycat-killer/awesome-copycats> \ No newline at end of file From 76b4c1e48530c593ac892ecc250292f36665661f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 08:11:23 -0700 Subject: [PATCH 180/546] Updated yawn (rest) --- yawn.rest | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/yawn.rest b/yawn.rest index f8fc130..8991040 100644 --- a/yawn.rest +++ b/yawn.rest @@ -1,10 +1,4 @@ -========================================= -Yahoo's Awesome (WM) Weather Notification -========================================= - ----------------- -Lain integration ----------------- +*This is an integration of this* module_. :Author: Luke Bonham :License: WTFPLv2_ @@ -127,6 +121,7 @@ hence I named my file "it_IT" (Italian localization). **NOTE:** If you create a localization, feel free to send me! I will add it. +.. _module: https://github.com/copycat-killer/yawn .. _WTFPLv2: http://www.wtfpl.net .. _perceptive: https://github.com/ioga/perceptive .. _Tamsyn: http://www.fial.com/~scott/tamsyn-font/ From 7dd36dc2999c8c5990c885e1addf5316bc29e030 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 08:12:13 -0700 Subject: [PATCH 181/546] Updated yawn (rest) --- yawn.rest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yawn.rest b/yawn.rest index 8991040..4551597 100644 --- a/yawn.rest +++ b/yawn.rest @@ -1,4 +1,4 @@ -*This is an integration of this* module_. +(*Integration of this* module_) :Author: Luke Bonham :License: WTFPLv2_ From 89f9a0d9f6a1c2a05762bf1547b65ffdec005e09 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 08:12:59 -0700 Subject: [PATCH 182/546] Updated Widgets (markdown) --- Widgets.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index f6fde73..53c6f04 100644 --- a/Widgets.md +++ b/Widgets.md @@ -19,4 +19,5 @@ We say this because, for some widget, `function` return a table to be used for n - [mpd](https://github.com/copycat-killer/lain/wiki/mpd) - [net](https://github.com/copycat-killer/lain/wiki/net) - [sysload](https://github.com/copycat-killer/lain/wiki/sysload) -- [temp](https://github.com/copycat-killer/lain/wiki/temp) \ No newline at end of file +- [temp](https://github.com/copycat-killer/lain/wiki/temp) +- [yawn](https://github.com/copycat-killer/lain/wiki/yawn) \ No newline at end of file From 2b193e42dadcd928d0122c243b231b71e55b9784 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 11:32:52 -0700 Subject: [PATCH 183/546] Updated To start (markdown) --- To-start.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/To-start.md b/To-start.md index 36f32a0..a2be5ff 100644 --- a/To-start.md +++ b/To-start.md @@ -1,6 +1,4 @@ -[<- home](https://github.com/copycat-killer/lain/wiki) - -All you have to do is to include the module: +All you have to do to include the module: local lain = require("lain") From 1c728c3111383e5dad7bc7b5777ee0bc444e11a7 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 11:33:09 -0700 Subject: [PATCH 184/546] Updated Layouts (markdown) --- Layouts.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Layouts.md b/Layouts.md index f9dd490..7c4ff41 100644 --- a/Layouts.md +++ b/Layouts.md @@ -1,5 +1,3 @@ -[<- home](https://github.com/copycat-killer/lain/wiki) - Currently, there are **7** layouts. lain/layout From 8241f66587358c4fab30b2167892e53776cd87ad Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 11:33:31 -0700 Subject: [PATCH 185/546] Updated Widgets (markdown) --- Widgets.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Widgets.md b/Widgets.md index 53c6f04..cdcac1b 100644 --- a/Widgets.md +++ b/Widgets.md @@ -1,5 +1,3 @@ -[<- home](https://github.com/copycat-killer/lain/wiki) - Every widget is output by a `function`. Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. From 5bb1acd467582d5304a29527a849b3ee460b0cd6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 11:33:45 -0700 Subject: [PATCH 186/546] Updated Utilities (markdown) --- Utilities.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Utilities.md b/Utilities.md index 8bb7597..3cf188e 100644 --- a/Utilities.md +++ b/Utilities.md @@ -1,5 +1,3 @@ -[<- home](https://github.com/copycat-killer/lain/wiki) - markup ------ From a6bb0ef8d5c570023e1b9819d6b289db7f3e7155 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 11:35:11 -0700 Subject: [PATCH 187/546] Updated Utilities (markdown) --- Utilities.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Utilities.md b/Utilities.md index 3cf188e..cbf8c0f 100644 --- a/Utilities.md +++ b/Utilities.md @@ -49,7 +49,8 @@ menu\_clients\_current\_tags Similar to `awful.menu.clients()`, but this menu only shows the clients of currently visible tags. Use it with a key binding like this: - awful.key({ "Mod1" }, "Tab", function() + awful.key({ "Mod1" }, "Tab", + function() awful.menu.menu_keys.down = { "Down", "Alt_L", "Tab", "j" } awful.menu.menu_keys.up = { "Up", "k" } lain.util.menu_clients_current_tags({ width = 350 }, { keygrabber = true }) From 540a1af279deefcb17891801835c7d9d84e90b2a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 11:36:21 -0700 Subject: [PATCH 188/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index cdcac1b..6e6d361 100644 --- a/Widgets.md +++ b/Widgets.md @@ -8,7 +8,7 @@ We say this because, for some widget, `function` return a table to be used for n - [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) - [bat](https://github.com/copycat-killer/lain/wiki/bat) - [borderbox](https://github.com/copycat-killer/lain/wiki/borderbox) -- [calendar](https://github.com/copycat-killer/lain/wiki/caldendar) +- [calendar](https://github.com/copycat-killer/lain/wiki/calendar) - [cpu](https://github.com/copycat-killer/lain/wiki/cpu) - [fs](https://github.com/copycat-killer/lain/wiki/fs) - [imap](https://github.com/copycat-killer/lain/wiki/imap) From 7a6e392d098631a79d14eb1735e0b91829e33de3 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 16:20:57 -0700 Subject: [PATCH 189/546] Updated calendar (markdown) --- calendar.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/calendar.md b/calendar.md index 182c805..1d63a65 100644 --- a/calendar.md +++ b/calendar.md @@ -1,11 +1,11 @@ Attaches a calendar notification to a widget. - lain.widgets.calendar:attach(mywidget) + lain.widgets.calendar:attach(widget) - Left click: switch to previous month. - Right click: switch to next month. -Optionally you can call the function with background and foreground colors arguments, both or just one: +Optionally you can call the function with bg and fg colors arguments, both or just one: lain.widgets.calendar:attach(mytextclock, "#FFFFFF", "#000000") -- or @@ -13,6 +13,8 @@ Optionally you can call the function with background and foreground colors argum -- or lain.widgets.calendar:attach(mytextclock, nil, "#000000") +default bg and fg colors are `beautiful.bg_normal` and `beautiful.fg_focus`. + Notification will show an icon displaying current day, and formatted output from ``cal`` with current day highlighted. From 64f6fe9d609557f3386d7525b048a9410866abd3 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 16:35:54 -0700 Subject: [PATCH 190/546] Updated calendar (markdown) --- calendar.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/calendar.md b/calendar.md index 1d63a65..2b75840 100644 --- a/calendar.md +++ b/calendar.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Attaches a calendar notification to a widget. lain.widgets.calendar:attach(widget) From 0530fc4fd38e073263af06fbee7ccd2010eea238 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 7 Sep 2013 16:37:33 -0700 Subject: [PATCH 191/546] Updated mpd (markdown) --- mpd.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/mpd.md b/mpd.md index 27f3faf..33a0dd6 100644 --- a/mpd.md +++ b/mpd.md @@ -46,24 +46,24 @@ Finally, you can control the widget with key bindings like these: -- MPD control awful.key({ altkey, "Control" }, "Up", - function () - awful.util.spawn_with_shell( "mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle", false ) - mympd.notify() - end), + function () + awful.util.spawn_with_shell("mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle") + mpdwidget.notify() + end), awful.key({ altkey, "Control" }, "Down", - function () - awful.util.spawn_with_shell( "mpc stop || ncmpcpp stop || ncmpc stop || pms stop", false ) - mympd.notify() - end), + function () + awful.util.spawn_with_shell("mpc stop || ncmpcpp stop || ncmpc stop || pms stop") + mpdwidget.notify() + end), awful.key({ altkey, "Control" }, "Left", - function () - awful.util.spawn_with_shell( "mpc prev || ncmpcpp prev || ncmpc prev || pms prev", false ) - mympd.notify() - end), + function () + awful.util.spawn_with_shell("mpc prev || ncmpcpp prev || ncmpc prev || pms prev") + mpdwidget.notify() + end), awful.key({ altkey, "Control" }, "Right", - function () - awful.util.spawn_with_shell( "mpc next || ncmpcpp next || ncmpc next || pms next", false ) - mympd.notify() - end), + function () + awful.util.spawn_with_shell("mpc next || ncmpcpp next || ncmpc next || pms next") + mpdwidget.notify() + end), where `altkey = "Mod1"`. \ No newline at end of file From 279c5e9fe373a0b5b36cb3a1efa15cd46229c627 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 05:01:10 -0700 Subject: [PATCH 192/546] Updated Home (markdown) --- Home.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Home.md b/Home.md index b98a1dd..9342879 100644 --- a/Home.md +++ b/Home.md @@ -2,7 +2,9 @@ Welcome to the Lain wiki! ### Installation -Simply clone this repository into your Awesome directory. +Simply clone this repository into your Awesome directory: + + git clone https://github.com/copycat-killer/lain.git ~/.config/awesome/lain ### Index From ae528aac430fd36e138bdadde303d50b8cc89f07 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 05:15:50 -0700 Subject: [PATCH 193/546] Updated mpd (markdown) --- mpd.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mpd.md b/mpd.md index 33a0dd6..4b97f05 100644 --- a/mpd.md +++ b/mpd.md @@ -27,8 +27,8 @@ Variable | Meaning | Type | Default `port` | MPD port | string | "6600" `music_dir` | Music directory | string | "~/Music" `refresh_timeout` | Refresh timeout seconds | int | 1 -`color_artist` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" -`color_song` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" +`header_color` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" `spr` | Separator text between artist and song values | string | " " `app` | Music program to spawn on click | string | "ncmpcpp" `shadow` | Hide widget when there are no songs playing | boolean | false From b2982375bbb9e99e8830d8428523cfdeda573afc Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 05:20:21 -0700 Subject: [PATCH 194/546] Updated imap (markdown) --- imap.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/imap.md b/imap.md index d7e68b4..47e7b51 100644 --- a/imap.md +++ b/imap.md @@ -40,8 +40,7 @@ Variable | Meaning | Type | Default `refresh_timeout` | Refresh timeout seconds | int | 60 `header` | Text to show before value | string | " Mail " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color_newmail` | New mail value color | string | `beautiful.fg_focus` or "#FFFFFF" -`color_nomail` | No mail value color | string | `beautiful.fg_normal` or "#FFFFFF" +`color` | Mail value color | string | `beautiful.fg_focus` or "#FFFFFF" `mail_encoding` | Mail character encoding | string | autodetected `maxlen` | Maximum chars to display in notification | int | 200 `app` | Mail program to spawn on click | string | "mutt" From ed79b2f287993e547a91939be04075e601de4ada Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 06:14:11 -0700 Subject: [PATCH 195/546] Updated yawn (rest => markdown) --- yawn.md | 89 +++++++++++++++++++++++++++++++++++++ yawn.rest | 128 ------------------------------------------------------ 2 files changed, 89 insertions(+), 128 deletions(-) create mode 100644 yawn.md delete mode 100644 yawn.rest diff --git a/yawn.md b/yawn.md new file mode 100644 index 0000000..fa6e91c --- /dev/null +++ b/yawn.md @@ -0,0 +1,89 @@ +Yahoo's Awesome Weather notification +----------- + +Yawn provides brief and compact weather notification via Naughty and Yahoo! Weather API. + +Usage +----- + +You can ``register`` Yawn to get a set of widgets, or ``attach`` it to +an existent widget. + +### register + + yawn = lain.widgets.yawn(id, args) + +- ``id`` + + An integer that defines the WOEID code of your city. + To obtain it you can google 'yahoo weather %CITYNAME%' and follow the first link. + It will look like: + + http://weather.yahoo.com/united-states/california/san-diego-2487889/ + + and the last number in that link will be the ID you need. + +- ``args`` + + An optional table which can contain the following settings: + + Variables | Meaning | Type | Possible values | Default value + --- | --- | --- | --- | --- + `u` | Units | string | "c" (Celsius), "f" (Fahrenheit) | "c" + `toshow` | What to show | string | "forecast", "units", "both" | "forecast" + `color` | ``yawn.widget`` color | string | hexadecimal colors | + +The function creates an imagebox icon and a textbox widget. Add them to you wibox like this: + + right_layout:add(yawn.icon) + right_layout:add(yawn.widget) + +Hovering over ``yawn.icon`` will display the notification. + +### attach + + lain.widgets.yawn.attach(widget, id, args) + +Arguments: + +- ``widget`` + + The widget which you want to attach yawn to. + +- ``id`` + + Same as in ``register``. + +- ``args`` + + Same as in ``register``. + +Hovering over ``widget`` will display the notification. + +Popup shortcut +-------------- + +You can also create a keybinding for the weather popup like this: :: + + awful.key( { "Mod1" }, "w", function () yawn.show(5) end ) + +where ``show`` argument is an integer defining timeout seconds. + +Localization +------------ + +Default language is English, but Yawn can be localized. + +Move to `localizations` subdirectory and fill `localization_template`. + +Once you're done, rename it like your locale id. In my case: + + $ lua + Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio + > print(os.getenv("LANG"):match("(%S*$*)[.]")) + it_IT + > + +hence I named my file "it_IT" (Italian localization). + +**NOTE:** If you create a localization, feel free to send me! I will add it. \ No newline at end of file diff --git a/yawn.rest b/yawn.rest deleted file mode 100644 index 4551597..0000000 --- a/yawn.rest +++ /dev/null @@ -1,128 +0,0 @@ -(*Integration of this* module_) - -:Author: Luke Bonham -:License: WTFPLv2_ -:Version: 2.0-git - -Description ------------ - -Yawn is a module for Awesome WM providing brief and compact -weather notification via Naughty and Yahoo! Weather API. - -Originally a port of perceptive_, it became a completely new module after various improvements and style changes. - ------ -Usage ------ - -You can ``register`` Yawn to get a set of widgets, or ``attach`` it to -an existent widget. - -register -^^^^^^^^ - -Call: :: - - lain.widgets.yawn(id, args) - -Arguments: - -``id`` - An integer that defines the WOEID code of your city. - To obtain it you can google 'yahoo weather %CITYNAME%' and follow the first link. - It will look like:: - - http://weather.yahoo.com/united-states/california/san-diego-2487889/ - - and the last number in that link will be the ID you need. -``args`` - An optional table which can contain the following settings: - ``u`` - Units. Type: string. Possible values: "c" (Celsius), "f" (Fahrenheit). Default: "c". - - ``toshow`` - What to show. Type: string. Possible values: "units", "forecast", "both". - Default: "forecast". - - ``units_color`` - Color of units text. Type: string. Possible values: hexadecimal color - codes. - - ``forecast_color`` - Color of forecast text. Type: string. Possible values: hexadecimal color - codes. - - ``notification_color`` - Color of notification text. Type: string. Possible values: hexadecimal color - codes. - - ``spr`` - A separator. Type: string. You can define it when ``toshow`` is set to "both". - - ``footer`` - A footer. Type: string. You can define it when ``toshow`` is set to - "both". - -The function creates an imagebox icon and a textbox widget. Add them to you wibox like this: :: - - right_layout:add(lain.widgets.yawn.icon) - right_layout:add(lain.widgets.yawn.widget) - -Hovering over ``yawn.icon`` will display the notification. - -attach -^^^^^^ - -Call: :: - - lain.widgets.yawn.attach(widget, id, args) - -Arguments: - -``widget`` - The widget which you want to attach yawn to. -``id`` - same as in ``register`` -``args`` - same as in ``register`` - -Hovering over ``widget`` will display the notification. - --------------- -Popup shortcut --------------- - -You can also create a keybinding for the weather popup like this: :: - - globalkeys = awful.util.table.join( - ... - awful.key( { "Mod1" }, "w", function () lain.widgets.yawn.show(5) end ) - ... - -where ``show`` argument is an integer defining timeout seconds. - ------------- -Localization ------------- - -Default language is English, but Yawn can be localized. -Move to ``localizations`` subdirectory and fill ``localization_template``. - -Once you're done, rename it like your locale id. In my case: :: - - $ lua - Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio - > print(os.getenv("LANG"):match("(%S*$*)[.]")) - it_IT - > - -hence I named my file "it_IT" (Italian localization). - -**NOTE:** If you create a localization, feel free to send me! I will add it. - -.. _module: https://github.com/copycat-killer/yawn -.. _WTFPLv2: http://www.wtfpl.net -.. _perceptive: https://github.com/ioga/perceptive -.. _Tamsyn: http://www.fial.com/~scott/tamsyn-font/ -.. _Rainbow: https://github.com/copycat-killer/awesome-copycats> \ No newline at end of file From a905a653c051f6fac91673ecc0f0262279ecc541 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 06:15:08 -0700 Subject: [PATCH 196/546] Updated yawn (markdown) --- yawn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yawn.md b/yawn.md index fa6e91c..b58846c 100644 --- a/yawn.md +++ b/yawn.md @@ -48,7 +48,7 @@ Arguments: - ``widget`` - The widget which you want to attach yawn to. + The widget which you want to attach Yawn to. - ``id`` From b9df9d975094f7a13a59397de772e4eef8c739e5 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 06:19:10 -0700 Subject: [PATCH 197/546] Updated yawn (markdown) --- yawn.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/yawn.md b/yawn.md index b58846c..070bf2e 100644 --- a/yawn.md +++ b/yawn.md @@ -1,7 +1,6 @@ -Yahoo's Awesome Weather notification ------------ +(YAhoo! Weather Notification) -Yawn provides brief and compact weather notification via Naughty and Yahoo! Weather API. +Yawn provides brief and compact Yahoo! Weather notification. Usage ----- @@ -63,7 +62,7 @@ Hovering over ``widget`` will display the notification. Popup shortcut -------------- -You can also create a keybinding for the weather popup like this: :: +You can also create a keybinding for the weather popup like this: awful.key( { "Mod1" }, "w", function () yawn.show(5) end ) From f55accf8ad7585a3f070c77253a339fdb8c284e8 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:12:28 -0700 Subject: [PATCH 198/546] Updated calendar (markdown) --- calendar.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/calendar.md b/calendar.md index 2b75840..5b4587d 100644 --- a/calendar.md +++ b/calendar.md @@ -7,7 +7,7 @@ Attaches a calendar notification to a widget. - Left click: switch to previous month. - Right click: switch to next month. -Optionally you can call the function with bg and fg colors arguments, both or just one: +Optionally you can call the function with fg and bg colors arguments, both or just one: lain.widgets.calendar:attach(mytextclock, "#FFFFFF", "#000000") -- or @@ -15,7 +15,7 @@ Optionally you can call the function with bg and fg colors arguments, both or ju -- or lain.widgets.calendar:attach(mytextclock, nil, "#000000") -default bg and fg colors are `beautiful.bg_normal` and `beautiful.fg_focus`. +default fg and fb colors are `beautiful.fg_focus` and `beautiful.bg_normal`. Notification will show an icon displaying current day, and formatted output from ``cal`` with current day highlighted. From a58f0719f37380a53679223a15772ecc7387bd70 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:29:56 -0700 Subject: [PATCH 199/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index 9dcc894..7f7cd82 100644 --- a/cpu.md +++ b/cpu.md @@ -9,7 +9,7 @@ The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- `refresh_timeout` | Refresh timeout seconds | int | 10 -`header` | Text to show before value | string | " Cpu " +`header` | Text to show before value | string | "Cpu" `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `footer` | Text to add after value | string | "%" From 6d21ffc4f64a3a9ccf5c3537c7199476b94c5efc Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:30:21 -0700 Subject: [PATCH 200/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index 7f7cd82..8a3d5d8 100644 --- a/cpu.md +++ b/cpu.md @@ -9,7 +9,7 @@ The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- `refresh_timeout` | Refresh timeout seconds | int | 10 -`header` | Text to show before value | string | "Cpu" +`header` | Text to show before value | string | "Cpu " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `footer` | Text to add after value | string | "%" From 408a2c94dcf30e7d318947039e7f8cd97c68ed3a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:30:32 -0700 Subject: [PATCH 201/546] Updated bat (markdown) --- bat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bat.md b/bat.md index 79c17da..2d80786 100644 --- a/bat.md +++ b/bat.md @@ -14,7 +14,7 @@ Variable | Meaning | Type | Default `battery` | Identifier of the battery | string | "BAT0" `show_all` | Show all values (true), or only remaining capacity (false) | boolean | false `refresh_timeout` | Refresh timeout seconds | int | 30 -`header` | Text to show before value | string | " Bat " +`header` | Text to show before value | string | "Bat " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `shadow` | Hide the widget when battery is not present | boolean | false \ No newline at end of file From c8ecdd6bdad3a258e878d955f029d2ba59abaa1c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:31:22 -0700 Subject: [PATCH 202/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 4946fe7..ccb7386 100644 --- a/fs.md +++ b/fs.md @@ -12,7 +12,7 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `partition` | Partition to monitor | string | "/" `refresh_timeout` | Refresh timeout seconds | int | 600 -`header` | Text to show before value | string | " Hdd " +`header` | Text to show before value | string | "Hdd " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `footer` | Text to show after value | string | "%" From c62808245dfcc7afdf0b0f68f18983f42f1b5036 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:33:20 -0700 Subject: [PATCH 203/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 47e7b51..e30f688 100644 --- a/imap.md +++ b/imap.md @@ -38,7 +38,7 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `port` | IMAP port | int | 993 `refresh_timeout` | Refresh timeout seconds | int | 60 -`header` | Text to show before value | string | " Mail " +`header` | Text to show before value | string | "Mail " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Mail value color | string | `beautiful.fg_focus` or "#FFFFFF" `mail_encoding` | Mail character encoding | string | autodetected From ec030d2614b049846f5357db93b979034f31a199 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:34:36 -0700 Subject: [PATCH 204/546] Updated mem (markdown) --- mem.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mem.md b/mem.md index 173452d..69db14b 100644 --- a/mem.md +++ b/mem.md @@ -13,7 +13,7 @@ Variable | Meaning | Type | Default `refresh_timeout` | Refresh timeout seconds | int | 10 `show_swap` | Show amount of used swap space? | boolean | false `show_total` | Show amout of total memory? | boolean | false -`header` | Text to show before value | string | " Mem " +`header` | Text to show before value | string | "Mem " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `footer` | Text to show after value | string | "MB" From 104860fce749106596cdeb0bdf58dadb077a2587 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:51:36 -0700 Subject: [PATCH 205/546] Updated bat (markdown) --- bat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bat.md b/bat.md index 2d80786..79c17da 100644 --- a/bat.md +++ b/bat.md @@ -14,7 +14,7 @@ Variable | Meaning | Type | Default `battery` | Identifier of the battery | string | "BAT0" `show_all` | Show all values (true), or only remaining capacity (false) | boolean | false `refresh_timeout` | Refresh timeout seconds | int | 30 -`header` | Text to show before value | string | "Bat " +`header` | Text to show before value | string | " Bat " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `shadow` | Hide the widget when battery is not present | boolean | false \ No newline at end of file From 1c3be93cd700af8979c2f66bb68847f33be658c5 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:51:51 -0700 Subject: [PATCH 206/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index 8a3d5d8..9dcc894 100644 --- a/cpu.md +++ b/cpu.md @@ -9,7 +9,7 @@ The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- `refresh_timeout` | Refresh timeout seconds | int | 10 -`header` | Text to show before value | string | "Cpu " +`header` | Text to show before value | string | " Cpu " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `footer` | Text to add after value | string | "%" From 0c6ccd64afd011ccffaf55140e6d73b708fa2852 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:52:01 -0700 Subject: [PATCH 207/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index 9dcc894..1dce16e 100644 --- a/cpu.md +++ b/cpu.md @@ -12,6 +12,6 @@ Variable | Meaning | Type | Default `header` | Text to show before value | string | " Cpu " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to add after value | string | "%" +`footer` | Text to add after value | string | "% " **Note**: `footer` color is `color`. \ No newline at end of file From e2143ade926da4ebced2958237b27d86b2e879e2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:52:39 -0700 Subject: [PATCH 208/546] Updated fs (markdown) --- fs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs.md b/fs.md index ccb7386..eb67110 100644 --- a/fs.md +++ b/fs.md @@ -12,10 +12,10 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `partition` | Partition to monitor | string | "/" `refresh_timeout` | Refresh timeout seconds | int | 600 -`header` | Text to show before value | string | "Hdd " +`header` | Text to show before value | string | " Hdd " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to show after value | string | "%" +`footer` | Text to show after value | string | " " `shadow` | Hide the widget if `partition` < 90 | boolean | false **Note**: `footer` color is `color`. From 5b7caa37c973b9b2ef8be966bd861b00efbbee9b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:54:06 -0700 Subject: [PATCH 209/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index e30f688..47e7b51 100644 --- a/imap.md +++ b/imap.md @@ -38,7 +38,7 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `port` | IMAP port | int | 993 `refresh_timeout` | Refresh timeout seconds | int | 60 -`header` | Text to show before value | string | "Mail " +`header` | Text to show before value | string | " Mail " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Mail value color | string | `beautiful.fg_focus` or "#FFFFFF" `mail_encoding` | Mail character encoding | string | autodetected From c3ea2190169f32786eff48ec334d08bfd6798459 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 09:55:18 -0700 Subject: [PATCH 210/546] Updated mem (markdown) --- mem.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mem.md b/mem.md index 69db14b..68c6748 100644 --- a/mem.md +++ b/mem.md @@ -13,9 +13,9 @@ Variable | Meaning | Type | Default `refresh_timeout` | Refresh timeout seconds | int | 10 `show_swap` | Show amount of used swap space? | boolean | false `show_total` | Show amout of total memory? | boolean | false -`header` | Text to show before value | string | "Mem " +`header` | Text to show before value | string | " Mem " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to show after value | string | "MB" +`footer` | Text to show after value | string | "MB " **Note**: `footer` color is `color`. \ No newline at end of file From 2b497c0ed879ebcae09b4d1057e92400632aab2f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 10:20:49 -0700 Subject: [PATCH 211/546] Updated mpd (markdown) --- mpd.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index 4b97f05..4a3398a 100644 --- a/mpd.md +++ b/mpd.md @@ -29,11 +29,12 @@ Variable | Meaning | Type | Default `refresh_timeout` | Refresh timeout seconds | int | 1 `header_color` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to append to values | string | "" `spr` | Separator text between artist and song values | string | " " `app` | Music program to spawn on click | string | "ncmpcpp" `shadow` | Hide widget when there are no songs playing | boolean | false -**Note**: `spr` can be a markup text. +**Note**: `footer` and `spr` can be markup text. `lain.widgets.mpd` outputs the following table: From edaee615614c7e98712bbac34d5f84b32365c27b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 10:21:51 -0700 Subject: [PATCH 212/546] Updated mpd (markdown) --- mpd.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mpd.md b/mpd.md index 4a3398a..1d35f02 100644 --- a/mpd.md +++ b/mpd.md @@ -29,12 +29,12 @@ Variable | Meaning | Type | Default `refresh_timeout` | Refresh timeout seconds | int | 1 `header_color` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to append to values | string | "" `spr` | Separator text between artist and song values | string | " " +`footer` | Text to append after values | string | "" `app` | Music program to spawn on click | string | "ncmpcpp" `shadow` | Hide widget when there are no songs playing | boolean | false -**Note**: `footer` and `spr` can be markup text. +**Note**: `spr` and `footer` can be markup text. `lain.widgets.mpd` outputs the following table: From a36db9a16e166f573f2582c74c1ae56786b560a3 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 16:42:15 -0700 Subject: [PATCH 213/546] Updated net (markdown) --- net.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net.md b/net.md index b02c239..82772d7 100644 --- a/net.md +++ b/net.md @@ -14,11 +14,12 @@ Variable | Meaning | Type | Default `spr` | Separator text between download and upload values | string | " " `header` | Text to show before value | string | `iface` `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" +`footer` | Text to append after value | string | "" `color_up` | Upload value color | string | `beautiful.fg_focus` or "#FFFFFF" `color_down` | Download value color | string | `beautiful.fg_focus` or "#FFFFFF" `app` | Net program to spawn on click | string | "sudo wifi-menu" -**Note**: `spr` can be a markup text. +**Note**: `spr` and `footer` can be a markup text. Possible value for `units` are stored in table `lain.widgets.net.units`, which contains: From 31825bb01cf100e848cc83c0bb8d8a92551a6caf Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 16:51:10 -0700 Subject: [PATCH 214/546] Updated alsabar (markdown) --- alsabar.md | 1 + 1 file changed, 1 insertion(+) diff --git a/alsabar.md b/alsabar.md index 9338ff8..9b5a711 100644 --- a/alsabar.md +++ b/alsabar.md @@ -42,6 +42,7 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `font` | Notifications font | string | The one defined in `beautiful.font` `font_size` | Notifications font size | string | "11" +`color` | Notifications color | string | `beautiful.fg_focus` `bar_size` | Wibox height | int | 18 It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height, From c518eb3e858b96b75c7d5f7b983676da6c771328 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 8 Sep 2013 17:09:36 -0700 Subject: [PATCH 215/546] Updated mpd (markdown) --- mpd.md | 1 + 1 file changed, 1 insertion(+) diff --git a/mpd.md b/mpd.md index 1d35f02..7640b4c 100644 --- a/mpd.md +++ b/mpd.md @@ -27,6 +27,7 @@ Variable | Meaning | Type | Default `port` | MPD port | string | "6600" `music_dir` | Music directory | string | "~/Music" `refresh_timeout` | Refresh timeout seconds | int | 1 +`pre` | Text before values | string | "" `header_color` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" `spr` | Separator text between artist and song values | string | " " From fa18bd379af6644d64bb73f4fb90f4d9d1b0c879 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 04:52:53 -0700 Subject: [PATCH 216/546] Updated alsa (markdown) --- alsa.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index 4cfa8f3..337f7e8 100644 --- a/alsa.md +++ b/alsa.md @@ -17,8 +17,11 @@ Variable | Meaning | Type | Default `header` | Text to show before value | string | " Vol " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to append after value | string | "" -and outputs the following table: +*Note*: `footer` can be markup text. + +`lain.widgets.alsa` outputs the following table: Variable | Meaning | Type --- | --- | --- From 69d8188289256603f1b856805aeb9ba882cc9dd0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 04:53:58 -0700 Subject: [PATCH 217/546] Updated alsa (markdown) --- alsa.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index 337f7e8..2ca1746 100644 --- a/alsa.md +++ b/alsa.md @@ -17,7 +17,7 @@ Variable | Meaning | Type | Default `header` | Text to show before value | string | " Vol " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to append after value | string | "" +`footer` | Text to append after value | string | " " *Note*: `footer` can be markup text. From 8a5a77acdca8bd699c6883eb74d5651e0cd49fcb Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 04:58:26 -0700 Subject: [PATCH 218/546] Updated bat (markdown) --- bat.md | 1 + 1 file changed, 1 insertion(+) diff --git a/bat.md b/bat.md index 79c17da..5d89b14 100644 --- a/bat.md +++ b/bat.md @@ -17,4 +17,5 @@ Variable | Meaning | Type | Default `header` | Text to show before value | string | " Bat " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to append after value | string | " " `shadow` | Hide the widget when battery is not present | boolean | false \ No newline at end of file From de95c3d52940e403f875fd4298783bd34b1f48e2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 04:59:05 -0700 Subject: [PATCH 219/546] Updated bat (markdown) --- bat.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bat.md b/bat.md index 5d89b14..8b24151 100644 --- a/bat.md +++ b/bat.md @@ -18,4 +18,6 @@ Variable | Meaning | Type | Default `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" `footer` | Text to append after value | string | " " -`shadow` | Hide the widget when battery is not present | boolean | false \ No newline at end of file +`shadow` | Hide the widget when battery is not present | boolean | false + +**Note**: `footer` can be markup text. \ No newline at end of file From c7f1311f61c80b97a3bf397d5391094ea0d6eb65 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 05:00:23 -0700 Subject: [PATCH 220/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index eb67110..7ee1f5c 100644 --- a/fs.md +++ b/fs.md @@ -18,7 +18,7 @@ Variable | Meaning | Type | Default `footer` | Text to show after value | string | " " `shadow` | Hide the widget if `partition` < 90 | boolean | false -**Note**: `footer` color is `color`. +**Note**: `footer` can be markup text. `lain.widgets.fs` outputs the following table: From 74827d8a0e17c88acc89c9db35f76e63fa38fd8c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 05:01:17 -0700 Subject: [PATCH 221/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 7ee1f5c..eb67110 100644 --- a/fs.md +++ b/fs.md @@ -18,7 +18,7 @@ Variable | Meaning | Type | Default `footer` | Text to show after value | string | " " `shadow` | Hide the widget if `partition` < 90 | boolean | false -**Note**: `footer` can be markup text. +**Note**: `footer` color is `color`. `lain.widgets.fs` outputs the following table: From 6e896b59ce3a8e8247d627486cba37ef2e54b238 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 05:03:26 -0700 Subject: [PATCH 222/546] Updated imap (markdown) --- imap.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/imap.md b/imap.md index 47e7b51..97cd437 100644 --- a/imap.md +++ b/imap.md @@ -41,12 +41,15 @@ Variable | Meaning | Type | Default `header` | Text to show before value | string | " Mail " `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color` | Mail value color | string | `beautiful.fg_focus` or "#FFFFFF" +`footer` | Text to append after value | string | " " `mail_encoding` | Mail character encoding | string | autodetected `maxlen` | Maximum chars to display in notification | int | 200 `app` | Mail program to spawn on click | string | "mutt" `shadow` | Hide widget when there are no mails | boolean | false `is_plain` | Define whether `password` is a plain password (true) or a function that retrieves it (false) | boolean | false +**Note**: `footer` can be markup text. + Let's focus better on `is_plain`. You can just set your password like this: From 9f3f9d4a414f05d66246ffeb526f57aa50540035 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 05:06:06 -0700 Subject: [PATCH 223/546] Updated maildir (markdown) --- maildir.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/maildir.md b/maildir.md index c35b2f9..bd81c02 100644 --- a/maildir.md +++ b/maildir.md @@ -33,5 +33,8 @@ Variable | Meaning | Type | Default `header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" `color_newmail` | New mail value color | string | `beautiful.fg_focus` or "#FFFFFF" `color_nomail` | No mail value color | string | `beautiful.fg_normal` or "#FFFFFF" +`footer` | Text to append after value | string | " " `app` | Mail program to spawn on click | string | "mutt"| boolean | false -`shadow` | Hide widget when there are no mails | boolean | false \ No newline at end of file +`shadow` | Hide widget when there are no mails | boolean | false + +**Note**: `footer` can be markup text. \ No newline at end of file From a5b848ed5a5c0a3af976dcad3e02e0fb21818afa Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 05:06:43 -0700 Subject: [PATCH 224/546] Updated maildir (markdown) --- maildir.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/maildir.md b/maildir.md index bd81c02..a30e59f 100644 --- a/maildir.md +++ b/maildir.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + Shows maildirs status in a textbox. Maildirs are structured as follows: From 96452a41fbf23d14b6001dcc11b9e71d78ab60a2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 05:14:40 -0700 Subject: [PATCH 225/546] Updated mpd (markdown) --- mpd.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mpd.md b/mpd.md index 7640b4c..2a0ba32 100644 --- a/mpd.md +++ b/mpd.md @@ -27,9 +27,9 @@ Variable | Meaning | Type | Default `port` | MPD port | string | "6600" `music_dir` | Music directory | string | "~/Music" `refresh_timeout` | Refresh timeout seconds | int | 1 -`pre` | Text before values | string | "" -`header_color` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" +`header` | Text before values | string | "" +`artist_color` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" +`song_color` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" `spr` | Separator text between artist and song values | string | " " `footer` | Text to append after values | string | "" `app` | Music program to spawn on click | string | "ncmpcpp" From 81992cd18c41bb461a83531a967d83d030595e50 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 9 Sep 2013 14:54:04 -0700 Subject: [PATCH 226/546] Updated Home (markdown) --- Home.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Home.md b/Home.md index 9342879..6c93aae 100644 --- a/Home.md +++ b/Home.md @@ -1,5 +1,14 @@ Welcome to the Lain wiki! +### Dependencies + +Package | Requested by +--- | --- +alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) +curl | widget types accessing network resources +imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) +python3 | [imap](https://github.com/copycat-killer/lain/wiki/imap) + ### Installation Simply clone this repository into your Awesome directory: From 50d1f754c16fe9981decf0aaa113a6eaf681e3e4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 12:24:16 -0700 Subject: [PATCH 227/546] Destroyed To start (markdown) --- To-start.md | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 To-start.md diff --git a/To-start.md b/To-start.md deleted file mode 100644 index a2be5ff..0000000 --- a/To-start.md +++ /dev/null @@ -1,26 +0,0 @@ -All you have to do to include the module: - - local lain = require("lain") - -Some widgets require a terminal, lain default is `xterm`, but can be changed: - - lain.widgets.terminal = "urxvtc" - -or - - lain.widgets.terminal = terminal - -providing you have something like this: - - terminal = "urxvtc" - -in your `rc.lua`. - -`terminal` may also be a lua function that accepts one parameter. -Something like this: - - function footerm(cmd) - -- elaborate cmd - end - - lain.widgets.terminal = footerm From e7ebea22be7a5a22323da4886302bdb95349d26e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 12:25:53 -0700 Subject: [PATCH 228/546] Updated Home (markdown) --- Home.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Home.md b/Home.md index 6c93aae..74f336f 100644 --- a/Home.md +++ b/Home.md @@ -15,9 +15,12 @@ Simply clone this repository into your Awesome directory: git clone https://github.com/copycat-killer/lain.git ~/.config/awesome/lain -### Index +then include it in your `rc.lua`: + + local lain = require("lain") + +### Submodules -- [To start](https://github.com/copycat-killer/lain/wiki/To-start) - [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts) - [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - [Utilities](https://github.com/copycat-killer/lain/wiki/Utilities) \ No newline at end of file From 97c1e547db8e54aeac70de2d2e8a65d73654ade8 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 12:31:48 -0700 Subject: [PATCH 229/546] Updated Widgets (markdown) --- Widgets.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Widgets.md b/Widgets.md index 6e6d361..86c1f46 100644 --- a/Widgets.md +++ b/Widgets.md @@ -4,6 +4,8 @@ Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. We say this because, for some widget, `function` return a table to be used for notification and update purposes. +Almost all widgets can be set by an input function called `settings`: you can markup textboxes and do other customizations within it. + - [alsa](https://github.com/copycat-killer/lain/wiki/alsa) - [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) - [bat](https://github.com/copycat-killer/lain/wiki/bat) From d614f25b59239cf3688d9d5ef02424a2e289971b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 12:32:17 -0700 Subject: [PATCH 230/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index 86c1f46..8accde9 100644 --- a/Widgets.md +++ b/Widgets.md @@ -4,7 +4,7 @@ Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. We say this because, for some widget, `function` return a table to be used for notification and update purposes. -Almost all widgets can be set by an input function called `settings`: you can markup textboxes and do other customizations within it. +Almost all widgets can be set by an input function called `settings`: you can markup textboxes and do whatever customization within it. - [alsa](https://github.com/copycat-killer/lain/wiki/alsa) - [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) From ff64bfead928d0c5027162c7810912a50c756f5a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 12:32:50 -0700 Subject: [PATCH 231/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index 8accde9..0772360 100644 --- a/Widgets.md +++ b/Widgets.md @@ -2,7 +2,7 @@ Every widget is output by a `function`. Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. -We say this because, for some widget, `function` return a table to be used for notification and update purposes. +We say this because, for some widget, `function` returns a table to be used for notification and update purposes. Almost all widgets can be set by an input function called `settings`: you can markup textboxes and do whatever customization within it. From aba6c37b9c0517f6f39d4db4a54862b800cc70a8 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 12:56:10 -0700 Subject: [PATCH 232/546] Updated Widgets (markdown) --- Widgets.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Widgets.md b/Widgets.md index 0772360..2138b27 100644 --- a/Widgets.md +++ b/Widgets.md @@ -2,9 +2,22 @@ Every widget is output by a `function`. Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. -We say this because, for some widget, `function` returns a table to be used for notification and update purposes. +This is said because, for some widgets, `function` returns a table to be used for notification and update purposes. -Almost all widgets can be set by an input function called `settings`: you can markup textboxes and do whatever customization within it. +Every widget may take either a table or a list of variables as argument. + +If it takes a table, you have to define a function variable called `settings` in it: with this you can markup textboxes using predefined variables and do whatever customization you want. + +I'll give an example: + + mycpu = lain.widgets.cpu({ + timeout = 4, + settings = function() + widgets:set_markup("Cpu " .. usage) + end + }) + +check the sections for all the details. - [alsa](https://github.com/copycat-killer/lain/wiki/alsa) - [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) From c90ee42b5d0e01775e8c4d46f62dc4e7cf9ce9d2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 12:58:14 -0700 Subject: [PATCH 233/546] Updated Widgets (markdown) --- Widgets.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Widgets.md b/Widgets.md index 2138b27..42021bd 100644 --- a/Widgets.md +++ b/Widgets.md @@ -8,7 +8,7 @@ Every widget may take either a table or a list of variables as argument. If it takes a table, you have to define a function variable called `settings` in it: with this you can markup textboxes using predefined variables and do whatever customization you want. -I'll give an example: +I'll give an example just to take a grasp, see the sections for all the details: mycpu = lain.widgets.cpu({ timeout = 4, @@ -17,8 +17,6 @@ I'll give an example: end }) -check the sections for all the details. - - [alsa](https://github.com/copycat-killer/lain/wiki/alsa) - [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) - [bat](https://github.com/copycat-killer/lain/wiki/bat) From ff3a614d7b45905e0cf969936cb8547ef1f90033 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:00:23 -0700 Subject: [PATCH 234/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index 42021bd..a798c67 100644 --- a/Widgets.md +++ b/Widgets.md @@ -8,7 +8,7 @@ Every widget may take either a table or a list of variables as argument. If it takes a table, you have to define a function variable called `settings` in it: with this you can markup textboxes using predefined variables and do whatever customization you want. -I'll give an example just to take a grasp, see the sections for all the details: +Here follows a simple example, see the sections for all the details: mycpu = lain.widgets.cpu({ timeout = 4, From eabc5b4991db5cb4dc85551a5814a10f633f72b1 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:01:39 -0700 Subject: [PATCH 235/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index a798c67..c0a7dd6 100644 --- a/Widgets.md +++ b/Widgets.md @@ -13,7 +13,7 @@ Here follows a simple example, see the sections for all the details: mycpu = lain.widgets.cpu({ timeout = 4, settings = function() - widgets:set_markup("Cpu " .. usage) + widget:set_markup("Cpu " .. usage) end }) From 2098a3ef16f6f435509adde00fc7a37794a140d2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:19:34 -0700 Subject: [PATCH 236/546] Updated Widgets (markdown) --- Widgets.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Widgets.md b/Widgets.md index c0a7dd6..7130cc3 100644 --- a/Widgets.md +++ b/Widgets.md @@ -6,9 +6,15 @@ This is said because, for some widgets, `function` returns a table to be used fo Every widget may take either a table or a list of variables as argument. -If it takes a table, you have to define a function variable called `settings` in it: with this you can markup textboxes using predefined variables and do whatever customization you want. +If it takes a table, you have to define a function variable called `settings` in it, in order to make your customizations. -Here follows a simple example, see the sections for all the details: +To markup the textbox, call `widget:set_markup(...)` within `settings`. + +You can feed `set_markup` with predefined arguments, see the sections for all the details. + +`widget` is a textbox, so you can also threat it like any other `wibox.widget.textbox`. + +Here follows an example: mycpu = lain.widgets.cpu({ timeout = 4, @@ -17,6 +23,8 @@ Here follows a simple example, see the sections for all the details: end }) +--- + - [alsa](https://github.com/copycat-killer/lain/wiki/alsa) - [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) - [bat](https://github.com/copycat-killer/lain/wiki/bat) From cc7173f060ca66885794b4584c8bcb0fa2a0dc38 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:25:23 -0700 Subject: [PATCH 237/546] Updated alsa (markdown) --- alsa.md | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/alsa.md b/alsa.md index 2ca1746..3e31c74 100644 --- a/alsa.md +++ b/alsa.md @@ -4,43 +4,39 @@ Shows and controls alsa volume with a textbox. myvolume = lain.widgets.alsa() -* Left click: Launch `alsamixer` in your `terminal`. -* Right click: Mute/unmute. -* Scroll wheel: Increase/decrase volume. - -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 5 `channel` | Mixer channel | string | "Master" -`step` | Step at which volume is increased/decreased | string | "1%" -`header` | Text to show before value | string | " Vol " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to append after value | string | " " +`settings` | User settings | function | empty function -*Note*: `footer` can be markup text. +`settings` can be fed with the following variables: -`lain.widgets.alsa` outputs the following table: +Variable | Meaning | Type | Values +--- | --- | --- | --- +volume.level | Self explained | int | 0-100 +volume.status | Device status | string | "on", "off" + +### output table Variable | Meaning | Type --- | --- | --- `widget` | The widget | `wibox.widget.textbox` -`channel` | Alsa channel | string -`step` | Increase/decrease step | string -`notify` | Update `widget` | function +`notify` | Force update `widget` | function Finally, you can control the widget with key bindings like these: -- Volume control awful.key({ altkey }, "Up", function () - awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "+") + awful.util.spawn("amixer sset Master 1%+") volume.notify() end), awful.key({ altkey }, "Down", function () - awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "-") + awful.util.spawn("amixer sset Master 1%-") volume.notify() end), awful.key({ altkey }, "m", From a3832b86deffa231776cf843262e6f90bb2eaa45 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:28:54 -0700 Subject: [PATCH 238/546] Updated alsabar (markdown) --- alsabar.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/alsabar.md b/alsabar.md index 9b5a711..549b28a 100644 --- a/alsabar.md +++ b/alsabar.md @@ -1,12 +1,6 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -Shows and controls alsa volume with a progressbar. - -Dependencies: - -- alsa-utils (of course) - -Plus tooltips, notifications, and color changes at mute/unmute switch. +Shows and controls alsa volume with a progressbar and provides tooltips, notifications, and color changes at mute/unmute switch. myvolumebar = lain.widgets.alsabar() @@ -48,7 +42,7 @@ Variable | Meaning | Type | Default It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height, **if** you have set it different than default (18). -`lain.widgets.alsabar` outputs the following table: +### output table Variable | Meaning | Type --- | --- | --- @@ -57,7 +51,7 @@ Variable | Meaning | Type `step` | Increase/decrease step | string `notify` | The notification | function -Finally, you can control the widget with key bindings like these: +You can control the widget with key bindings like these: -- Volume control awful.key({ altkey }, "Up", From 19aa8f682799b01a225e55701b60ab42e7a72e7d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:29:07 -0700 Subject: [PATCH 239/546] Updated alsa (markdown) --- alsa.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index 3e31c74..2029e8c 100644 --- a/alsa.md +++ b/alsa.md @@ -26,7 +26,7 @@ Variable | Meaning | Type `widget` | The widget | `wibox.widget.textbox` `notify` | Force update `widget` | function -Finally, you can control the widget with key bindings like these: +You can control the widget with key bindings like these: -- Volume control awful.key({ altkey }, "Up", From e95e05e2d3fdd1e192dba22b79e968247ed6d20f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:31:03 -0700 Subject: [PATCH 240/546] Updated alsa (markdown) --- alsa.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index 2029e8c..7ad0a6e 100644 --- a/alsa.md +++ b/alsa.md @@ -2,7 +2,7 @@ Shows and controls alsa volume with a textbox. - myvolume = lain.widgets.alsa() + volume = lain.widgets.alsa() ### input table From 87af954c99c654d8f405819ef9e1b1ea6a563eea Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:32:32 -0700 Subject: [PATCH 241/546] Updated bat (markdown) --- bat.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/bat.md b/bat.md index 8b24151..1f8bf1f 100644 --- a/bat.md +++ b/bat.md @@ -7,17 +7,14 @@ Displays a notification when battery is low or critical. mybattery = lain.widgets.bat() -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 30 `battery` | Identifier of the battery | string | "BAT0" -`show_all` | Show all values (true), or only remaining capacity (false) | boolean | false -`refresh_timeout` | Refresh timeout seconds | int | 30 -`header` | Text to show before value | string | " Bat " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to append after value | string | " " -`shadow` | Hide the widget when battery is not present | boolean | false +`settings` | User settings | function | empty function -**Note**: `footer` can be markup text. \ No newline at end of file +### output + +A textbox. \ No newline at end of file From 558efea651bcf07c4f63b4ff69954bed6545f827 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:40:31 -0700 Subject: [PATCH 242/546] Updated calendar (markdown) --- calendar.md | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/calendar.md b/calendar.md index 5b4587d..fa4e563 100644 --- a/calendar.md +++ b/calendar.md @@ -2,37 +2,27 @@ Attaches a calendar notification to a widget. - lain.widgets.calendar:attach(widget) + lain.widgets.calendar:attach(widget, args) - Left click: switch to previous month. - Right click: switch to next month. -Optionally you can call the function with fg and bg colors arguments, both or just one: +`args` is an optional table which can contain: - lain.widgets.calendar:attach(mytextclock, "#FFFFFF", "#000000") - -- or - lain.widgets.calendar:attach(mytextclock, "#FFFFFF") - -- or - lain.widgets.calendar:attach(mytextclock, nil, "#000000") +Variable | Meaning | Type | Default +--- | --- | --- | --- +`icons` | Path to calendar icons | string | [lain/icons/cal/white](https://github.com/copycat-killer/lain/tree/master/icons/cal/white) +`font_size` | Calendar font size | int | 12 +`fg` | Calendar foreground color | string | `beautiful.fg_normal` +`bg` | Calendar background color | string | `beautiful.bg_normal` +`position` | Calendar position | string | "top_right" -default fg and fb colors are `beautiful.fg_focus` and `beautiful.bg_normal`. +`position` possible values are defined [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify). Notification will show an icon displaying current day, and formatted output from ``cal`` with current day highlighted. -Calendar icons are placed in [lain/icons/cal](https://github.com/copycat-killer/lain/tree/master/icons/cal), default set being ``white``. - -You can add your own set, and tell lain to use it like this: - - lain.widgets.calendar.icons_dir = lain.widgets.icons_dir .. "cal/myicons" - -also, you can set notification font size: - - lain.widgets.calendar.font_size = 14 - -default is 12. - -Finally, you can call the notification with a key binding like this: +You can call the notification with a key binding like this: awful.key({ altkey }, "c", function () lain.widgets.calendar:show(7) end), From a05ff1d75aa5ebaaaa95f300067fc79bc97fcc06 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:42:18 -0700 Subject: [PATCH 243/546] Updated cpu (markdown) --- cpu.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cpu.md b/cpu.md index 1dce16e..3c49f64 100644 --- a/cpu.md +++ b/cpu.md @@ -4,14 +4,13 @@ Shows in a textbox the average CPU usage percent for a given amount of time. mycpuusage = lain.widgets.cpu() -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- -`refresh_timeout` | Refresh timeout seconds | int | 10 -`header` | Text to show before value | string | " Cpu " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to add after value | string | "% " +`timeout` | Refresh timeout seconds | int | 10 +`settings` | User settings | function | empty function -**Note**: `footer` color is `color`. \ No newline at end of file +### output + +A textbox. \ No newline at end of file From 1e932a7f5f026890704fcb0940fb8c78add4f4de Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:43:13 -0700 Subject: [PATCH 244/546] Updated cpu (markdown) --- cpu.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpu.md b/cpu.md index 3c49f64..5cafceb 100644 --- a/cpu.md +++ b/cpu.md @@ -11,6 +11,8 @@ Variable | Meaning | Type | Default `timeout` | Refresh timeout seconds | int | 10 `settings` | User settings | function | empty function +`settings` can be fed with `usage`, which is the cpu use percentage. + ### output A textbox. \ No newline at end of file From 818546e18b162f8de6c788a665cd340ca36cce76 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:46:24 -0700 Subject: [PATCH 245/546] Updated bat (markdown) --- bat.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bat.md b/bat.md index 1f8bf1f..04c80dd 100644 --- a/bat.md +++ b/bat.md @@ -15,6 +15,8 @@ Variable | Meaning | Type | Default `battery` | Identifier of the battery | string | "BAT0" `settings` | User settings | function | empty function +`settings` can be fed with `bat_now` table, which contains the following strings: `status`, `perc`, `time`, `watt`. + ### output A textbox. \ No newline at end of file From 4372151c87afb56435aad2fb800139d3658ca4b6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 13:47:26 -0700 Subject: [PATCH 246/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index 5cafceb..4994e1d 100644 --- a/cpu.md +++ b/cpu.md @@ -11,7 +11,7 @@ Variable | Meaning | Type | Default `timeout` | Refresh timeout seconds | int | 10 `settings` | User settings | function | empty function -`settings` can be fed with `usage`, which is the cpu use percentage. +`settings` can be fed with the string `usage`, which means the cpu use percentage. ### output From e44940ce34d3e5feae6f01c9a2f3ac8beef3342d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:00:43 -0700 Subject: [PATCH 247/546] Updated fs (markdown) --- fs.md | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/fs.md b/fs.md index eb67110..f1aa353 100644 --- a/fs.md +++ b/fs.md @@ -6,21 +6,30 @@ Displays a notification when the partition is full or has low space. mypartition = lain.widgets.fs() -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- +`timeout` | Refresh timeout seconds -| int | 600 `partition` | Partition to monitor | string | "/" -`refresh_timeout` | Refresh timeout seconds | int | 600 -`header` | Text to show before value | string | " Hdd " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to show after value | string | " " -`shadow` | Hide the widget if `partition` < 90 | boolean | false +`settings` | User settings | function | empty function -**Note**: `footer` color is `color`. +`settings` can use the following `partition` related value strings: `used`, `available`, `size_mb`, `size_gb`. -`lain.widgets.fs` outputs the following table: +It can also use value strings in these formats: + + fs_info[p .. "used_p"] + fs_info[p .. "avail_p"] + fs_info[p .. "size_mb"] + fs_info[p .. "size_gb"] + +where `p` is the "mount" column of the output of `df` command (`/`, `/home`, `/boot`, ...). + +This means you can set the widget for a certain partition, but you can look up at others too. + +Finally, `settings` can modify `notification_preset` table too. This table will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. + +### output table Variable | Meaning | Type --- | --- | --- From ac084fd61b1fb3090d3c31c1f0bb8311345da498 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:00:59 -0700 Subject: [PATCH 248/546] Updated alsa (markdown) --- alsa.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index 7ad0a6e..f632717 100644 --- a/alsa.md +++ b/alsa.md @@ -12,7 +12,7 @@ Variable | Meaning | Type | Default `channel` | Mixer channel | string | "Master" `settings` | User settings | function | empty function -`settings` can be fed with the following variables: +`settings` can use the following variables: Variable | Meaning | Type | Values --- | --- | --- | --- From 1a26a10e7e2b66b17e85971da613c55dbd0229a0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:01:35 -0700 Subject: [PATCH 249/546] Updated bat (markdown) --- bat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bat.md b/bat.md index 04c80dd..ec10057 100644 --- a/bat.md +++ b/bat.md @@ -15,7 +15,7 @@ Variable | Meaning | Type | Default `battery` | Identifier of the battery | string | "BAT0" `settings` | User settings | function | empty function -`settings` can be fed with `bat_now` table, which contains the following strings: `status`, `perc`, `time`, `watt`. +`settings` can use the `bat_now` table, which contains the following strings: `status`, `perc`, `time`, `watt`. ### output From fb211a3483309d66776bbe64f80e40cae427ea5c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:02:15 -0700 Subject: [PATCH 250/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index 4994e1d..11bf53f 100644 --- a/cpu.md +++ b/cpu.md @@ -11,7 +11,7 @@ Variable | Meaning | Type | Default `timeout` | Refresh timeout seconds | int | 10 `settings` | User settings | function | empty function -`settings` can be fed with the string `usage`, which means the cpu use percentage. +`settings` can use the string `usage`, which is the cpu use percentage. ### output From df669be704440521b3e14817b75e268a11f7ad7b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:02:56 -0700 Subject: [PATCH 251/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index f1aa353..07f59a6 100644 --- a/fs.md +++ b/fs.md @@ -23,7 +23,7 @@ It can also use value strings in these formats: fs_info[p .. "size_mb"] fs_info[p .. "size_gb"] -where `p` is the "mount" column of the output of `df` command (`/`, `/home`, `/boot`, ...). +where `p` is the "mount" column of the output of `df` command ("/", "/home", "/boot", ...). This means you can set the widget for a certain partition, but you can look up at others too. From edb65339d50996197e8b651fc90259899677f76e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:03:36 -0700 Subject: [PATCH 252/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 07f59a6..6525e41 100644 --- a/fs.md +++ b/fs.md @@ -23,7 +23,7 @@ It can also use value strings in these formats: fs_info[p .. "size_mb"] fs_info[p .. "size_gb"] -where `p` is the "mount" column of the output of `df` command ("/", "/home", "/boot", ...). +where `p` is the last column of the output of `df` ("/", "/home", "/boot", ...). This means you can set the widget for a certain partition, but you can look up at others too. From f2fd571bee7cd5aa0a38f0649868ab042023698d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:04:23 -0700 Subject: [PATCH 253/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 6525e41..bb57c3a 100644 --- a/fs.md +++ b/fs.md @@ -23,7 +23,7 @@ It can also use value strings in these formats: fs_info[p .. "size_mb"] fs_info[p .. "size_gb"] -where `p` is the last column of the output of `df` ("/", "/home", "/boot", ...). +where `p` is the last column of `df` ("/", "/home", "/boot", ...). This means you can set the widget for a certain partition, but you can look up at others too. From 606d4f06d03290070c8bfa3cff50b15218c76b88 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:13:33 -0700 Subject: [PATCH 254/546] Updated fs (markdown) --- fs.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs.md b/fs.md index bb57c3a..883008d 100644 --- a/fs.md +++ b/fs.md @@ -27,7 +27,9 @@ where `p` is the last column of `df` ("/", "/home", "/boot", ...). This means you can set the widget for a certain partition, but you can look up at others too. -Finally, `settings` can modify `notification_preset` table too. This table will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. +Finally, `settings` can modify `notification_preset` table too. This table will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: + + notification_preset = { fg = beautiful.fg_normal } ### output table From 3028d8f44e9a7237eb04bfb17d60494a7f57775f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:14:30 -0700 Subject: [PATCH 255/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 883008d..46bcbc2 100644 --- a/fs.md +++ b/fs.md @@ -23,7 +23,7 @@ It can also use value strings in these formats: fs_info[p .. "size_mb"] fs_info[p .. "size_gb"] -where `p` is the last column of `df` ("/", "/home", "/boot", ...). +where `p` is the last column of `df` command ("/", "/home", "/boot", ...). This means you can set the widget for a certain partition, but you can look up at others too. From d9ed217c2ce568f4960013e76bd377a01fd47267 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:17:21 -0700 Subject: [PATCH 256/546] Updated imap (markdown) --- imap.md | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/imap.md b/imap.md index 97cd437..7b8e761 100644 --- a/imap.md +++ b/imap.md @@ -2,10 +2,6 @@ Shows mail status in a textbox over IMAP protocol. -Dependencies: - -- python3 - New mails are notified through a notification like this: +---------------------------------------------------+ @@ -26,29 +22,22 @@ Text will be cut if the mail is too long. The function takes a table as argument. Required table parameters are: -Variable | Type ---- | --- -`server` | string -`mail` | string -`password` | string +Variable | Meaning | Type +--- | --- | --- +`server` | Mail server | string +`mail` | User mail | string +`password` | User password | string while the optional are: Variable | Meaning | Type | Default --- | --- | --- | --- `port` | IMAP port | int | 993 -`refresh_timeout` | Refresh timeout seconds | int | 60 -`header` | Text to show before value | string | " Mail " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Mail value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to append after value | string | " " -`mail_encoding` | Mail character encoding | string | autodetected +`timeout` | Refresh timeout seconds | int | 60 +`encoding` | Mail character encoding | string | autodetected `maxlen` | Maximum chars to display in notification | int | 200 -`app` | Mail program to spawn on click | string | "mutt" -`shadow` | Hide widget when there are no mails | boolean | false `is_plain` | Define whether `password` is a plain password (true) or a function that retrieves it (false) | boolean | false - -**Note**: `footer` can be markup text. +`settings` | User settings | function Let's focus better on `is_plain`. @@ -65,6 +54,20 @@ and you'll have the same security provided by `~/.netrc`. When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. -You can also define your custom icon for the naughty notification. Just set `lain_mail_notify` into `theme.lua`: +`settings` can use the string `mailcount`, whose possible values are: - theme.lain_mail_notify = "/path/to/my/icon" \ No newline at end of file +- "0" +- "invalid credentials" +- string number + +and can modify `notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: + + notification _preset = { + icon = lain/icons/mail.png, + timeout = 8, + position = "top_left" + } + +### output + +A textbox. \ No newline at end of file From 131218c85e8787e11114e6f14c0650995974b2cc Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:25:32 -0700 Subject: [PATCH 257/546] Updated imap (markdown) --- imap.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/imap.md b/imap.md index 7b8e761..501ffac 100644 --- a/imap.md +++ b/imap.md @@ -1,5 +1,7 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) +**Please be warned**: as for now, this works fine in normal link situations, but is discouraged to use it if your connection is sobbing, since it may cause some short freezes. I am at work to solve this. + Shows mail status in a textbox over IMAP protocol. New mails are notified through a notification like this: From c036411efd3b0423c8e7c8792f7f227c78ba3f8b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:26:48 -0700 Subject: [PATCH 258/546] Updated imap (markdown) --- imap.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 501ffac..87a69e9 100644 --- a/imap.md +++ b/imap.md @@ -1,6 +1,8 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -**Please be warned**: as for now, this works fine in normal link situations, but is discouraged to use it if your connection is sobbing, since it may cause some short freezes. I am at work to solve this. +**Please be warned**: as for now, this works fine in normal link situations, but is discouraged to use it if your connection is sobbing, since it may cause some short freezes. I am working on socket libraries to solve this. If you're a Python programmer, feel free to lend a hand. + +--- Shows mail status in a textbox over IMAP protocol. From 299798e1c505d3c1477405a62e8669f37fc974b2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:27:24 -0700 Subject: [PATCH 259/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 87a69e9..cf5324d 100644 --- a/imap.md +++ b/imap.md @@ -1,6 +1,6 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -**Please be warned**: as for now, this works fine in normal link situations, but is discouraged to use it if your connection is sobbing, since it may cause some short freezes. I am working on socket libraries to solve this. If you're a Python programmer, feel free to lend a hand. +**Please be warned**: as for now, this works fine in normal link situations, but is discouraged to use it if your connection is sobbing, since it may cause some short freezes due to timeout issues. I am working on socket libraries to solve this. If you're a Python programmer, feel free to lend a hand. --- From 6524693b71ffc090854ad07a144befb744edda1c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:28:03 -0700 Subject: [PATCH 260/546] Updated imap (markdown) --- imap.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imap.md b/imap.md index cf5324d..e583410 100644 --- a/imap.md +++ b/imap.md @@ -1,6 +1,8 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -**Please be warned**: as for now, this works fine in normal link situations, but is discouraged to use it if your connection is sobbing, since it may cause some short freezes due to timeout issues. I am working on socket libraries to solve this. If you're a Python programmer, feel free to lend a hand. +**Please be warned**: as for now, this works fine in normal link situations, but is discouraged to use it if your connection is sobbing, since it may cause some short freezes due to timeout issues. I am working on socket libraries to solve this. + +If you're a Python programmer, feel free to lend a hand. --- From c77e4191baf4b708d3925fe0822980f005668537 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:31:01 -0700 Subject: [PATCH 261/546] Updated maildir (markdown) --- maildir.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/maildir.md b/maildir.md index a30e59f..355ecdd 100644 --- a/maildir.md +++ b/maildir.md @@ -24,19 +24,16 @@ If there's new mails, the textbox will say something like "mail: bugs(3), system mymaildir = lain.widgets.maildir("/path/to/my/maildir") -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 60 `mailpath` | Path to your maildir | string | "~/Mail" -`ignore_boxes` | A list of boxes to ignore | table | empty table -`refresh_timeout` | Refresh timeout seconds | int | 60 -`header` | Text to show before value | string | " Mail " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color_newmail` | New mail value color | string | `beautiful.fg_focus` or "#FFFFFF" -`color_nomail` | No mail value color | string | `beautiful.fg_normal` or "#FFFFFF" -`footer` | Text to append after value | string | " " -`app` | Mail program to spawn on click | string | "mutt"| boolean | false -`shadow` | Hide widget when there are no mails | boolean | false +`settings` | User settings | function | empty function -**Note**: `footer` can be markup text. \ No newline at end of file +`settings` can use the string `newmail`, which format will be something like defined above, or "no mail". + +### output + +A textbox. \ No newline at end of file From bab5d155b029d5a42bfa695d66f7e1e098d00da7 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:33:06 -0700 Subject: [PATCH 262/546] Updated mem (markdown) --- mem.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/mem.md b/mem.md index 68c6748..067dc25 100644 --- a/mem.md +++ b/mem.md @@ -10,12 +10,11 @@ contain: Variable | Meaning | Type | Default --- | --- | --- | --- -`refresh_timeout` | Refresh timeout seconds | int | 10 -`show_swap` | Show amount of used swap space? | boolean | false -`show_total` | Show amout of total memory? | boolean | false -`header` | Text to show before value | string | " Mem " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to show after value | string | "MB " +`timeout` | Refresh timeout seconds | int | 10 +`settings` | User settings | function | empty function -**Note**: `footer` color is `color`. \ No newline at end of file +`settings` can use the strings `used` (memory used MB) and `swapused` (swap used MB). + +### output + +A textbox. \ No newline at end of file From ac65284aa693d5d65351e2f94f62aca8b4765d05 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:40:31 -0700 Subject: [PATCH 263/546] Updated Widgets (markdown) --- Widgets.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Widgets.md b/Widgets.md index 7130cc3..1a26b80 100644 --- a/Widgets.md +++ b/Widgets.md @@ -1,8 +1,6 @@ Every widget is output by a `function`. -Unless otherwise expressly noted, `function` returns a `wibox.widget.textbox`. - -This is said because, for some widgets, `function` returns a table to be used for notification and update purposes. +For some widgets, `function` returns a `wibox.widget.textbox`, for others a table to be used for notification and update purposes. Every widget may take either a table or a list of variables as argument. From 70750818def17a7fcafb70564040dfd64faa44dd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:47:19 -0700 Subject: [PATCH 264/546] Updated mpd (markdown) --- mpd.md | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/mpd.md b/mpd.md index 2a0ba32..ab36d15 100644 --- a/mpd.md +++ b/mpd.md @@ -2,7 +2,7 @@ Shows MPD status in a textbox. - mympd = lain.widgets.mpd() + mpdwidget = lain.widgets.mpd() Now playing songs are notified like this: @@ -14,37 +14,47 @@ Now playing songs are notified like this: | +-------+ | +--------------------------------------------------------+ -Dependencies - -- imagemagick - The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 1 `password` | MPD password | string | "" `host` | MPD server | string | "127.0.0.1" `port` | MPD port | string | "6600" `music_dir` | Music directory | string | "~/Music" -`refresh_timeout` | Refresh timeout seconds | int | 1 -`header` | Text before values | string | "" -`artist_color` | Artist value color | string | `beautiful.fg_normal` or "#FFFFFF" -`song_color` | Song value color | string | `beautiful.fg_focus` or "#FFFFFF" -`spr` | Separator text between artist and song values | string | " " -`footer` | Text to append after values | string | "" -`app` | Music program to spawn on click | string | "ncmpcpp" -`shadow` | Hide widget when there are no songs playing | boolean | false +`settings` | User settings | function | empty function -**Note**: `spr` and `footer` can be markup text. +`settings` can use `mpd_now` table, which contains the following string values: -`lain.widgets.mpd` outputs the following table: +- state +- file +- artist +- title +- album +- date + +and can modify `notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: + + notification _preset = { + title = "Now playing", + text = mpd_now.artist .. " (" .. + mpd_now.album .. ") - " .. + mpd_now.date .. "\n" .. + mpd_now.title, + fg = beautiful.fg_normal or "#FFFFFF", + bg = beautiful.bg_normal or "#000000", + timeout = 6 + } + +### output table Variable | Meaning | Type --- | --- | --- `widget` | The textbox | `wibox.widget.textbox` `notify` | The notification | function -Finally, you can control the widget with key bindings like these: +You can control the widget with key bindings like these: -- MPD control awful.key({ altkey, "Control" }, "Up", From de3e1da7cba095a4755bb376d4cb352abdaa8c50 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:52:25 -0700 Subject: [PATCH 265/546] Updated mpd (markdown) --- mpd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index ab36d15..8b35e81 100644 --- a/mpd.md +++ b/mpd.md @@ -14,7 +14,7 @@ Now playing songs are notified like this: | +-------+ | +--------------------------------------------------------+ -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- From 0828bfa394c12520db723c23d7e1490d7775b068 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:55:52 -0700 Subject: [PATCH 266/546] Updated net (markdown) --- net.md | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/net.md b/net.md index 82772d7..096b6a0 100644 --- a/net.md +++ b/net.md @@ -4,26 +4,15 @@ Monitors network interfaces and shows current traffic in a textbox. mynet = lain.widgets.net() -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 2 `iface` | Network device | string | autodetected -`refresh_timeout` | Refresh timeout seconds | int | 2 `units` | Units | int | 1024 (kilobytes) -`spr` | Separator text between download and upload values | string | " " -`header` | Text to show before value | string | `iface` -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`footer` | Text to append after value | string | "" -`color_up` | Upload value color | string | `beautiful.fg_focus` or "#FFFFFF" -`color_down` | Download value color | string | `beautiful.fg_focus` or "#FFFFFF" -`app` | Net program to spawn on click | string | "sudo wifi-menu" +`settings` | User settings | function | empty function -**Note**: `spr` and `footer` can be a markup text. +Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), ... . -Possible value for `units` are stored in table `lain.widgets.net.units`, which contains: - - ["b"] = 1, - ["kb"] = 1024, - ["mb"] = 1024^2, - ["gb"] = 1024^3 \ No newline at end of file +`settings` can use the following `iface` strings: `carrier`, `state`, `sent`, `received`. \ No newline at end of file From 1d70c86346d7824f1bb9d609505957f7c3bba8e3 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 14:56:45 -0700 Subject: [PATCH 267/546] Updated net (markdown) --- net.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net.md b/net.md index 096b6a0..bace937 100644 --- a/net.md +++ b/net.md @@ -15,4 +15,8 @@ Variable | Meaning | Type | Default Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), ... . -`settings` can use the following `iface` strings: `carrier`, `state`, `sent`, `received`. \ No newline at end of file +`settings` can use the following `iface` strings: `carrier`, `state`, `sent`, `received`. + +### output + +A textbox. \ No newline at end of file From 88626b7bb0f93d18cc10961a5f11289b62b5591e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 15:00:37 -0700 Subject: [PATCH 268/546] Updated sysload (markdown) --- sysload.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sysload.md b/sysload.md index 65b5eec..234770b 100644 --- a/sysload.md +++ b/sysload.md @@ -4,13 +4,15 @@ Show the current system load in a textbox. mysysload = lain.widgets.sysload() -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- -`show_all` | Show all the three values (true), or only the first one (false) | boolean | false -`refresh_timeout` | Refresh timeout seconds | int | 5 -`header` | Text to show before value | string | " Load " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`app` | Proc program to spawn on click | string | "top" \ No newline at end of file +`timeout` | Refresh timeout seconds | int | 5 +`settings` | User settings | function | empty function + +`settings` can use strings `a`, `b` and `c`, which are loadavg over 1, 5, and 15 minutes. + +### output + +A textbox. \ No newline at end of file From 22396b825d9e00d4206f6e03260bf5d261a21ba6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 15:02:23 -0700 Subject: [PATCH 269/546] Updated temp (markdown) --- temp.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/temp.md b/temp.md index 92d7d06..f7315b6 100644 --- a/temp.md +++ b/temp.md @@ -10,8 +10,7 @@ The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- -`refresh_timeout` | Refresh timeout seconds | int | 5 -`header` | Text to show before value | string | " Temp " -`header_color` | Header color | string | `beautiful.fg_normal` or "#FFFFFF" -`color` | Value color | string | `beautiful.fg_focus` or "#FFFFFF" -`footer` | Text to show after value | string | "C " \ No newline at end of file +`timeout` | Refresh timeout seconds | int | 5 +`settings` | User settings | function | empty function + +`settings` can use the string `coretemp_now`, which means current core temperature, expressed in Celsius (linux standard). \ No newline at end of file From 4a5a9c60846d60ee9db4d26813dc70075301a86b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 15:03:57 -0700 Subject: [PATCH 270/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index 11bf53f..ae490b0 100644 --- a/cpu.md +++ b/cpu.md @@ -8,7 +8,7 @@ Shows in a textbox the average CPU usage percent for a given amount of time. Variable | Meaning | Type | Default --- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 10 +`timeout` | Refresh timeout seconds | int | 5 `settings` | User settings | function | empty function `settings` can use the string `usage`, which is the cpu use percentage. From 0f36234af05bace823e452c077029e858f9c9d5b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 15:04:34 -0700 Subject: [PATCH 271/546] Updated mem (markdown) --- mem.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mem.md b/mem.md index 067dc25..80e6a88 100644 --- a/mem.md +++ b/mem.md @@ -10,7 +10,7 @@ contain: Variable | Meaning | Type | Default --- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 10 +`timeout` | Refresh timeout seconds | int | 3 `settings` | User settings | function | empty function `settings` can use the strings `used` (memory used MB) and `swapused` (swap used MB). From 7d6ad2a551a21a399c18aa645d8bf7e5ad7336b0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 10 Sep 2013 15:10:43 -0700 Subject: [PATCH 272/546] Updated yawn (markdown) --- yawn.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/yawn.md b/yawn.md index 070bf2e..6a087cc 100644 --- a/yawn.md +++ b/yawn.md @@ -24,15 +24,18 @@ an existent widget. - ``args`` - An optional table which can contain the following settings: + A required table which can contain: Variables | Meaning | Type | Possible values | Default value --- | --- | --- | --- | --- `u` | Units | string | "c" (Celsius), "f" (Fahrenheit) | "c" - `toshow` | What to show | string | "forecast", "units", "both" | "forecast" - `color` | ``yawn.widget`` color | string | hexadecimal colors | + `timeout` | Refresh timeout seconds | int | integers | 600 + `settings` | User settings | function | function | empty function -The function creates an imagebox icon and a textbox widget. Add them to you wibox like this: + `settings` can use strings `forecast`, `units', and can modify `notification_preset` table, which + will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. + +The function `register` creates an imagebox icon and a textbox widget. Add them to you wibox like this: right_layout:add(yawn.icon) right_layout:add(yawn.widget) From 0006445c96dee7758535982ec3ab517d65de5a15 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 05:46:07 -0700 Subject: [PATCH 273/546] Updated Utilities (markdown) --- Utilities.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Utilities.md b/Utilities.md index cbf8c0f..7e18683 100644 --- a/Utilities.md +++ b/Utilities.md @@ -1,11 +1,11 @@ markup ------ -This is a submodule which helps you markupping your text. +Made markup easier! First, require it like this: - local markup = require("lain.util.markup") + local markup = lain.util.markup then you can call its functions: From 831843ea8215de345abcd4e012cd5754d1ee76fd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 05:46:54 -0700 Subject: [PATCH 274/546] Updated Utilities (markdown) --- Utilities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utilities.md b/Utilities.md index 7e18683..6afff16 100644 --- a/Utilities.md +++ b/Utilities.md @@ -46,7 +46,7 @@ they all take one argument, which is the text to markup, except `fg.color` and ` menu\_clients\_current\_tags ---------------------------- -Similar to `awful.menu.clients()`, but this menu only shows the clients +Similar to `awful.menu.clients`, but this menu only shows the clients of currently visible tags. Use it with a key binding like this: awful.key({ "Mod1" }, "Tab", From 68c7a3bf379942a3a833e29ef7a08e238663479d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 07:09:56 -0700 Subject: [PATCH 275/546] Updated mpd (markdown) --- mpd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index 8b35e81..bd7232e 100644 --- a/mpd.md +++ b/mpd.md @@ -27,7 +27,7 @@ Variable | Meaning | Type | Default `settings` can use `mpd_now` table, which contains the following string values: -- state +- state (possible values: "play", "pause", "stop") - file - artist - title From 4a09e9f9081c5f4fc49193c76b198c64228f608d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 07:19:34 -0700 Subject: [PATCH 276/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 46bcbc2..44be2b2 100644 --- a/fs.md +++ b/fs.md @@ -14,7 +14,7 @@ Variable | Meaning | Type | Default `partition` | Partition to monitor | string | "/" `settings` | User settings | function | empty function -`settings` can use the following `partition` related value strings: `used`, `available`, `size_mb`, `size_gb`. +`settings` can use the following `partition` related float values: `used` and `available`, `size_mb`, `size_gb`. It can also use value strings in these formats: From 1d7fdb618e96644f2c2ebe217a4e0a2c79d7ca93 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 07:28:25 -0700 Subject: [PATCH 277/546] Updated yawn (markdown) --- yawn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yawn.md b/yawn.md index 6a087cc..5b111bd 100644 --- a/yawn.md +++ b/yawn.md @@ -32,7 +32,7 @@ an existent widget. `timeout` | Refresh timeout seconds | int | integers | 600 `settings` | User settings | function | function | empty function - `settings` can use strings `forecast`, `units', and can modify `notification_preset` table, which + `settings` can use strings `forecast`, `units`, and can modify `notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. The function `register` creates an imagebox icon and a textbox widget. Add them to you wibox like this: From a23ff4301e64584bd933b9515e1ce6f2fe733b58 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 09:36:42 -0700 Subject: [PATCH 278/546] Updated imap (markdown) --- imap.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/imap.md b/imap.md index e583410..6590ee7 100644 --- a/imap.md +++ b/imap.md @@ -1,8 +1,6 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -**Please be warned**: as for now, this works fine in normal link situations, but is discouraged to use it if your connection is sobbing, since it may cause some short freezes due to timeout issues. I am working on socket libraries to solve this. - -If you're a Python programmer, feel free to lend a hand. +**Please be warned**: this is a temporary solution, since it works fine in normal situations but causes little freezes if connection is sobbing. I am working on something much more solid. --- From 0025ef766d28db61974311f57d206e91d5d381e0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 09:39:38 -0700 Subject: [PATCH 279/546] Updated alsa (markdown) --- alsa.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/alsa.md b/alsa.md index f632717..af1139a 100644 --- a/alsa.md +++ b/alsa.md @@ -24,7 +24,7 @@ volume.status | Device status | string | "on", "off" Variable | Meaning | Type --- | --- | --- `widget` | The widget | `wibox.widget.textbox` -`notify` | Force update `widget` | function +`update` | Update `widget` | function You can control the widget with key bindings like these: @@ -32,22 +32,22 @@ You can control the widget with key bindings like these: awful.key({ altkey }, "Up", function () awful.util.spawn("amixer sset Master 1%+") - volume.notify() + volume.update() end), awful.key({ altkey }, "Down", function () awful.util.spawn("amixer sset Master 1%-") - volume.notify() + volume.update() end), awful.key({ altkey }, "m", function () awful.util.spawn("amixer set Master playback toggle") - volume.notify() + volume.update() end), awful.key({ altkey, "Control" }, "m", function () awful.util.spawn("amixer set Master playback 100%", false ) - volume.notify() + volume.update() end), where `altkey = "Mod1"`. \ No newline at end of file From 999c0503926bf848ec65033127bb7bc7a7ce3989 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 09:40:33 -0700 Subject: [PATCH 280/546] Updated alsa (markdown) --- alsa.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alsa.md b/alsa.md index af1139a..65314d2 100644 --- a/alsa.md +++ b/alsa.md @@ -31,12 +31,12 @@ You can control the widget with key bindings like these: -- Volume control awful.key({ altkey }, "Up", function () - awful.util.spawn("amixer sset Master 1%+") + awful.util.spawn("amixer set Master 1%+") volume.update() end), awful.key({ altkey }, "Down", function () - awful.util.spawn("amixer sset Master 1%-") + awful.util.spawn("amixer set Master 1%-") volume.update() end), awful.key({ altkey }, "m", From 0683c87e997e9ca8bf3cc0787ee3ddf2481ab1f6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 09:41:14 -0700 Subject: [PATCH 281/546] Updated alsabar (markdown) --- alsabar.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alsabar.md b/alsabar.md index 549b28a..7763fe4 100644 --- a/alsabar.md +++ b/alsabar.md @@ -56,12 +56,12 @@ You can control the widget with key bindings like these: -- Volume control awful.key({ altkey }, "Up", function () - awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "+") + awful.util.spawn("amixer set " .. volume.channel .. " " .. volume.step .. "+") volume.notify() end), awful.key({ altkey }, "Down", function () - awful.util.spawn("amixer sset " .. volume.channel .. " " .. volume.step .. "-") + awful.util.spawn("amixer set " .. volume.channel .. " " .. volume.step .. "-") volume.notify() end), awful.key({ altkey }, "m", From 377498cdfb6481be11f2edb0393eb3ff4d66a62a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 10:06:31 -0700 Subject: [PATCH 282/546] Updated mpd (markdown) --- mpd.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/mpd.md b/mpd.md index bd7232e..2f7a24c 100644 --- a/mpd.md +++ b/mpd.md @@ -38,13 +38,9 @@ and can modify `notification_preset` table, which will be the preset for the nau notification _preset = { title = "Now playing", - text = mpd_now.artist .. " (" .. - mpd_now.album .. ") - " .. - mpd_now.date .. "\n" .. - mpd_now.title, - fg = beautiful.fg_normal or "#FFFFFF", - bg = beautiful.bg_normal or "#000000", - timeout = 6 + timeout = 6, + text = string.format("%s (%s) - %s\n%s", mpd_now.artist, + mpd_now.album, mpd_now.date, mpd_now.title) } ### output table From 421f78494768137d249cd7fb946f962e7ff19179 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 10:10:07 -0700 Subject: [PATCH 283/546] Updated yawn (markdown) --- yawn.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/yawn.md b/yawn.md index 5b111bd..a9a1a7b 100644 --- a/yawn.md +++ b/yawn.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + (YAhoo! Weather Notification) Yawn provides brief and compact Yahoo! Weather notification. From d25edd7d2bbe319800033671ddf0fa42e930ab74 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 10:40:47 -0700 Subject: [PATCH 284/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 6590ee7..491bc31 100644 --- a/imap.md +++ b/imap.md @@ -1,6 +1,6 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -**Please be warned**: this is a temporary solution, since it works fine in normal situations but causes little freezes if connection is sobbing. I am working on something much more solid. +**Please be warned**: this is a temporary solution, since it works fine in normal situations but may causes little freezes if connection is sobbing. I am working on something much more solid. --- From 49742b2fa9c33580903ee2af11d095fe46ec7d3e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 10:51:45 -0700 Subject: [PATCH 285/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 491bc31..3063bec 100644 --- a/imap.md +++ b/imap.md @@ -1,6 +1,6 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -**Please be warned**: this is a temporary solution, since it works fine in normal situations but may causes little freezes if connection is sobbing. I am working on something much more solid. +**Please be warned**: this is a temporary solution, I am working on something much more solid. --- From 1bab36983b644e29b6b8843c90a493c2901ea32d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 10:54:18 -0700 Subject: [PATCH 286/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index 1a26b80..e812db2 100644 --- a/Widgets.md +++ b/Widgets.md @@ -10,7 +10,7 @@ To markup the textbox, call `widget:set_markup(...)` within `settings`. You can feed `set_markup` with predefined arguments, see the sections for all the details. -`widget` is a textbox, so you can also threat it like any other `wibox.widget.textbox`. +`widget` is a textbox, so you can threat it like any other `wibox.widget.textbox`. Here follows an example: From eef2b8bd8942119a81f8eb4804536f3a62a82ae7 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 16:17:09 -0700 Subject: [PATCH 287/546] Updated imap (markdown) --- imap.md | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/imap.md b/imap.md index 3063bec..af29cb3 100644 --- a/imap.md +++ b/imap.md @@ -1,28 +1,16 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -**Please be warned**: this is a temporary solution, I am working on something much more solid. - ---- - Shows mail status in a textbox over IMAP protocol. + myimapcheck = lain.widgets.imap(args) + New mails are notified through a notification like this: - +---------------------------------------------------+ - | +---+ | - | |\ /| donald@disney.org has 3 new messages | - | +---+ | - | Latest From: Mickey Mouse | - | Subject: Re: pay raise | - | | - | Not after what you did yesterday. | - | Daisy told me everything [...] | - | | - +---------------------------------------------------+ - -Text will be cut if the mail is too long. - - myimapcheck = lain.widgets.imap(args) + +--------------------------------------------+ + | +---+ | + | |\ /| donald@disney.org has 3 new messages | + | +---+ | + +--------------------------------------------+ The function takes a table as argument. Required table parameters are: @@ -38,8 +26,6 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `port` | IMAP port | int | 993 `timeout` | Refresh timeout seconds | int | 60 -`encoding` | Mail character encoding | string | autodetected -`maxlen` | Maximum chars to display in notification | int | 200 `is_plain` | Define whether `password` is a plain password (true) or a function that retrieves it (false) | boolean | false `settings` | User settings | function @@ -58,20 +44,17 @@ and you'll have the same security provided by `~/.netrc`. When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. -`settings` can use the string `mailcount`, whose possible values are: +`settings` can use the value `mailcount`, an integer greater or equal to zero, and can modify `notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. -- "0" -- "invalid credentials" -- string number - -and can modify `notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: +Default definition: notification _preset = { icon = lain/icons/mail.png, - timeout = 8, position = "top_left" } +Note that `mailcount` is 0 either if there are no new mails or credentials are invalid, so make sure you get the right settings. + ### output A textbox. \ No newline at end of file From 1bb4d3a124912805bc3a2e7ef3b1b22e2544764c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 17:25:35 -0700 Subject: [PATCH 288/546] Updated imap (markdown) --- imap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imap.md b/imap.md index af29cb3..7b232a1 100644 --- a/imap.md +++ b/imap.md @@ -1,10 +1,10 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -Shows mail status in a textbox over IMAP protocol. +Shows mail count in a textbox fetching over IMAP. myimapcheck = lain.widgets.imap(args) -New mails are notified through a notification like this: +New mails are notified like this: +--------------------------------------------+ | +---+ | From a8865ef1879ce892177029bf4cbdd02b863b5278 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 11 Sep 2013 17:26:08 -0700 Subject: [PATCH 289/546] Updated Home (markdown) --- Home.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Home.md b/Home.md index 74f336f..6b7b58d 100644 --- a/Home.md +++ b/Home.md @@ -7,7 +7,6 @@ Package | Requested by alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) curl | widget types accessing network resources imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) -python3 | [imap](https://github.com/copycat-killer/lain/wiki/imap) ### Installation From 09d7ce58c1f1a335490d5aadf1a105fd12394a5e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 08:04:28 -0700 Subject: [PATCH 290/546] Updated alsabar (markdown) --- alsabar.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/alsabar.md b/alsabar.md index 7763fe4..ad5b1bf 100644 --- a/alsabar.md +++ b/alsabar.md @@ -1,6 +1,6 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -Shows and controls alsa volume with a progressbar and provides tooltips, notifications, and color changes at mute/unmute switch. +Shows and controls alsa volume with a progressbar; provides tooltips, notifications, and color changes at mute/unmute switch. myvolumebar = lain.widgets.alsabar() @@ -12,6 +12,7 @@ The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 4 `width` | Bar width | int | 63 `height` | Bar height | int | 1 `ticks` | Set bar ticks on | boolean | true From e9bd8803d85049b18833c7ec9e07b4e58953a5df Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 08:43:38 -0700 Subject: [PATCH 291/546] Updated fs (markdown) --- fs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs.md b/fs.md index 44be2b2..5588ca7 100644 --- a/fs.md +++ b/fs.md @@ -27,9 +27,9 @@ where `p` is the last column of `df` command ("/", "/home", "/boot", ...). This means you can set the widget for a certain partition, but you can look up at others too. -Finally, `settings` can modify `notification_preset` table too. This table will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: +Finally, `settings` can modify `fs_notification_preset` table too. This table will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: - notification_preset = { fg = beautiful.fg_normal } + fs_notification_preset = { fg = beautiful.fg_normal } ### output table From 82192b3889feaeca7f1ab3ad52c49ec3d5352ea1 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 08:44:22 -0700 Subject: [PATCH 292/546] Updated imap (markdown) --- imap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imap.md b/imap.md index 7b232a1..ba92d0f 100644 --- a/imap.md +++ b/imap.md @@ -44,11 +44,11 @@ and you'll have the same security provided by `~/.netrc`. When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. -`settings` can use the value `mailcount`, an integer greater or equal to zero, and can modify `notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. +`settings` can use the value `mailcount`, an integer greater or equal to zero, and can modify `mail_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: - notification _preset = { + mail_notification _preset = { icon = lain/icons/mail.png, position = "top_left" } From 12c1acb5371753195cb7ef30a13d3f493ea343bf Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 08:47:10 -0700 Subject: [PATCH 293/546] Updated mpd (markdown) --- mpd.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mpd.md b/mpd.md index 2f7a24c..51467e1 100644 --- a/mpd.md +++ b/mpd.md @@ -34,9 +34,9 @@ Variable | Meaning | Type | Default - album - date -and can modify `notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: +and can modify `mpd_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: - notification _preset = { + mpd_notification _preset = { title = "Now playing", timeout = 6, text = string.format("%s (%s) - %s\n%s", mpd_now.artist, From 1ae2152188f00b97600ffd8f3f165fb85ff1228c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 08:52:53 -0700 Subject: [PATCH 294/546] Updated yawn (markdown) --- yawn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yawn.md b/yawn.md index a9a1a7b..30d160c 100644 --- a/yawn.md +++ b/yawn.md @@ -34,7 +34,7 @@ an existent widget. `timeout` | Refresh timeout seconds | int | integers | 600 `settings` | User settings | function | function | empty function - `settings` can use strings `forecast`, `units`, and can modify `notification_preset` table, which + `settings` can use strings `forecast`, `units`, and can modify `yawn_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. The function `register` creates an imagebox icon and a textbox widget. Add them to you wibox like this: From 567b48f8a1ff91eb859997378ea9f1355c21c409 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 09:07:46 -0700 Subject: [PATCH 295/546] Updated alsabar (markdown) --- alsabar.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alsabar.md b/alsabar.md index ad5b1bf..7a90478 100644 --- a/alsabar.md +++ b/alsabar.md @@ -67,12 +67,12 @@ You can control the widget with key bindings like these: end), awful.key({ altkey }, "m", function () - awful.util.spawn("amixer set Master playback toggle") + awful.util.spawn("amixer set " .. volume.channel .. " playback toggle") volume.notify() end), awful.key({ altkey, "Control" }, "m", function () - awful.util.spawn("amixer set Master playback 100%", false ) + awful.util.spawn("amixer set " .. volume.channel .. " playback 100%", false ) volume.notify() end), From da846b94e7c30151c5ebbd1bdb746e02994c7dfc Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 09:15:04 -0700 Subject: [PATCH 296/546] Updated mpd (markdown) --- mpd.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mpd.md b/mpd.md index 51467e1..de945b4 100644 --- a/mpd.md +++ b/mpd.md @@ -56,22 +56,22 @@ You can control the widget with key bindings like these: awful.key({ altkey, "Control" }, "Up", function () awful.util.spawn_with_shell("mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle") - mpdwidget.notify() + mpdwidget.update() end), awful.key({ altkey, "Control" }, "Down", function () awful.util.spawn_with_shell("mpc stop || ncmpcpp stop || ncmpc stop || pms stop") - mpdwidget.notify() + mpdwidget.update() end), awful.key({ altkey, "Control" }, "Left", function () awful.util.spawn_with_shell("mpc prev || ncmpcpp prev || ncmpc prev || pms prev") - mpdwidget.notify() + mpdwidget.update() end), awful.key({ altkey, "Control" }, "Right", function () awful.util.spawn_with_shell("mpc next || ncmpcpp next || ncmpc next || pms next") - mpdwidget.notify() + mpdwidget.update() end), where `altkey = "Mod1"`. \ No newline at end of file From e241095ee6e5f705d05a65c88240163e4f5d5ebe Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 09:37:19 -0700 Subject: [PATCH 297/546] Updated alsa (markdown) --- alsa.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/alsa.md b/alsa.md index 65314d2..6cc8b59 100644 --- a/alsa.md +++ b/alsa.md @@ -16,8 +16,8 @@ Variable | Meaning | Type | Default Variable | Meaning | Type | Values --- | --- | --- | --- -volume.level | Self explained | int | 0-100 -volume.status | Device status | string | "on", "off" +volume_now.level | Self explained | int | 0-100 +volume_now.status | Device status | string | "on", "off" ### output table @@ -32,22 +32,22 @@ You can control the widget with key bindings like these: awful.key({ altkey }, "Up", function () awful.util.spawn("amixer set Master 1%+") - volume.update() + volumewidget.update() end), awful.key({ altkey }, "Down", function () awful.util.spawn("amixer set Master 1%-") - volume.update() + volumewidget.update() end), awful.key({ altkey }, "m", function () awful.util.spawn("amixer set Master playback toggle") - volume.update() + volumewidget.update() end), awful.key({ altkey, "Control" }, "m", function () awful.util.spawn("amixer set Master playback 100%", false ) - volume.update() + volumewidget.update() end), where `altkey = "Mod1"`. \ No newline at end of file From 7820874500305941464f69a116bd603180e26284 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 09:37:35 -0700 Subject: [PATCH 298/546] Updated alsa (markdown) --- alsa.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsa.md b/alsa.md index 6cc8b59..abe82b8 100644 --- a/alsa.md +++ b/alsa.md @@ -2,7 +2,7 @@ Shows and controls alsa volume with a textbox. - volume = lain.widgets.alsa() + volumewidget = lain.widgets.alsa() ### input table From 88e64639d11859621848ca2ebe21acfa6adfc4d2 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 09:37:54 -0700 Subject: [PATCH 299/546] Updated alsa (markdown) --- alsa.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/alsa.md b/alsa.md index abe82b8..daf4016 100644 --- a/alsa.md +++ b/alsa.md @@ -16,8 +16,8 @@ Variable | Meaning | Type | Default Variable | Meaning | Type | Values --- | --- | --- | --- -volume_now.level | Self explained | int | 0-100 -volume_now.status | Device status | string | "on", "off" +`volume_now.level` | Self explained | int | 0-100 +`volume_now.status` | Device status | string | "on", "off" ### output table From 979986f42a895ba93231d888aa53ccbd8934559e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 09:57:10 -0700 Subject: [PATCH 300/546] Updated alsabar (markdown) --- alsabar.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/alsabar.md b/alsabar.md index 7a90478..711c8ce 100644 --- a/alsabar.md +++ b/alsabar.md @@ -58,22 +58,22 @@ You can control the widget with key bindings like these: awful.key({ altkey }, "Up", function () awful.util.spawn("amixer set " .. volume.channel .. " " .. volume.step .. "+") - volume.notify() + myvolumebar.notify() end), awful.key({ altkey }, "Down", function () awful.util.spawn("amixer set " .. volume.channel .. " " .. volume.step .. "-") - volume.notify() + myvolumeba.notify() end), awful.key({ altkey }, "m", function () awful.util.spawn("amixer set " .. volume.channel .. " playback toggle") - volume.notify() + myvolumebar.notify() end), awful.key({ altkey, "Control" }, "m", function () awful.util.spawn("amixer set " .. volume.channel .. " playback 100%", false ) - volume.notify() + myvolumebar.notify() end), where `altkey = "Mod1"`. \ No newline at end of file From a773b5b8b6b333774b1d13ea332e82bd9b6f226c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 12:32:27 -0700 Subject: [PATCH 301/546] Updated net (markdown) --- net.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net.md b/net.md index bace937..a1b6d35 100644 --- a/net.md +++ b/net.md @@ -13,9 +13,9 @@ Variable | Meaning | Type | Default `units` | Units | int | 1024 (kilobytes) `settings` | User settings | function | empty function -Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), ... . +Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), and so on. -`settings` can use the following `iface` strings: `carrier`, `state`, `sent`, `received`. +`settings` can use the following `iface` strings: `carrier` ("0", "1"), `state` ("up", "down"), `sent`, `received` (numbers). ### output From 9afb2b28aa802f68f97fd785da9f0efccce8548f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 12:33:04 -0700 Subject: [PATCH 302/546] Updated net (markdown) --- net.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net.md b/net.md index a1b6d35..f1cd095 100644 --- a/net.md +++ b/net.md @@ -15,7 +15,11 @@ Variable | Meaning | Type | Default Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), and so on. -`settings` can use the following `iface` strings: `carrier` ("0", "1"), `state` ("up", "down"), `sent`, `received` (numbers). +`settings` can use the following `iface` strings: + +- `carrier` ("0", "1"); +- `state` ("up", "down"); +- `sent` and `received` (numbers). ### output From ef85d5638f0cc96fc892a980f281f17c1f740ec1 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 12:34:21 -0700 Subject: [PATCH 303/546] Updated bat (markdown) --- bat.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bat.md b/bat.md index ec10057..27a0d32 100644 --- a/bat.md +++ b/bat.md @@ -15,7 +15,12 @@ Variable | Meaning | Type | Default `battery` | Identifier of the battery | string | "BAT0" `settings` | User settings | function | empty function -`settings` can use the `bat_now` table, which contains the following strings: `status`, `perc`, `time`, `watt`. +`settings` can use the `bat_now` table, which contains the following strings: + +- `status` ("Not present", "Charging", "Discharging"); +-`perc`; +- `time`; +- `watt`. ### output From 127b9f6c1405ff97178b14c462361c4656f547d3 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 12:34:40 -0700 Subject: [PATCH 304/546] Updated bat (markdown) --- bat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bat.md b/bat.md index 27a0d32..50c14e8 100644 --- a/bat.md +++ b/bat.md @@ -18,7 +18,7 @@ Variable | Meaning | Type | Default `settings` can use the `bat_now` table, which contains the following strings: - `status` ("Not present", "Charging", "Discharging"); --`perc`; +- `perc`; - `time`; - `watt`. From 3a5d2753d637a702c64c5326c436536805b8afd4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 12:47:57 -0700 Subject: [PATCH 305/546] Updated mem (markdown) --- mem.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mem.md b/mem.md index 80e6a88..1079ca5 100644 --- a/mem.md +++ b/mem.md @@ -13,7 +13,7 @@ Variable | Meaning | Type | Default `timeout` | Refresh timeout seconds | int | 3 `settings` | User settings | function | empty function -`settings` can use the strings `used` (memory used MB) and `swapused` (swap used MB). +`settings` can use the strings `mem_now.used` (memory used MB) and `mem_now.swapused` (swap used MB). ### output From 69977551b0e780a1aa1952add4344ec0628fda93 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 12:49:36 -0700 Subject: [PATCH 306/546] Updated sysload (markdown) --- sysload.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysload.md b/sysload.md index 234770b..4ed61a8 100644 --- a/sysload.md +++ b/sysload.md @@ -11,7 +11,7 @@ Variable | Meaning | Type | Default `timeout` | Refresh timeout seconds | int | 5 `settings` | User settings | function | empty function -`settings` can use strings `a`, `b` and `c`, which are loadavg over 1, 5, and 15 minutes. +`settings` can use strings `load_1`, `load_5` and `load_15`, which are loadavg over 1, 5, and 15 minutes. ### output From 4c9f01221f1b105f43a2338db60f321da8fee87c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 15:15:22 -0700 Subject: [PATCH 307/546] Updated net (markdown) --- net.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net.md b/net.md index f1cd095..6a1c52d 100644 --- a/net.md +++ b/net.md @@ -17,9 +17,9 @@ Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), `settings` can use the following `iface` strings: -- `carrier` ("0", "1"); -- `state` ("up", "down"); -- `sent` and `received` (numbers). +- `net_now.carrier` ("0", "1"); +- `net_now.state` ("up", "down"); +- `net_now.sent` and `net_now.received` (numbers). ### output From 79bbc9caa7aeb7b5b08fbd4373bcc0bdf2a52a04 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 15:26:46 -0700 Subject: [PATCH 308/546] Updated cpu (markdown) --- cpu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu.md b/cpu.md index ae490b0..e42180c 100644 --- a/cpu.md +++ b/cpu.md @@ -11,7 +11,7 @@ Variable | Meaning | Type | Default `timeout` | Refresh timeout seconds | int | 5 `settings` | User settings | function | empty function -`settings` can use the string `usage`, which is the cpu use percentage. +`settings` can use the string `cpu_now.usage`, which is the cpu use percentage. ### output From 9a5ae851b262c64a09427dd2ede66ac5dc615b5a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 15:27:04 -0700 Subject: [PATCH 309/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index e812db2..8395445 100644 --- a/Widgets.md +++ b/Widgets.md @@ -17,7 +17,7 @@ Here follows an example: mycpu = lain.widgets.cpu({ timeout = 4, settings = function() - widget:set_markup("Cpu " .. usage) + widget:set_markup("Cpu " .. cpu_now.usage) end }) From 68ac07505d347e227759e8b11046867e8cecc685 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 15:38:37 -0700 Subject: [PATCH 310/546] Updated alsabar (markdown) --- alsabar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsabar.md b/alsabar.md index 711c8ce..e50b5c7 100644 --- a/alsabar.md +++ b/alsabar.md @@ -47,7 +47,7 @@ It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height, Variable | Meaning | Type --- | --- | --- -`widget` | The widget | `awful.widget.progressbar` +`bar` | The widget | `awful.widget.progressbar` `channel` | Alsa channel | string `step` | Increase/decrease step | string `notify` | The notification | function From 5ba3a27a7112def5062d0afe23e7e0d34933d340 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 17:29:55 -0700 Subject: [PATCH 311/546] Updated temp (markdown) --- temp.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/temp.md b/temp.md index f7315b6..91f3031 100644 --- a/temp.md +++ b/temp.md @@ -1,16 +1,20 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -Show the current core temperature in a textbox. +Shows the current core temperature in a textbox. Reads from `/sys/class/thermal`, so value is expressed in Celsius. mytemp = lain.widgets.temp() -The function takes a table as optional argument, which can contain: +### input table Variable | Meaning | Type | Default --- | --- | --- | --- `timeout` | Refresh timeout seconds | int | 5 `settings` | User settings | function | empty function -`settings` can use the string `coretemp_now`, which means current core temperature, expressed in Celsius (linux standard). \ No newline at end of file +`settings` can use the string `coretemp_now`, which means current core temperature, expressed in Celsius (linux standard). + +### output + +A textbox. \ No newline at end of file From 4dfc4ac2784610bf6428266286e5257a3b88ca82 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 17:31:12 -0700 Subject: [PATCH 312/546] Updated sysload (markdown) --- sysload.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysload.md b/sysload.md index 4ed61a8..3e53881 100644 --- a/sysload.md +++ b/sysload.md @@ -1,6 +1,6 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -Show the current system load in a textbox. +Shows the current system load. mysysload = lain.widgets.sysload() From 4a345ff7de707d349abd4f354a243dd8fdc4ef3e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 17:32:07 -0700 Subject: [PATCH 313/546] Updated net (markdown) --- net.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net.md b/net.md index 6a1c52d..f857239 100644 --- a/net.md +++ b/net.md @@ -15,7 +15,7 @@ Variable | Meaning | Type | Default Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), and so on. -`settings` can use the following `iface` strings: +`settings` can use the following `iface` related strings: - `net_now.carrier` ("0", "1"); - `net_now.state` ("up", "down"); From 243b70e8f6f27c60b8672daf45e96383ea774c93 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 17:33:41 -0700 Subject: [PATCH 314/546] Updated mpd (markdown) --- mpd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index de945b4..8a25d04 100644 --- a/mpd.md +++ b/mpd.md @@ -48,7 +48,7 @@ and can modify `mpd_notification_preset` table, which will be the preset for the Variable | Meaning | Type --- | --- | --- `widget` | The textbox | `wibox.widget.textbox` -`notify` | The notification | function +`update` | The notification | function You can control the widget with key bindings like these: From 2f66e5ef68f96ecfa3bae1c2596dfbc963e3f207 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 17:34:20 -0700 Subject: [PATCH 315/546] Updated mem (markdown) --- mem.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mem.md b/mem.md index 1079ca5..ba37923 100644 --- a/mem.md +++ b/mem.md @@ -4,9 +4,7 @@ Shows memory status (in MiB) in a textbox. mymem = lain.widgets.mem() - -The function takes a table as an optional argument. That table may -contain: +# input table Variable | Meaning | Type | Default --- | --- | --- | --- From 2210465e215e263ecd4950dba6608461f82f0259 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 17:34:34 -0700 Subject: [PATCH 316/546] Updated mem (markdown) --- mem.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mem.md b/mem.md index ba37923..84b7ad2 100644 --- a/mem.md +++ b/mem.md @@ -4,7 +4,7 @@ Shows memory status (in MiB) in a textbox. mymem = lain.widgets.mem() -# input table +### input table Variable | Meaning | Type | Default --- | --- | --- | --- From f6b48b8e113cc353ae64c4418ccb29556dec2018 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 17:38:16 -0700 Subject: [PATCH 317/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index 5588ca7..e30c473 100644 --- a/fs.md +++ b/fs.md @@ -14,7 +14,7 @@ Variable | Meaning | Type | Default `partition` | Partition to monitor | string | "/" `settings` | User settings | function | empty function -`settings` can use the following `partition` related float values: `used` and `available`, `size_mb`, `size_gb`. +`settings` can use the following `partition` related float values: `used`, `available`, `size_mb`, `size_gb`. It can also use value strings in these formats: From e9831446b8a0f5de6497f05d0bbb9f930aaa5f3f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 12 Sep 2013 17:41:39 -0700 Subject: [PATCH 318/546] Updated alsabar (markdown) --- alsabar.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/alsabar.md b/alsabar.md index e50b5c7..6dea44f 100644 --- a/alsabar.md +++ b/alsabar.md @@ -40,8 +40,7 @@ Variable | Meaning | Type | Default `color` | Notifications color | string | `beautiful.fg_focus` `bar_size` | Wibox height | int | 18 -It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height, -**if** you have set it different than default (18). +It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height. ### output table From 8daba68e882e4e3c61b1cf3f2fc2a3e7c0806e20 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Fri, 13 Sep 2013 14:00:43 -0700 Subject: [PATCH 319/546] Updated alsabar (markdown) --- alsabar.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/alsabar.md b/alsabar.md index 6dea44f..f694c69 100644 --- a/alsabar.md +++ b/alsabar.md @@ -2,7 +2,7 @@ Shows and controls alsa volume with a progressbar; provides tooltips, notifications, and color changes at mute/unmute switch. - myvolumebar = lain.widgets.alsabar() + volume = lain.widgets.alsabar() * Left click: Launch `alsamixer` in your `terminal`. * Right click: Mute/unmute. @@ -53,26 +53,26 @@ Variable | Meaning | Type You can control the widget with key bindings like these: - -- Volume control + -- ALSA volume control awful.key({ altkey }, "Up", - function () - awful.util.spawn("amixer set " .. volume.channel .. " " .. volume.step .. "+") - myvolumebar.notify() - end), + function () + awful.util.spawn("amixer -q set " .. volume.channel .. " " .. volume.step .. "+") + volume.notify() + end), awful.key({ altkey }, "Down", - function () - awful.util.spawn("amixer set " .. volume.channel .. " " .. volume.step .. "-") - myvolumeba.notify() - end), + function () + awful.util.spawn("amixer -q set " .. volume.channel .. " " .. volume.step .. "-") + volume.notify() + end), awful.key({ altkey }, "m", - function () - awful.util.spawn("amixer set " .. volume.channel .. " playback toggle") - myvolumebar.notify() - end), - awful.key({ altkey, "Control" }, "m", - function () - awful.util.spawn("amixer set " .. volume.channel .. " playback 100%", false ) - myvolumebar.notify() - end), + function () + awful.util.spawn("amixer -q set " .. volume.channel .. " playback toggle") + volume.notify() + end), + awful.key({ altkey, "Control" }, "m", + function () + awful.util.spawn("amixer -q set " .. volume.channel .. " playback 100%") + volume.notify() + end), where `altkey = "Mod1"`. \ No newline at end of file From b57305092f05236e9730d63353f70c3e855faa11 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Fri, 13 Sep 2013 14:11:07 -0700 Subject: [PATCH 320/546] Updated Widgets (markdown) --- Widgets.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Widgets.md b/Widgets.md index 8395445..981e4e1 100644 --- a/Widgets.md +++ b/Widgets.md @@ -21,6 +21,8 @@ Here follows an example: end }) +If you want to see more complex applications, check [awesome-copycats](https://github.com/copycat-killer/awesome-copycats). + --- - [alsa](https://github.com/copycat-killer/lain/wiki/alsa) From 166bb8483762fe6aec5be4b515ccb00fc54be1a7 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Fri, 13 Sep 2013 15:04:30 -0700 Subject: [PATCH 321/546] Updated mpd (markdown) --- mpd.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mpd.md b/mpd.md index 8a25d04..70a7938 100644 --- a/mpd.md +++ b/mpd.md @@ -14,6 +14,12 @@ Now playing songs are notified like this: | +-------+ | +--------------------------------------------------------+ +You need a file like this + + "(front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$" + +in the album folder in order to show album art in the notification too. + ### input table Variable | Meaning | Type | Default @@ -23,6 +29,7 @@ Variable | Meaning | Type | Default `host` | MPD server | string | "127.0.0.1" `port` | MPD port | string | "6600" `music_dir` | Music directory | string | "~/Music" +`cover_size` | Album art notification size | int | 100 `settings` | User settings | function | empty function `settings` can use `mpd_now` table, which contains the following string values: From ff2cb368718fea80f5daffaea75ddcb5d7da18df Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Fri, 13 Sep 2013 15:05:37 -0700 Subject: [PATCH 322/546] Updated mpd (markdown) --- mpd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index 70a7938..62d6e4b 100644 --- a/mpd.md +++ b/mpd.md @@ -16,7 +16,7 @@ Now playing songs are notified like this: You need a file like this - "(front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$" + (front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$ in the album folder in order to show album art in the notification too. From ad6cdb2ad0f4b3f0fd9c2f0e50b9d5733f6d8b84 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Fri, 13 Sep 2013 15:05:58 -0700 Subject: [PATCH 323/546] Updated mpd (markdown) --- mpd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index 62d6e4b..44d7826 100644 --- a/mpd.md +++ b/mpd.md @@ -18,7 +18,7 @@ You need a file like this (front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$ -in the album folder in order to show album art in the notification too. +in the album folder in order to show album art too. ### input table From 8d893392caf98f5e03f34dcb47d37f66fa0f72dd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Fri, 13 Sep 2013 15:06:13 -0700 Subject: [PATCH 324/546] Updated mpd (markdown) --- mpd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index 44d7826..7db0498 100644 --- a/mpd.md +++ b/mpd.md @@ -16,7 +16,7 @@ Now playing songs are notified like this: You need a file like this - (front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif)$ + (front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif) in the album folder in order to show album art too. From 608d570a06d737969c944e5da3d000a723d21d0d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 14 Sep 2013 08:11:13 -0700 Subject: [PATCH 325/546] Updated Layouts (markdown) --- Layouts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Layouts.md b/Layouts.md index 7c4ff41..07184a4 100644 --- a/Layouts.md +++ b/Layouts.md @@ -247,7 +247,7 @@ you have to add an item called `useless_gap_width` in your `theme.lua`. If it doesn't exist, the width will default to 0. Example: - theme.useless_gap_width = "5" + theme.useless_gap_width = 5 What about layout icons? ======================== From b7fc82e99133ee9af2bdebcdc36e3eb178d9da47 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 17 Sep 2013 15:14:40 -0700 Subject: [PATCH 326/546] Updated Home (markdown) --- Home.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Home.md b/Home.md index 6b7b58d..63ede55 100644 --- a/Home.md +++ b/Home.md @@ -8,6 +8,8 @@ alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar] curl | widget types accessing network resources imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) +*(Why ImageMagick? Because Cairo doesn't do high quality filtering at the moment)* + ### Installation Simply clone this repository into your Awesome directory: From 079729b357a14fdf40356dbbb66180bf237db1d5 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 17 Sep 2013 15:15:07 -0700 Subject: [PATCH 327/546] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 63ede55..78f40c6 100644 --- a/Home.md +++ b/Home.md @@ -8,7 +8,7 @@ alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar] curl | widget types accessing network resources imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) -*(Why ImageMagick? Because Cairo doesn't do high quality filtering at the moment)* +*(Why ImageMagick? Because Cairo doesn't do high quality filtering at the moment.)* ### Installation From 2d01d70e6be41351df903ec6afd2d709b35f80bd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 17 Sep 2013 15:26:32 -0700 Subject: [PATCH 328/546] Updated mpd (markdown) --- mpd.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index 7db0498..0e2eca5 100644 --- a/mpd.md +++ b/mpd.md @@ -16,7 +16,7 @@ Now playing songs are notified like this: You need a file like this - (front|cover|art|Folder|folder)\.(jpg|jpeg|png|gif) + (Front|front|Cover|cover|Art|art|Folder|folder)\.(jpg|jpeg|png|gif) in the album folder in order to show album art too. @@ -30,6 +30,7 @@ Variable | Meaning | Type | Default `port` | MPD port | string | "6600" `music_dir` | Music directory | string | "~/Music" `cover_size` | Album art notification size | int | 100 +`default_art` | Default art | string | "" `settings` | User settings | function | empty function `settings` can use `mpd_now` table, which contains the following string values: From 2baa09b17dcf29bd8901b79b3e4fea461186b01c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 18 Sep 2013 06:53:48 -0700 Subject: [PATCH 329/546] Updated Utilities (markdown) --- Utilities.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Utilities.md b/Utilities.md index 6afff16..de9f56b 100644 --- a/Utilities.md +++ b/Utilities.md @@ -127,4 +127,27 @@ You can use it with a key binding like this: awful.key({ modkey, "Shift" }, "r", function () lain.util.prompt_rename_tag(mypromptbox) end) -Credits goes to [minism](https://bbs.archlinux.org/viewtopic.php?pid=1315135#p1315135). \ No newline at end of file +Credits goes to [minism](https://bbs.archlinux.org/viewtopic.php?pid=1315135#p1315135). + +useless\_gaps\_resize +--------------------- + +Changes `beautiful.useless_gaps_width` on the fly, if present. + +The function takes an integer argument, being the amount of pixel to add/remove to gaps. + +You could use it with these keybindings: + + -- On the fly useless gaps change + awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end), + awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end), + +where `altkey=Mod1`, or you could use it as a button like this: + + mywidget:buttons(awful.util.table.join ( + awful.button({}, 4, function() lain.util.useless_gaps_resize(-1) end), + awful.button({}, 5, function() lain.util.useless_gaps_resize(1) end) + end) + )) + +so when hovering the mouse over `mywidget`, you can adjust useless gaps size by scrolling with the mouse wheel. \ No newline at end of file From d41db5f1e83669bbceb901ce4c2b19b9200f1850 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 18 Sep 2013 06:54:08 -0700 Subject: [PATCH 330/546] Updated Utilities (markdown) --- Utilities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utilities.md b/Utilities.md index de9f56b..3f00c35 100644 --- a/Utilities.md +++ b/Utilities.md @@ -132,7 +132,7 @@ Credits goes to [minism](https://bbs.archlinux.org/viewtopic.php?pid=1315135#p13 useless\_gaps\_resize --------------------- -Changes `beautiful.useless_gaps_width` on the fly, if present. +Changes `beautiful.useless_gaps_width` on the fly. The function takes an integer argument, being the amount of pixel to add/remove to gaps. From cefb2277aae1533ebc9c2952cfe8203d28ac65ea Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 18 Sep 2013 06:55:03 -0700 Subject: [PATCH 331/546] Updated Utilities (markdown) --- Utilities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Utilities.md b/Utilities.md index 3f00c35..a5c29ac 100644 --- a/Utilities.md +++ b/Utilities.md @@ -142,7 +142,7 @@ You could use it with these keybindings: awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end), awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end), -where `altkey=Mod1`, or you could use it as a button like this: +where `altkey=Mod1`, or you could use it like this: mywidget:buttons(awful.util.table.join ( awful.button({}, 4, function() lain.util.useless_gaps_resize(-1) end), From dbbfc11c20718a09f409f2f9144a0ffdf04c5da4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 18 Sep 2013 07:55:30 -0700 Subject: [PATCH 332/546] Updated Utilities (markdown) --- Utilities.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Utilities.md b/Utilities.md index a5c29ac..3797f3c 100644 --- a/Utilities.md +++ b/Utilities.md @@ -70,8 +70,7 @@ the currently used layout. Use it with a client keybinding like this: ... ) -If you want to "de-magnify" it, just reset the clients floating state to -`false` (hit `Mod4`+`CTRL`+`Space`, for example). +If you want to "de-magnify" it, just retype the keybinding. niceborder\_{focus, unfocus} ---------------------------- From d27ebe2f1f746b62cd4a6b6dc8c423c50e2aa9e8 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 05:01:28 -0700 Subject: [PATCH 333/546] Updated Home (markdown) --- Home.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Home.md b/Home.md index 78f40c6..aad783f 100644 --- a/Home.md +++ b/Home.md @@ -2,11 +2,11 @@ Welcome to the Lain wiki! ### Dependencies -Package | Requested by ---- | --- -alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) -curl | widget types accessing network resources -imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) +Package | Requested by | Reason +--- | --- | --- +alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / +curl | widgets accessing network resources | Lua socket is not a core library. +imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) | Cairo doesn't do high quality filtering. *(Why ImageMagick? Because Cairo doesn't do high quality filtering at the moment.)* From 0d696b5f0634eb30d77eea8f08633e7a3390e210 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 05:02:06 -0700 Subject: [PATCH 334/546] Updated Home (markdown) --- Home.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Home.md b/Home.md index aad783f..5afbc2c 100644 --- a/Home.md +++ b/Home.md @@ -2,9 +2,9 @@ Welcome to the Lain wiki! ### Dependencies -Package | Requested by | Reason +Package | Requested by | Reason of choice --- | --- | --- -alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / +alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / curl | widgets accessing network resources | Lua socket is not a core library. imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) | Cairo doesn't do high quality filtering. From 8c8ebdc1580f239cca3eb9f03b91cef8d321be34 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 05:04:08 -0700 Subject: [PATCH 335/546] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 5afbc2c..bc479c0 100644 --- a/Home.md +++ b/Home.md @@ -5,7 +5,7 @@ Welcome to the Lain wiki! Package | Requested by | Reason of choice --- | --- | --- alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / -curl | widgets accessing network resources | Lua socket is not a core library. +curl | widgets accessing network resources | LuaSocket is not a core library. LuaSSL is out of date. imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) | Cairo doesn't do high quality filtering. *(Why ImageMagick? Because Cairo doesn't do high quality filtering at the moment.)* From c061737f1f08d79826bcdc116a26806339193dea Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 06:24:58 -0700 Subject: [PATCH 336/546] Updated borderbox (markdown) --- borderbox.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/borderbox.md b/borderbox.md index e4d7afb..5ac0b04 100644 --- a/borderbox.md +++ b/borderbox.md @@ -40,7 +40,7 @@ adds a borderbox on top of them: ... -- Most likely, you'll want to do this as well: - awful.screen.padding(screen[s], { bottom = 1 }) + awful.screen.padding(screen[s], "bottom") -- Create the box and place it above the existing box. lain.widgets.borderbox(mywibox[s], s, { position = "above" } ) From b09852a054c4bf87566a8d4a9f351a7b8bf22c4a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 06:27:57 -0700 Subject: [PATCH 337/546] Updated borderbox (markdown) --- borderbox.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/borderbox.md b/borderbox.md index 5ac0b04..9fd138c 100644 --- a/borderbox.md +++ b/borderbox.md @@ -15,7 +15,7 @@ Variable | Meaning | Type | Default `color` | Color of the additional box | string | `#FFFFFF` `size` | Size in pixels of the additional box | int | 1 -Possible values for `.position`: `above`, `below`, `left` and `right`. +Possible values for `.position`: `top`, `bottom`, `left` and `right`. ### Example usage From f5bab9a7c7ef3ab37fd996e225a0e6691e7da0c5 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 06:55:39 -0700 Subject: [PATCH 338/546] Updated borderbox (markdown) --- borderbox.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/borderbox.md b/borderbox.md index 9fd138c..a56026a 100644 --- a/borderbox.md +++ b/borderbox.md @@ -43,7 +43,7 @@ adds a borderbox on top of them: awful.screen.padding(screen[s], "bottom") -- Create the box and place it above the existing box. - lain.widgets.borderbox(mywibox[s], s, { position = "above" } ) + lain.widgets.borderbox(mywibox[s], s ) ... end \ No newline at end of file From 96845ff43bad00e2826259a0473a9a36052166ab Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 11:27:46 -0700 Subject: [PATCH 339/546] Updated Home (markdown) --- Home.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/Home.md b/Home.md index bc479c0..a7bee69 100644 --- a/Home.md +++ b/Home.md @@ -8,8 +8,6 @@ alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar] curl | widgets accessing network resources | LuaSocket is not a core library. LuaSSL is out of date. imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) | Cairo doesn't do high quality filtering. -*(Why ImageMagick? Because Cairo doesn't do high quality filtering at the moment.)* - ### Installation Simply clone this repository into your Awesome directory: From 475ba083c9904a229efe53ea1965e27a5552fa1f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 12:06:19 -0700 Subject: [PATCH 340/546] Updated Utilities (markdown) --- Utilities.md | 112 +++++++++++++++++++++++++++------------------------ 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/Utilities.md b/Utilities.md index 3797f3c..3ab9245 100644 --- a/Utilities.md +++ b/Utilities.md @@ -43,6 +43,64 @@ they all take one argument, which is the text to markup, except `fg.color` and ` markup.fg.color(text, color) markup.bg.color(text, color) +dynamic tagging +--------------- + +That is: + +- create a new tag; +- rename current tag; +- delete current tag. + +If you delete a tag, any rule set on it shall be broken, so be careful. + +Use it with key bindings like these: + + awful.key({ modkey, "Shift" }, "n", function () lain.util.create_tag(mypromptbox) end), + awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag(mypromptbox) end), + awful.key({ modkey, "Shift" }, "d", function () lain.util.delete_tag() end), + +useless\_gaps\_resize +--------------------- + +Changes `beautiful.useless_gaps_width` on the fly. + +The function takes an integer argument, being the amount of pixel to add/remove to gaps. + +You could use it with these keybindings: + + -- On the fly useless gaps change + awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end), + awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end), + +where `altkey=Mod1`, or you could use it like this: + + mywidget:buttons(awful.util.table.join ( + awful.button({}, 4, function() lain.util.useless_gaps_resize(-1) end), + awful.button({}, 5, function() lain.util.useless_gaps_resize(1) end) + end) + )) + +so when hovering the mouse over `mywidget`, you can adjust useless gaps size by scrolling with the mouse wheel. + +tag\_view\_nonempty +------------------- + +This function lets you jump to the next/previous non-empty tag. +It takes two arguments: + +* `direction`: `1` for next non-empty tag, `-1` for previous. +* `sc`: Screen which the taglist is in. Default is `mouse.screen` or `1`. This + argument is optional. + +You can use it with key bindings like these: + + -- Non-empty tag browsing + awful.key({ altkey }, "Left", function () lain.util.tag_view_nonempty(-1) end), + awful.key({ altkey }, "Right", function () lain.util.tag_view_nonempty(1) end), + +where `altkey = "Mod1"`. + menu\_clients\_current\_tags ---------------------------- @@ -97,56 +155,4 @@ This requires to define additional colors in your `theme.lua`. For example: theme.border_normal_highprio = "#A03333" theme.border_focus_lowprio = "#3333FF" - theme.border_normal_lowprio = "#333366" - -tag\_view\_nonempty -------------------- - -This function lets you jump to the next/previous non-empty tag. -It takes two arguments: - -* `direction`: `1` for next non-empty tag, `-1` for previous. -* `sc`: Screen which the taglist is in. Default is `mouse.screen` or `1`. This - argument is optional. - -You can use it with key bindings like these: - - -- Non-empty tag browsing - awful.key({ altkey }, "Left", function () lain.util.tag_view_nonempty(-1) end), - awful.key({ altkey }, "Right", function () lain.util.tag_view_nonempty(1) end), - -where `altkey = "Mod1"`. - -prompt\_rename\_tag -------------------- - -This function enables you to dynamically rename the current tag you have focused. - -You can use it with a key binding like this: - - awful.key({ modkey, "Shift" }, "r", function () lain.util.prompt_rename_tag(mypromptbox) end) - -Credits goes to [minism](https://bbs.archlinux.org/viewtopic.php?pid=1315135#p1315135). - -useless\_gaps\_resize ---------------------- - -Changes `beautiful.useless_gaps_width` on the fly. - -The function takes an integer argument, being the amount of pixel to add/remove to gaps. - -You could use it with these keybindings: - - -- On the fly useless gaps change - awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end), - awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end), - -where `altkey=Mod1`, or you could use it like this: - - mywidget:buttons(awful.util.table.join ( - awful.button({}, 4, function() lain.util.useless_gaps_resize(-1) end), - awful.button({}, 5, function() lain.util.useless_gaps_resize(1) end) - end) - )) - -so when hovering the mouse over `mywidget`, you can adjust useless gaps size by scrolling with the mouse wheel. \ No newline at end of file + theme.border_normal_lowprio = "#333366" \ No newline at end of file From f02dc38bf93fc64322c808d749a56cb292556698 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 16:49:45 -0700 Subject: [PATCH 341/546] Updated alsabar (markdown) --- alsabar.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/alsabar.md b/alsabar.md index f694c69..39506b0 100644 --- a/alsabar.md +++ b/alsabar.md @@ -13,6 +13,7 @@ The function takes a table as optional argument, which can contain: Variable | Meaning | Type | Default --- | --- | --- | --- `timeout` | Refresh timeout seconds | int | 4 +`settings` | User settings | function | empty function `width` | Bar width | int | 63 `height` | Bar height | int | 1 `ticks` | Set bar ticks on | boolean | true @@ -42,6 +43,8 @@ Variable | Meaning | Type | Default It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height. +`settings` can use the integer `alsa_level` and `alsa_status`. + ### output table Variable | Meaning | Type From e41f4ab4f999bb15d72c509a1a603f5994b2ffd0 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 16:54:37 -0700 Subject: [PATCH 342/546] Updated alsabar (markdown) --- alsabar.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/alsabar.md b/alsabar.md index 39506b0..31a7b23 100644 --- a/alsabar.md +++ b/alsabar.md @@ -43,8 +43,12 @@ Variable | Meaning | Type | Default It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height. -`settings` can use the integer `alsa_level` and `alsa_status`. +`settings` can use the following variables: +Variable | Meaning | Type | Values +--- | --- | --- | --- +`volume_now.level` | Self explained | int | 0-100 +`volume_now.status` | Device status | string | "on", "off" ### output table Variable | Meaning | Type From a60ba4b36cc1c98c9f6988b4543e9185a95ae771 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 19 Sep 2013 18:05:20 -0700 Subject: [PATCH 343/546] Updated alsabar (markdown) --- alsabar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsabar.md b/alsabar.md index 31a7b23..fa5f209 100644 --- a/alsabar.md +++ b/alsabar.md @@ -38,7 +38,7 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `font` | Notifications font | string | The one defined in `beautiful.font` `font_size` | Notifications font size | string | "11" -`color` | Notifications color | string | `beautiful.fg_focus` +`color` | Notifications color | string | `beautiful.fg_normal` `bar_size` | Wibox height | int | 18 It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height. From 5bcffd21a3a80b7f36c4dd4fcdec3bcc64192790 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 24 Sep 2013 09:15:38 -0700 Subject: [PATCH 344/546] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index a7bee69..e8271f3 100644 --- a/Home.md +++ b/Home.md @@ -6,7 +6,7 @@ Package | Requested by | Reason of choice --- | --- | --- alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / curl | widgets accessing network resources | LuaSocket is not a core library. LuaSSL is out of date. -imagemagick | [mpd](https://github.com/copycat-killer/lain/wiki/mpd) | Cairo doesn't do high quality filtering. +imagemagick | album arts in [mpd](https://github.com/copycat-killer/lain/wiki/mpd) notifications | Cairo doesn't do high quality filtering. ### Installation From fdbbac8d7d23a020fe16220343869f7052bec97f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 25 Sep 2013 03:30:55 -0700 Subject: [PATCH 345/546] Updated Home (markdown) --- Home.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Home.md b/Home.md index e8271f3..6cdae23 100644 --- a/Home.md +++ b/Home.md @@ -1,6 +1,7 @@ Welcome to the Lain wiki! -### Dependencies +Dependencies +------------------ Package | Requested by | Reason of choice --- | --- | --- @@ -8,17 +9,25 @@ alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar] curl | widgets accessing network resources | LuaSocket is not a core library. LuaSSL is out of date. imagemagick | album arts in [mpd](https://github.com/copycat-killer/lain/wiki/mpd) notifications | Cairo doesn't do high quality filtering. -### Installation +Installation +--------------- -Simply clone this repository into your Awesome directory: +### Arch Linux + +[AUR package](https://aur.archlinux.org/packages/lain/) + +### Other distributions git clone https://github.com/copycat-killer/lain.git ~/.config/awesome/lain -then include it in your `rc.lua`: +Usage +-------- + +First, include it in your `rc.lua`: local lain = require("lain") -### Submodules +Then check out the submodules you want: - [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts) - [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets) From 24545e46b78c1f48c47882c963cdddce670c3bb4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 25 Sep 2013 06:05:56 -0700 Subject: [PATCH 346/546] Created task (markdown) --- task.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 task.md diff --git a/task.md b/task.md new file mode 100644 index 0000000..8c68ac0 --- /dev/null +++ b/task.md @@ -0,0 +1,30 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Attaches a [taskwarrior](http://taskwarrior.org/projects/show/taskwarrior) notification to a widget, and lets to add/search tasks from the promptbox. + + lain.widgets.contrib.task:attach(widget, args) + +`args` is an optional table which can contain: + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`font_size` | Calendar font size | int | 12 +`fg` | Calendar foreground color | string | `beautiful.fg_normal` +`bg` | Calendar background color | string | `beautiful.bg_normal` +`position` | Calendar position | string | "top_right" +`timeout` | Notification timeout seconds | int | 7 + +`position` possible values are defined [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify). + +Notification will show the output of `task` command. + +You can call the notification with a key binding like this: + + awful.key({ modkey, altkey }, "t", lain.widgets.task.show), + +where ``altkey = "Mod1"``. + +And you can prompt to add/search a task with key bindings like these: + + awful.key({ modkey, }, "t", lain.widgets.contrib.task.prompt_add), + awful.key({ modkey, "Shift" }, "t", lain.widgets.contrib.task.prompt_search), \ No newline at end of file From 17acc050982d7912cd13d3018b4bc7a6c411dea6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 25 Sep 2013 06:06:11 -0700 Subject: [PATCH 347/546] Updated Widgets (markdown) --- Widgets.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Widgets.md b/Widgets.md index 981e4e1..b534f15 100644 --- a/Widgets.md +++ b/Widgets.md @@ -1,3 +1,6 @@ +General usage +------------- + Every widget is output by a `function`. For some widgets, `function` returns a `wibox.widget.textbox`, for others a table to be used for notification and update purposes. @@ -23,7 +26,8 @@ Here follows an example: If you want to see more complex applications, check [awesome-copycats](https://github.com/copycat-killer/awesome-copycats). ---- +Index +----- - [alsa](https://github.com/copycat-killer/lain/wiki/alsa) - [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) @@ -39,4 +43,9 @@ If you want to see more complex applications, check [awesome-copycats](https://g - [net](https://github.com/copycat-killer/lain/wiki/net) - [sysload](https://github.com/copycat-killer/lain/wiki/sysload) - [temp](https://github.com/copycat-killer/lain/wiki/temp) -- [yawn](https://github.com/copycat-killer/lain/wiki/yawn) \ No newline at end of file +- [yawn](https://github.com/copycat-killer/lain/wiki/yawn) + +User contributed widgets +------------------------ + +- [task](https://github.com/copycat-killer/lain/wiki/task) \ No newline at end of file From 1f4363dbfe3ec61368636a7e65f7eb1ff6c44842 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 25 Sep 2013 06:06:43 -0700 Subject: [PATCH 348/546] Updated Widgets (markdown) --- Widgets.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Widgets.md b/Widgets.md index b534f15..acb7075 100644 --- a/Widgets.md +++ b/Widgets.md @@ -45,7 +45,7 @@ Index - [temp](https://github.com/copycat-killer/lain/wiki/temp) - [yawn](https://github.com/copycat-killer/lain/wiki/yawn) -User contributed widgets ------------------------- +User contributed +---------------- - [task](https://github.com/copycat-killer/lain/wiki/task) \ No newline at end of file From a83256cdfe2f7f2fca8956f3d3e6edd84fe31416 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 25 Sep 2013 06:10:33 -0700 Subject: [PATCH 349/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index acb7075..ebe0810 100644 --- a/Widgets.md +++ b/Widgets.md @@ -45,7 +45,7 @@ Index - [temp](https://github.com/copycat-killer/lain/wiki/temp) - [yawn](https://github.com/copycat-killer/lain/wiki/yawn) -User contributed +Users contributed ---------------- - [task](https://github.com/copycat-killer/lain/wiki/task) \ No newline at end of file From d0d7d3df3509745924fd028edaa79e5f40c6473d Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 25 Sep 2013 08:02:02 -0700 Subject: [PATCH 350/546] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 6cdae23..9ba8362 100644 --- a/Home.md +++ b/Home.md @@ -23,7 +23,7 @@ Installation Usage -------- -First, include it in your `rc.lua`: +First, include it into your `rc.lua`: local lain = require("lain") From 5c39389704c25aa1958fb767d13b84f5b1f4073e Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 26 Sep 2013 02:51:15 -0700 Subject: [PATCH 351/546] Created tpbat (markdown) --- tpbat.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tpbat.md diff --git a/tpbat.md b/tpbat.md new file mode 100644 index 0000000..38c30c9 --- /dev/null +++ b/tpbat.md @@ -0,0 +1,5 @@ +A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi. Includes hover notification with more details. + + tpbatwidget = lain.widgets.contrib.tpbat() + +Configuration is identical to [main bat widget's](https://github.com/copycat-killer/lain/wiki/bat). \ No newline at end of file From f06fe30aca3d05d84831c7115c629f7eacd5a6d5 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 26 Sep 2013 02:51:28 -0700 Subject: [PATCH 352/546] Updated tpbat (markdown) --- tpbat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpbat.md b/tpbat.md index 38c30c9..cb21a6b 100644 --- a/tpbat.md +++ b/tpbat.md @@ -1,4 +1,4 @@ -A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi. Includes hover notification with more details. +A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi). Includes hover notification with more details. tpbatwidget = lain.widgets.contrib.tpbat() From b811df55fa96a03e33585cb7e5bc21e43e65eb24 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 26 Sep 2013 02:51:39 -0700 Subject: [PATCH 353/546] Updated tpbat (markdown) --- tpbat.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tpbat.md b/tpbat.md index cb21a6b..7eebc79 100644 --- a/tpbat.md +++ b/tpbat.md @@ -1,4 +1,6 @@ -A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi). Includes hover notification with more details. +A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi). + +Includes hover notification with more details. tpbatwidget = lain.widgets.contrib.tpbat() From 6a1351e68770ac118d976729be0d03e2f42eeded Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 26 Sep 2013 02:51:59 -0700 Subject: [PATCH 354/546] Updated tpbat (markdown) --- tpbat.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tpbat.md b/tpbat.md index 7eebc79..3d0b0e8 100644 --- a/tpbat.md +++ b/tpbat.md @@ -1,3 +1,5 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi). Includes hover notification with more details. From 7b9e9b8b67d7d50112d66ff4bfb2bb1f22dff6db Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 26 Sep 2013 02:52:49 -0700 Subject: [PATCH 355/546] Updated Widgets (markdown) --- Widgets.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index ebe0810..8a8945b 100644 --- a/Widgets.md +++ b/Widgets.md @@ -48,4 +48,5 @@ Index Users contributed ---------------- -- [task](https://github.com/copycat-killer/lain/wiki/task) \ No newline at end of file +- [task](https://github.com/copycat-killer/lain/wiki/task) +- [tpbat](https://github.com/copycat-killer/lain/wiki/tpbat) \ No newline at end of file From 261ecbd1cad4a325567f13e3b8aade58c211cab5 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sat, 28 Sep 2013 04:04:24 -0700 Subject: [PATCH 356/546] Updated Utilities (markdown) --- Utilities.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Utilities.md b/Utilities.md index 3ab9245..84fe3fa 100644 --- a/Utilities.md +++ b/Utilities.md @@ -50,6 +50,7 @@ That is: - create a new tag; - rename current tag; +- move current tag; - delete current tag. If you delete a tag, any rule set on it shall be broken, so be careful. @@ -58,6 +59,8 @@ Use it with key bindings like these: awful.key({ modkey, "Shift" }, "n", function () lain.util.create_tag(mypromptbox) end), awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag(mypromptbox) end), + awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(1) end), -- move next tag + awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(-1) end), -- move prev tag awful.key({ modkey, "Shift" }, "d", function () lain.util.delete_tag() end), useless\_gaps\_resize From b46ced57bc9d62ed7956859bcd3eb82ba8156ea4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Wed, 2 Oct 2013 07:14:45 -0700 Subject: [PATCH 357/546] Updated fs (markdown) --- fs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs.md b/fs.md index e30c473..1e34f86 100644 --- a/fs.md +++ b/fs.md @@ -14,7 +14,7 @@ Variable | Meaning | Type | Default `partition` | Partition to monitor | string | "/" `settings` | User settings | function | empty function -`settings` can use the following `partition` related float values: `used`, `available`, `size_mb`, `size_gb`. +`settings` can use the following `partition` related float values: `fs_now.used`, `fs_now.available`, `fs_now.size_mb`, `fs_now.size_gb`. It can also use value strings in these formats: From 273c23825d549d6f245fe6cc5148270f39992718 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Fri, 4 Oct 2013 06:19:52 -0700 Subject: [PATCH 358/546] Updated Layouts (markdown) --- Layouts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Layouts.md b/Layouts.md index 07184a4..d53b945 100644 --- a/Layouts.md +++ b/Layouts.md @@ -247,7 +247,7 @@ you have to add an item called `useless_gap_width` in your `theme.lua`. If it doesn't exist, the width will default to 0. Example: - theme.useless_gap_width = 5 + theme.useless_gap_width = 10 What about layout icons? ======================== From 5e5f195c9a9d38b80201eef4fa049f32b57c3d2b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Fri, 4 Oct 2013 09:51:14 -0700 Subject: [PATCH 359/546] Updated Layouts (markdown) --- Layouts.md | 114 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 43 deletions(-) diff --git a/Layouts.md b/Layouts.md index d53b945..fc302d4 100644 --- a/Layouts.md +++ b/Layouts.md @@ -1,11 +1,12 @@ -Currently, there are **7** layouts. +Currently, there are **8** layouts. lain/layout . + |-- termfair + |-- centerfair |-- cascade |-- cascadetile |-- centerwork - |-- termfair |-- uselessfair |-- uselesspiral `-- uselesstile @@ -27,6 +28,74 @@ Or set them on specific tags like this: How do layouts work? ========================= +termfair +-------- + +I do a lot of work on terminals. The common tiling algorithms usually +maximize windows, so you'll end up with a terminal that has about 200 +columns or more. That's way too much. Have you ever read a manpage in a +terminal of this size? + +This layout restricts the size of each window. Each window will have the +same width but is variable in height. Furthermore, windows are +left-aligned. The basic workflow is as follows (the number above the +screen is the number of open windows, the number in a cell is the fixed +number of a client): + + (1) (2) (3) + +---+---+---+ +---+---+---+ +---+---+---+ + | | | | | | | | | | | | + | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> + | | | | | | | | | | | | + +---+---+---+ +---+---+---+ +---+---+---+ + + (4) (5) (6) + +---+---+---+ +---+---+---+ +---+---+---+ + | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | + +---+---+---+ -> +---+---+---+ -> +---+---+---+ + | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | + +---+---+---+ +---+---+---+ +---+---+---+ + +The first client will be located in the left column. When opening +another window, this new window will be placed in the left column while +moving the first window into the middle column. Once a row is full, +another row above it will be created. + +Default number of columns and rows are respectively taken from `nmaster` +and `ncol` values in `awful.tag`, but you can set your own. + +For example, this sets `termfair` to 3 columns and at least 1 row: + + lain.layout.termfair.nmaster = 3 + lain.layout.termfair.ncol = 1 + +centerfair +---------- + +Similar to `termfair`, but with fixed number of vertical columns. Cols are centerded until there is nmaster columns, then windows are stacked in the slave columns, with at most ncol clients per column if possible. + + (1) (2) (3) + +---+---+---+ +-+---+---+-+ +---+---+---+ + | | | | | | | | | | | | | + | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | -> + | | | | | | | | | | | | | + +---+---+---+ +-+---+---+-+ +---+---+---+ + + (4) (5) + +---+---+---+ +---+---+---+ + | | | 3 | | | 2 | 4 | + + 1 + 2 +---+ -> + 1 +---+---+ + | | | 4 | | | 3 | 5 | + +---+---+---+ +---+---+---+ + +Like `termfair`, default number of columns and rows are respectively taken from `nmaster` +and `ncol` values in `awful.tag`, but you can set your own. + +For example: + + lain.layout.centerfair.nmaster = 3 + lain.layout.centerfair.ncol = 1 + cascade ------- @@ -174,47 +243,6 @@ Here's an example: ... ) -termfair --------- - -I do a lot of work on terminals. The common tiling algorithms usually -maximize windows, so you'll end up with a terminal that has about 200 -columns or more. That's way too much. Have you ever read a manpage in a -terminal of this size? - -This layout restricts the size of each window. Each window will have the -same width but is variable in height. Furthermore, windows are -left-aligned. The basic workflow is as follows (the number above the -screen is the number of open windows, the number in a cell is the fixed -number of a client): - - (1) (2) (3) - +---+---+---+ +---+---+---+ +---+---+---+ - | | | | | | | | | | | | - | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> - | | | | | | | | | | | | - +---+---+---+ +---+---+---+ +---+---+---+ - - (4) (5) (6) - +---+---+---+ +---+---+---+ +---+---+---+ - | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | - +---+---+---+ -> +---+---+---+ -> +---+---+---+ - | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | - +---+---+---+ +---+---+---+ +---+---+---+ - -The first client will be located in the left column. When opening -another window, this new window will be placed in the left column while -moving the first window into the middle column. Once a row is full, -another row above it will be created. - -Default number of columns and rows are respectively taken from `nmaster` -and `ncol` values in `awful.tag`, but you can set your own. - -For example, this sets `termfair` to 3 columns and at least 1 row: - - lain.layout.termfair.nmaster = 3 - lain.layout.termfair.ncol = 1 - uselessfair, uselesspiral & uselesstile --------------------------------------- These are duplicates of the stock `fair`, `spiral` and `tile` layouts. From a0fa709f342889efa4bae8d8ddefff2141d2cd8f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 6 Oct 2013 15:49:20 -0700 Subject: [PATCH 360/546] Updated Layouts (markdown) --- Layouts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Layouts.md b/Layouts.md index fc302d4..1ddca95 100644 --- a/Layouts.md +++ b/Layouts.md @@ -72,7 +72,7 @@ For example, this sets `termfair` to 3 columns and at least 1 row: centerfair ---------- -Similar to `termfair`, but with fixed number of vertical columns. Cols are centerded until there is nmaster columns, then windows are stacked in the slave columns, with at most ncol clients per column if possible. +Similar to `termfair`, but with fixed number of vertical columns. Cols are centerded until there are `nmaster` columns, then windows are stacked as slaves, with possibly `ncol` clients per column at most. (1) (2) (3) +---+---+---+ +-+---+---+-+ +---+---+---+ From 9755a7438468651e4a2cd04b0724e322fa6479c6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 12 Nov 2013 01:38:47 -0800 Subject: [PATCH 361/546] Updated task (markdown) --- task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/task.md b/task.md index 8c68ac0..b4bc7f0 100644 --- a/task.md +++ b/task.md @@ -20,7 +20,7 @@ Notification will show the output of `task` command. You can call the notification with a key binding like this: - awful.key({ modkey, altkey }, "t", lain.widgets.task.show), + awful.key({ modkey, altkey }, "t", lain.widgets.contrib.task.show), where ``altkey = "Mod1"``. From 4a89b573af93e1753e9fdeb279cfd7c7fb95675f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 12 Nov 2013 01:38:54 -0800 Subject: [PATCH 362/546] Updated Utilities (markdown) --- Utilities.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Utilities.md b/Utilities.md index 84fe3fa..0e58304 100644 --- a/Utilities.md +++ b/Utilities.md @@ -48,20 +48,20 @@ dynamic tagging That is: -- create a new tag; +- add a new tag; - rename current tag; - move current tag; -- delete current tag. +- remove current tag. If you delete a tag, any rule set on it shall be broken, so be careful. Use it with key bindings like these: - awful.key({ modkey, "Shift" }, "n", function () lain.util.create_tag(mypromptbox) end), + awful.key({ modkey, "Shift" }, "n", function () lain.util.add_tag(mypromptbox) end), awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag(mypromptbox) end), awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(1) end), -- move next tag - awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(-1) end), -- move prev tag - awful.key({ modkey, "Shift" }, "d", function () lain.util.delete_tag() end), + awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(-1) end), -- move previous tag + awful.key({ modkey, "Shift" }, "d", function () lain.util.remove_tag() end), useless\_gaps\_resize --------------------- From a46fca6d03bcb76569f42a67a98c087380730e7c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 12 Nov 2013 01:39:52 -0800 Subject: [PATCH 363/546] Updated Utilities (markdown) --- Utilities.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Utilities.md b/Utilities.md index 0e58304..e4f114a 100644 --- a/Utilities.md +++ b/Utilities.md @@ -59,8 +59,8 @@ Use it with key bindings like these: awful.key({ modkey, "Shift" }, "n", function () lain.util.add_tag(mypromptbox) end), awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag(mypromptbox) end), - awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(1) end), -- move next tag - awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(-1) end), -- move previous tag + awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(1) end), -- move to next tag + awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(-1) end), -- move to previous tag awful.key({ modkey, "Shift" }, "d", function () lain.util.remove_tag() end), useless\_gaps\_resize From 69dcc0eb29f42ec0a289a9e023fee3a89aacb068 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 12 Nov 2013 01:50:52 -0800 Subject: [PATCH 364/546] Updated Utilities (markdown) --- Utilities.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Utilities.md b/Utilities.md index e4f114a..2171503 100644 --- a/Utilities.md +++ b/Utilities.md @@ -63,6 +63,8 @@ Use it with key bindings like these: awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(-1) end), -- move to previous tag awful.key({ modkey, "Shift" }, "d", function () lain.util.remove_tag() end), +**Note** that these function won't work properly with [Copland theme](https://github.com/copycat-killer/awesome-copycats) or any other configuration that already uses a dynamic tagging module like [Eminent](https://github.com/copycat-killer/awesome-copycats/tree/master/eminent). + useless\_gaps\_resize --------------------- From 6e6914aa5b1b9e5de69f0769a64b83202122a7d0 Mon Sep 17 00:00:00 2001 From: blueluke Date: Tue, 12 Nov 2013 15:11:54 -0800 Subject: [PATCH 365/546] Removed a misplaced space in mpd_notification_preset variable declaration --- mpd.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mpd.md b/mpd.md index 0e2eca5..646b690 100644 --- a/mpd.md +++ b/mpd.md @@ -44,7 +44,7 @@ Variable | Meaning | Type | Default and can modify `mpd_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: - mpd_notification _preset = { + mpd_notification_preset = { title = "Now playing", timeout = 6, text = string.format("%s (%s) - %s\n%s", mpd_now.artist, From ca9579d7b130406e9bfb5e5ee004bd1c392780ee Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 28 Nov 2013 00:48:22 -0800 Subject: [PATCH 366/546] Updated Utilities (markdown) --- Utilities.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Utilities.md b/Utilities.md index 2171503..99588b9 100644 --- a/Utilities.md +++ b/Utilities.md @@ -59,8 +59,8 @@ Use it with key bindings like these: awful.key({ modkey, "Shift" }, "n", function () lain.util.add_tag(mypromptbox) end), awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag(mypromptbox) end), - awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(1) end), -- move to next tag - awful.key({ modkey, "Shift" }, "r", function () lain.util.move_tag(-1) end), -- move to previous tag + awful.key({ modkey, "Shift" }, "Left", function () lain.util.move_tag(1) end), -- move to next tag + awful.key({ modkey, "Shift" }, "Right", function () lain.util.move_tag(-1) end), -- move to previous tag awful.key({ modkey, "Shift" }, "d", function () lain.util.remove_tag() end), **Note** that these function won't work properly with [Copland theme](https://github.com/copycat-killer/awesome-copycats) or any other configuration that already uses a dynamic tagging module like [Eminent](https://github.com/copycat-killer/awesome-copycats/tree/master/eminent). From 17d1c8e0f9796ae54039103ae2ffefed31bcbcc4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 3 Dec 2013 02:29:12 -0800 Subject: [PATCH 367/546] Updated Home (markdown) --- Home.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 9ba8362..5581a9e 100644 --- a/Home.md +++ b/Home.md @@ -6,7 +6,7 @@ Dependencies Package | Requested by | Reason of choice --- | --- | --- alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / -curl | widgets accessing network resources | LuaSocket is not a core library. LuaSSL is out of date. +curl | widgets accessing network resources | LuaSocket is not a core library, and still not available for Lua 5.2+. LuaSSL is out of date. imagemagick | album arts in [mpd](https://github.com/copycat-killer/lain/wiki/mpd) notifications | Cairo doesn't do high quality filtering. Installation From 6aa59744be6a40d589d51e3dc605aec934afb166 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 3 Dec 2013 02:29:29 -0800 Subject: [PATCH 368/546] Updated Home (markdown) --- Home.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Home.md b/Home.md index 5581a9e..be89e32 100644 --- a/Home.md +++ b/Home.md @@ -6,7 +6,8 @@ Dependencies Package | Requested by | Reason of choice --- | --- | --- alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / -curl | widgets accessing network resources | LuaSocket is not a core library, and still not available for Lua 5.2+. LuaSSL is out of date. +curl | widgets accessing network resources | LuaSocket is not a core library, and still not available for Lua 5.2+. +LuaSSL is out of date. imagemagick | album arts in [mpd](https://github.com/copycat-killer/lain/wiki/mpd) notifications | Cairo doesn't do high quality filtering. Installation From 8671efc85c67afee497d5699bb8eb90066d0b4f7 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 5 Dec 2013 01:18:49 -0800 Subject: [PATCH 369/546] Updated Home (markdown) --- Home.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Home.md b/Home.md index be89e32..5581a9e 100644 --- a/Home.md +++ b/Home.md @@ -6,8 +6,7 @@ Dependencies Package | Requested by | Reason of choice --- | --- | --- alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / -curl | widgets accessing network resources | LuaSocket is not a core library, and still not available for Lua 5.2+. -LuaSSL is out of date. +curl | widgets accessing network resources | LuaSocket is not a core library, and still not available for Lua 5.2+. LuaSSL is out of date. imagemagick | album arts in [mpd](https://github.com/copycat-killer/lain/wiki/mpd) notifications | Cairo doesn't do high quality filtering. Installation From 648be56a195bd3fdb63b6de5ab5be90c628b4546 Mon Sep 17 00:00:00 2001 From: yawnt Date: Mon, 23 Dec 2013 08:04:02 -0800 Subject: [PATCH 370/546] Created brightness (markdown) --- brightness.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 brightness.md diff --git a/brightness.md b/brightness.md new file mode 100644 index 0000000..590359a --- /dev/null +++ b/brightness.md @@ -0,0 +1,40 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows brightness level in a textbox. + + volumewidget = lain.widgets.contrib.brightness() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`timeout` | Refresh timeout seconds | int | 5 +`backlight` | Backlight Video | string | "acpi_video0" +`settings` | User settings | function | empty function + +`settings` can use the following variables: + +Variable | Meaning | Type | Values +--- | --- | --- | --- +`brightness_now` | Brightness level | int | 0-100 + +### output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The widget | `wibox.widget.textbox` +`update` | Update `widget` | function + +You can control the widget with key bindings like these: + + -- Volume control + awful.key({}, "XF86MonBrightnessUp", + function () + awful.util.spawn("xbacklight -inc 1") + brightnesswidget.update() + end), + awful.key({}, "XF86MonBrightnessDown", + function () + awful.util.spawn("xbacklight -dec 1") + brightnesswidget.update() + end), From 1898354d7689dae919aa3e7e1f1d3b905b634c2f Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 23 Dec 2013 09:10:31 -0800 Subject: [PATCH 371/546] Created brigthness (markdown) --- brigthness.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 brigthness.md diff --git a/brigthness.md b/brigthness.md new file mode 100644 index 0000000..b0dfe76 --- /dev/null +++ b/brigthness.md @@ -0,0 +1,24 @@ +[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) + +Shows the current level of screen brightness. + + mybrightness = lain.widgets.contrib.brightness() + +### input table + +Variable | Meaning | Type | Default +--- | --- | --- | --- +`backlight` | Card managing backlight | `acpi_video0` +`timeout` | Refresh timeout seconds | int | 5 +`settings` | User settings | function | empty function + +`settings` can use the string `brightness_now`, which indicates the current brightness level. + +### output table + +Variable | Meaning | Type +--- | --- | --- +`widget` | The textbox | `wibox.widget.textbox` +`update` | The notification | function + +You can control the widget with key bindings like these: [TODO] \ No newline at end of file From 42280d5af340ec94994de5a34588e140e2ffd1b4 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 23 Dec 2013 09:11:07 -0800 Subject: [PATCH 372/546] Updated Widgets (markdown) --- Widgets.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index 8a8945b..12178e2 100644 --- a/Widgets.md +++ b/Widgets.md @@ -49,4 +49,5 @@ Users contributed ---------------- - [task](https://github.com/copycat-killer/lain/wiki/task) -- [tpbat](https://github.com/copycat-killer/lain/wiki/tpbat) \ No newline at end of file +- [tpbat](https://github.com/copycat-killer/lain/wiki/tpbat) +- [brightness](https://github.com/copycat-killer/lain/wiki/brigthness) \ No newline at end of file From 155ff91ffaa2e9345ed9721296243e3d022361fb Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 23 Dec 2013 09:14:39 -0800 Subject: [PATCH 373/546] Updated brightness (markdown) --- brightness.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/brightness.md b/brightness.md index 590359a..5a3a9db 100644 --- a/brightness.md +++ b/brightness.md @@ -1,15 +1,15 @@ [<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -Shows brightness level in a textbox. +Shows the current level of screen brightness in a textbox. - volumewidget = lain.widgets.contrib.brightness() + mybrightness = lain.widgets.contrib.brightness() ### input table Variable | Meaning | Type | Default --- | --- | --- | --- `timeout` | Refresh timeout seconds | int | 5 -`backlight` | Backlight Video | string | "acpi_video0" +`backlight` | Backlight video | string | "acpi_video0" `settings` | User settings | function | empty function `settings` can use the following variables: @@ -37,4 +37,4 @@ You can control the widget with key bindings like these: function () awful.util.spawn("xbacklight -dec 1") brightnesswidget.update() - end), + end), \ No newline at end of file From df4698902684aea1e5fbe6ea6552c0fa06a3191a Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 23 Dec 2013 09:15:04 -0800 Subject: [PATCH 374/546] Updated Widgets (markdown) --- Widgets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Widgets.md b/Widgets.md index 12178e2..5917aac 100644 --- a/Widgets.md +++ b/Widgets.md @@ -50,4 +50,4 @@ Users contributed - [task](https://github.com/copycat-killer/lain/wiki/task) - [tpbat](https://github.com/copycat-killer/lain/wiki/tpbat) -- [brightness](https://github.com/copycat-killer/lain/wiki/brigthness) \ No newline at end of file +- [brightness](https://github.com/copycat-killer/lain/wiki/brightness) \ No newline at end of file From 19bcd89afbff749c0b8bf04d676075aca92a5465 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 23 Dec 2013 09:17:57 -0800 Subject: [PATCH 375/546] Destroyed brigthness (markdown) --- brigthness.md | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 brigthness.md diff --git a/brigthness.md b/brigthness.md deleted file mode 100644 index b0dfe76..0000000 --- a/brigthness.md +++ /dev/null @@ -1,24 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows the current level of screen brightness. - - mybrightness = lain.widgets.contrib.brightness() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`backlight` | Card managing backlight | `acpi_video0` -`timeout` | Refresh timeout seconds | int | 5 -`settings` | User settings | function | empty function - -`settings` can use the string `brightness_now`, which indicates the current brightness level. - -### output table - -Variable | Meaning | Type ---- | --- | --- -`widget` | The textbox | `wibox.widget.textbox` -`update` | The notification | function - -You can control the widget with key bindings like these: [TODO] \ No newline at end of file From f4aae0997a6d914c88fa757d068a4e213eb12dc8 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 24 Dec 2013 03:28:49 -0800 Subject: [PATCH 376/546] Updated brightness (markdown) --- brightness.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brightness.md b/brightness.md index 5a3a9db..4cd4f8e 100644 --- a/brightness.md +++ b/brightness.md @@ -2,7 +2,7 @@ Shows the current level of screen brightness in a textbox. - mybrightness = lain.widgets.contrib.brightness() + brightnesswidget = lain.widgets.contrib.brightness() ### input table @@ -27,7 +27,7 @@ Variable | Meaning | Type You can control the widget with key bindings like these: - -- Volume control + -- Brightness control awful.key({}, "XF86MonBrightnessUp", function () awful.util.spawn("xbacklight -inc 1") From 9327898a0e58581793df6b20261f28d02a190946 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 24 Dec 2013 03:33:15 -0800 Subject: [PATCH 377/546] Updated tpbat (markdown) --- tpbat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpbat.md b/tpbat.md index 3d0b0e8..e54f469 100644 --- a/tpbat.md +++ b/tpbat.md @@ -6,4 +6,4 @@ Includes hover notification with more details. tpbatwidget = lain.widgets.contrib.tpbat() -Configuration is identical to [main bat widget's](https://github.com/copycat-killer/lain/wiki/bat). \ No newline at end of file +Configuration is identical to [standard bat widget's](https://github.com/copycat-killer/lain/wiki/bat). \ No newline at end of file From b0a458f8b753f1a3174cf713ef46ba2997e613dd Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 24 Dec 2013 03:33:29 -0800 Subject: [PATCH 378/546] Updated tpbat (markdown) --- tpbat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tpbat.md b/tpbat.md index e54f469..5a7ba0c 100644 --- a/tpbat.md +++ b/tpbat.md @@ -6,4 +6,4 @@ Includes hover notification with more details. tpbatwidget = lain.widgets.contrib.tpbat() -Configuration is identical to [standard bat widget's](https://github.com/copycat-killer/lain/wiki/bat). \ No newline at end of file +Configuration is identical to [standard battery widget's](https://github.com/copycat-killer/lain/wiki/bat). \ No newline at end of file From 309174ae7e5f9e629e6a40fe4f0faf23da074004 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 30 Dec 2013 06:57:45 -0800 Subject: [PATCH 379/546] Updated Layouts (markdown) --- Layouts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Layouts.md b/Layouts.md index 1ddca95..045c2c9 100644 --- a/Layouts.md +++ b/Layouts.md @@ -101,7 +101,7 @@ cascade Cascade all windows of a tag. -You can control the offsets by setting those two variables: +You can control the offsets by setting these two variables: lain.layout.cascade.cascade_offset_x = 64 lain.layout.cascade.cascade_offset_y = 16 From b008b01ecff8677e74ab6d77bc36a63a25b226e7 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 2 Jan 2014 03:16:09 -0800 Subject: [PATCH 380/546] Updated calendar (markdown) --- calendar.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/calendar.md b/calendar.md index fa4e563..b06c453 100644 --- a/calendar.md +++ b/calendar.md @@ -26,4 +26,6 @@ You can call the notification with a key binding like this: awful.key({ altkey }, "c", function () lain.widgets.calendar:show(7) end), -where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds. \ No newline at end of file +where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds. + +**Note that** this widget exploits ``cal`` to do the alignment, in order to avoid more dozens of code lines, but this requires that your system font is monospaced. \ No newline at end of file From 9f5b502185dc900f56b109752ea0cb352a7fcb71 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 13 Jan 2014 04:01:31 -0800 Subject: [PATCH 381/546] Updated bat (markdown) --- bat.md | 1 + 1 file changed, 1 insertion(+) diff --git a/bat.md b/bat.md index 50c14e8..82e7a8b 100644 --- a/bat.md +++ b/bat.md @@ -13,6 +13,7 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `timeout` | Refresh timeout seconds | int | 30 `battery` | Identifier of the battery | string | "BAT0" +`notify` | Enable notifications | boolean | true `settings` | User settings | function | empty function `settings` can use the `bat_now` table, which contains the following strings: From 0a5a9eee14724f7989b286dd1e8126ea7d863193 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 14 Jan 2014 00:53:12 -0800 Subject: [PATCH 382/546] Updated bat (markdown) --- bat.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bat.md b/bat.md index 82e7a8b..c450dbe 100644 --- a/bat.md +++ b/bat.md @@ -13,7 +13,7 @@ Variable | Meaning | Type | Default --- | --- | --- | --- `timeout` | Refresh timeout seconds | int | 30 `battery` | Identifier of the battery | string | "BAT0" -`notify` | Enable notifications | boolean | true +`notify` | Enable notifications | string | "on" `settings` | User settings | function | empty function `settings` can use the `bat_now` table, which contains the following strings: @@ -23,6 +23,8 @@ Variable | Meaning | Type | Default - `time`; - `watt`. +To disable warning notifications, set `notify` to `off`. + ### output A textbox. \ No newline at end of file From 6870633a0a9a5c0481d35aaa2655a116c4cce997 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 14 Jan 2014 00:53:56 -0800 Subject: [PATCH 383/546] Updated bat (markdown) --- bat.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bat.md b/bat.md index c450dbe..6bbb21e 100644 --- a/bat.md +++ b/bat.md @@ -23,7 +23,7 @@ Variable | Meaning | Type | Default - `time`; - `watt`. -To disable warning notifications, set `notify` to `off`. +To disable warning notifications, set `notify` to `"off"`. ### output From a339e3b6cf323d809647c1bacec0a388e955854c Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 14 Jan 2014 01:05:55 -0800 Subject: [PATCH 384/546] Updated alsabar (markdown) --- alsabar.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alsabar.md b/alsabar.md index fa5f209..6138f2c 100644 --- a/alsabar.md +++ b/alsabar.md @@ -16,7 +16,7 @@ Variable | Meaning | Type | Default `settings` | User settings | function | empty function `width` | Bar width | int | 63 `height` | Bar height | int | 1 -`ticks` | Set bar ticks on | boolean | true +`ticks` | Set bar ticks on | boolean | false `ticks_size` | Ticks size | int | 7 `vertical` | Set the bar vertical | boolean | false `channel` | Mixer channel | string | "Master" From d2ec840058a6de4eaafe57fe66953ede542815e6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 20 Jan 2014 09:52:35 -0800 Subject: [PATCH 385/546] Updated imap (markdown) --- imap.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/imap.md b/imap.md index ba92d0f..b0d5375 100644 --- a/imap.md +++ b/imap.md @@ -31,16 +31,26 @@ Variable | Meaning | Type | Default Let's focus better on `is_plain`. -You can just set your password like this: +The reason why it's false by default is to discourage the habit of storing passwords in plain files. - args.is_plain = false - args.password = "mypassword" +You can set your password in plain like this: + + myimapcheck = lain.widgets.imap({ + is_plain = true, + password = "myplainpassword", + [...] + }) and you'll have the same security provided by `~/.netrc`. **Or** you can use a keyring, like [python keyring](https://pypi.python.org/pypi/keyring): - args.password = "keyring get password" + myimapcheck = lain.widgets.imap({ + is_plain = true, + password = "myplainpassword", + server = "mail.autistici.org", + mail = "dada@anche.no", + }) When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. From 72aa10c4b7dd62e95ce9f3bbded184d1b272d345 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 20 Jan 2014 09:53:32 -0800 Subject: [PATCH 386/546] Updated imap (markdown) --- imap.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/imap.md b/imap.md index b0d5375..7952c81 100644 --- a/imap.md +++ b/imap.md @@ -46,10 +46,8 @@ and you'll have the same security provided by `~/.netrc`. **Or** you can use a keyring, like [python keyring](https://pypi.python.org/pypi/keyring): myimapcheck = lain.widgets.imap({ - is_plain = true, - password = "myplainpassword", - server = "mail.autistici.org", - mail = "dada@anche.no", + password = "keyring get mymail", + [...] }) When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. From be14ec3ff72d205d6e65380087e9a057be2b6151 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 20 Jan 2014 10:14:22 -0800 Subject: [PATCH 387/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index 7952c81..f754348 100644 --- a/imap.md +++ b/imap.md @@ -31,7 +31,7 @@ Variable | Meaning | Type | Default Let's focus better on `is_plain`. -The reason why it's false by default is to discourage the habit of storing passwords in plain files. +The reason why it's false by default is to discourage the habit of storing passwords in plain. You can set your password in plain like this: From 291910cdb61718058e81d938fb6dc1da7cc9cfff Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 20 Jan 2014 10:14:42 -0800 Subject: [PATCH 388/546] Updated imap (markdown) --- imap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imap.md b/imap.md index f754348..403a61a 100644 --- a/imap.md +++ b/imap.md @@ -33,7 +33,7 @@ Let's focus better on `is_plain`. The reason why it's false by default is to discourage the habit of storing passwords in plain. -You can set your password in plain like this: +So you can set your password in plain like this: myimapcheck = lain.widgets.imap({ is_plain = true, From e31436a3c1059a4c507e5a67dd8e4b35d21f7c3f Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 21 Jan 2014 16:03:04 +0100 Subject: [PATCH 389/546] wiki updated --- Home.md | 34 ------ Layouts.md | 298 -------------------------------------------------- Utilities.md | 163 --------------------------- Widgets.md | 53 --------- alsa.md | 53 --------- alsabar.md | 85 -------------- bat.md | 30 ----- borderbox.md | 49 --------- brightness.md | 40 ------- calendar.md | 31 ------ cpu.md | 18 --- fs.md | 45 -------- imap.md | 68 ------------ maildir.md | 39 ------- mem.md | 18 --- mpd.md | 85 -------------- net.md | 26 ----- sysload.md | 18 --- task.md | 30 ----- temp.md | 20 ---- tpbat.md | 9 -- wiki | 2 +- yawn.md | 93 ---------------- 23 files changed, 1 insertion(+), 1306 deletions(-) delete mode 100644 Home.md delete mode 100644 Layouts.md delete mode 100644 Utilities.md delete mode 100644 Widgets.md delete mode 100644 alsa.md delete mode 100644 alsabar.md delete mode 100644 bat.md delete mode 100644 borderbox.md delete mode 100644 brightness.md delete mode 100644 calendar.md delete mode 100644 cpu.md delete mode 100644 fs.md delete mode 100644 imap.md delete mode 100644 maildir.md delete mode 100644 mem.md delete mode 100644 mpd.md delete mode 100644 net.md delete mode 100644 sysload.md delete mode 100644 task.md delete mode 100644 temp.md delete mode 100644 tpbat.md delete mode 100644 yawn.md diff --git a/Home.md b/Home.md deleted file mode 100644 index 5581a9e..0000000 --- a/Home.md +++ /dev/null @@ -1,34 +0,0 @@ -Welcome to the Lain wiki! - -Dependencies ------------------- - -Package | Requested by | Reason of choice ---- | --- | --- -alsa-utils | [alsa](https://github.com/copycat-killer/lain/wiki/alsa), [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) | / -curl | widgets accessing network resources | LuaSocket is not a core library, and still not available for Lua 5.2+. LuaSSL is out of date. -imagemagick | album arts in [mpd](https://github.com/copycat-killer/lain/wiki/mpd) notifications | Cairo doesn't do high quality filtering. - -Installation ---------------- - -### Arch Linux - -[AUR package](https://aur.archlinux.org/packages/lain/) - -### Other distributions - - git clone https://github.com/copycat-killer/lain.git ~/.config/awesome/lain - -Usage --------- - -First, include it into your `rc.lua`: - - local lain = require("lain") - -Then check out the submodules you want: - -- [Layouts](https://github.com/copycat-killer/lain/wiki/Layouts) -- [Widgets](https://github.com/copycat-killer/lain/wiki/Widgets) -- [Utilities](https://github.com/copycat-killer/lain/wiki/Utilities) \ No newline at end of file diff --git a/Layouts.md b/Layouts.md deleted file mode 100644 index 045c2c9..0000000 --- a/Layouts.md +++ /dev/null @@ -1,298 +0,0 @@ -Currently, there are **8** layouts. - - lain/layout - . - |-- termfair - |-- centerfair - |-- cascade - |-- cascadetile - |-- centerwork - |-- uselessfair - |-- uselesspiral - `-- uselesstile - -Just add your favourites to ``layouts`` table: - - layouts = - { - ... - lain.layout.termfair, - lain.layout.uselesstile, - ... - } - -Or set them on specific tags like this: - - awful.layout.set(lain.layout.uselessfair, tags[1][7]) - -How do layouts work? -========================= - -termfair --------- - -I do a lot of work on terminals. The common tiling algorithms usually -maximize windows, so you'll end up with a terminal that has about 200 -columns or more. That's way too much. Have you ever read a manpage in a -terminal of this size? - -This layout restricts the size of each window. Each window will have the -same width but is variable in height. Furthermore, windows are -left-aligned. The basic workflow is as follows (the number above the -screen is the number of open windows, the number in a cell is the fixed -number of a client): - - (1) (2) (3) - +---+---+---+ +---+---+---+ +---+---+---+ - | | | | | | | | | | | | - | 1 | | | -> | 2 | 1 | | -> | 3 | 2 | 1 | -> - | | | | | | | | | | | | - +---+---+---+ +---+---+---+ +---+---+---+ - - (4) (5) (6) - +---+---+---+ +---+---+---+ +---+---+---+ - | 4 | | | | 5 | 4 | | | 6 | 5 | 4 | - +---+---+---+ -> +---+---+---+ -> +---+---+---+ - | 3 | 2 | 1 | | 3 | 2 | 1 | | 3 | 2 | 1 | - +---+---+---+ +---+---+---+ +---+---+---+ - -The first client will be located in the left column. When opening -another window, this new window will be placed in the left column while -moving the first window into the middle column. Once a row is full, -another row above it will be created. - -Default number of columns and rows are respectively taken from `nmaster` -and `ncol` values in `awful.tag`, but you can set your own. - -For example, this sets `termfair` to 3 columns and at least 1 row: - - lain.layout.termfair.nmaster = 3 - lain.layout.termfair.ncol = 1 - -centerfair ----------- - -Similar to `termfair`, but with fixed number of vertical columns. Cols are centerded until there are `nmaster` columns, then windows are stacked as slaves, with possibly `ncol` clients per column at most. - - (1) (2) (3) - +---+---+---+ +-+---+---+-+ +---+---+---+ - | | | | | | | | | | | | | - | | 1 | | -> | | 1 | 2 | | -> | 1 | 2 | 3 | -> - | | | | | | | | | | | | | - +---+---+---+ +-+---+---+-+ +---+---+---+ - - (4) (5) - +---+---+---+ +---+---+---+ - | | | 3 | | | 2 | 4 | - + 1 + 2 +---+ -> + 1 +---+---+ - | | | 4 | | | 3 | 5 | - +---+---+---+ +---+---+---+ - -Like `termfair`, default number of columns and rows are respectively taken from `nmaster` -and `ncol` values in `awful.tag`, but you can set your own. - -For example: - - lain.layout.centerfair.nmaster = 3 - lain.layout.centerfair.ncol = 1 - -cascade -------- - -Cascade all windows of a tag. - -You can control the offsets by setting these two variables: - - lain.layout.cascade.cascade_offset_x = 64 - lain.layout.cascade.cascade_offset_y = 16 - -The following reserves space for 5 windows: - - lain.layout.cascade.nmaster = 5 - -That is, no window will get resized upon the creation of a new window, -unless there's more than 5 windows. - -cascadetile ------------ - -Similar to `awful.layout.suit.tile` layout, however, clients in the slave -column are cascaded instead of tiled. - -Left column size can be set, otherwise is controlled by `mwfact` of the -tag. Additional windows will be opened in another column on the right. -New windows are placed above old windows. - -Whether the slave column is placed on top of the master window or not is -controlled by the value of `ncol`. A value of 1 means "overlapping slave column" -and anything else means "don't overlap windows". - -Usage example: - - lain.layout.cascadetile.cascade_offset_x = 2 - lain.layout.cascadetile.cascade_offset_y = 32 - lain.layout.cascadetile.extra_padding = 5 - lain.layout.cascadetile.nmaster = 5 - lain.layout.ncol = 1 - -`extra_padding` reduces the size of the master window if "overlapping -slave column" is activated. This allows you to see if there are any -windows in your slave column. - -Setting `cascade_offset_x` to a very small value or even 0 is reccommended to avoid wasting space. - -centerwork ----------- - -You start with one window, centered horizontally: - - +--------------------------+ - | +----------+ | - | | | | - | | | | - | | | | - | | MAIN | | - | | | | - | | | | - | | | | - | | | | - | +----------+ | - +--------------------------+ - -This is your main working window. You do most of the work right here. -Sometimes, you may want to open up additional windows. They're put in -the following four slots: - - +--------------------------+ - | +---+ +----------+ +---+ | - | | | | | | | | - | | 0 | | | | 1 | | - | | | | | | | | - | +---+ | MAIN | +---+ | - | +---+ | | +---+ | - | | | | | | | | - | | 2 | | | | 3 | | - | | | | | | | | - | +---+ +----------+ +---+ | - +--------------------------+ - -Yes, the number "four" is fixed. In total, you can only have five open -windows with this layout. Additional windows are not managed and set to -floating mode. **This is intentional**. - -You can set the order of the four auxiliary windows. This is the default -configuration: - - lain.layout.centerwork.top_left = 0 - lain.layout.centerwork.top_right = 1 - lain.layout.centerwork.bottom_left = 2 - lain.layout.centerwork.bottom_right = 3 - -This means: The bottom left slot will be occupied by the third window -(not counting the main window). Suppose you want your windows to appear -in this order: - - +--------------------------+ - | +---+ +----------+ +---+ | - | | | | | | | | - | | 3 | | | | 0 | | - | | | | | | | | - | +---+ | MAIN | +---+ | - | +---+ | | +---+ | - | | | | | | | | - | | 2 | | | | 1 | | - | | | | | | | | - | +---+ +----------+ +---+ | - +--------------------------+ - -This would require you to use these settings: - - lain.layout.centerwork.top_left = 3 - lain.layout.centerwork.top_right = 0 - lain.layout.centerwork.bottom_left = 2 - lain.layout.centerwork.bottom_right = 1 - -*Please note:* If you use Awesome's default configuration, navigation in -this layout may be very confusing. How do you get from the main window -to satellite ones depends on the order in which the windows are opened. -Thus, use of `awful.client.focus.bydirection()` is suggested. -Here's an example: - - globalkeys = awful.util.table.join( - ... - awful.key({ modkey }, "j", - function() - awful.client.focus.bydirection("down") - if client.focus then client.focus:raise() end - end), - awful.key({ modkey }, "k", - function() - awful.client.focus.bydirection("up") - if client.focus then client.focus:raise() end - end), - awful.key({ modkey }, "h", - function() - awful.client.focus.bydirection("left") - if client.focus then client.focus:raise() end - end), - awful.key({ modkey }, "l", - function() - awful.client.focus.bydirection("right") - if client.focus then client.focus:raise() end - end), - ... - ) - -uselessfair, uselesspiral & uselesstile ---------------------------------------- -These are duplicates of the stock `fair`, `spiral` and `tile` layouts. - -However, "useless gaps" (see below) have been added. - -Useless gaps -============ - -Useless gaps are gaps between windows. They are "useless" because they -serve no special purpose despite increasing overview. I find it easier -to recognize window boundaries if windows are set apart a little bit. - -The `uselessfair` layout, for example, looks like this: - - +================+ - # # - # +---+ +---+ # - # | 1 | | | # - # +---+ | | # - # | 3 | # - # +---+ | | # - # | 2 | | | # - # +---+ +---+ # - # # - +================+ - -All of lain layouts provide useless gaps. To set the width of the gaps, -you have to add an item called `useless_gap_width` in your `theme.lua`. -If it doesn't exist, the width will default to 0. -Example: - - theme.useless_gap_width = 10 - -What about layout icons? -======================== - -They are located in ``lain/icons/layout``. - -To use them, add lines to your ``theme.lua`` like this: - - theme.lain_icons = os.getenv("HOME") .. "/.config/awesome/lain/icons/layout/default/" - theme.layout_termfair = theme.lain_icons .. "termfairw.png" - theme.layout_cascade = theme.lain_icons .. "cascadew.png" - theme.layout_cascadetile = theme.lain_icons .. "cascadetilew.png" - theme.layout_centerwork = theme.lain_icons .. "centerworkw.png" - -Credits goes to [Nicolas Estibals](https://github.com/nestibal) for creating -layout icons for default theme. - -You can use them as a template for your custom versions. - -[<- home](https://github.com/copycat-killer/lain/wiki) \ No newline at end of file diff --git a/Utilities.md b/Utilities.md deleted file mode 100644 index 99588b9..0000000 --- a/Utilities.md +++ /dev/null @@ -1,163 +0,0 @@ -markup ------- - -Made markup easier! - -First, require it like this: - - local markup = lain.util.markup - -then you can call its functions: - - +-- markup - | - |`-- bold() Set bold. - |`-- italic() Set italicized text. - |`-- strike() Set strikethrough text. - |`-- underline() Set underlined text. - |`-- monospace() Set monospaced text. - |`-- big() Set bigger text. - |`-- small() Set smaller text. - |`-- font() Set the font of the text. - | - |`--+ bg - | | - | |`-- color() Set background color. - | |`-- focus() Set focus background color. - | |`-- normal() Set normal background color. - | `-- urgent() Set urgent background color. - | - |`--+ fg - | | - | |`-- color() Set foreground color. - | |`-- focus() Set focus foreground color. - | |`-- normal() Set normal foreground color. - | `-- urgent() Set urgent foreground color. - | - |`-- focus() Set both foreground and background focus colors. - |`-- normal() Set both foreground and background normal colors. - `-- urgent() Set both foreground and background urgent colors. - -they all take one argument, which is the text to markup, except `fg.color` and `bg.color`: - - markup.fg.color(text, color) - markup.bg.color(text, color) - -dynamic tagging ---------------- - -That is: - -- add a new tag; -- rename current tag; -- move current tag; -- remove current tag. - -If you delete a tag, any rule set on it shall be broken, so be careful. - -Use it with key bindings like these: - - awful.key({ modkey, "Shift" }, "n", function () lain.util.add_tag(mypromptbox) end), - awful.key({ modkey, "Shift" }, "r", function () lain.util.rename_tag(mypromptbox) end), - awful.key({ modkey, "Shift" }, "Left", function () lain.util.move_tag(1) end), -- move to next tag - awful.key({ modkey, "Shift" }, "Right", function () lain.util.move_tag(-1) end), -- move to previous tag - awful.key({ modkey, "Shift" }, "d", function () lain.util.remove_tag() end), - -**Note** that these function won't work properly with [Copland theme](https://github.com/copycat-killer/awesome-copycats) or any other configuration that already uses a dynamic tagging module like [Eminent](https://github.com/copycat-killer/awesome-copycats/tree/master/eminent). - -useless\_gaps\_resize ---------------------- - -Changes `beautiful.useless_gaps_width` on the fly. - -The function takes an integer argument, being the amount of pixel to add/remove to gaps. - -You could use it with these keybindings: - - -- On the fly useless gaps change - awful.key({ altkey, "Control" }, "+", function () lain.util.useless_gaps_resize(1) end), - awful.key({ altkey, "Control" }, "-", function () lain.util.useless_gaps_resize(-1) end), - -where `altkey=Mod1`, or you could use it like this: - - mywidget:buttons(awful.util.table.join ( - awful.button({}, 4, function() lain.util.useless_gaps_resize(-1) end), - awful.button({}, 5, function() lain.util.useless_gaps_resize(1) end) - end) - )) - -so when hovering the mouse over `mywidget`, you can adjust useless gaps size by scrolling with the mouse wheel. - -tag\_view\_nonempty -------------------- - -This function lets you jump to the next/previous non-empty tag. -It takes two arguments: - -* `direction`: `1` for next non-empty tag, `-1` for previous. -* `sc`: Screen which the taglist is in. Default is `mouse.screen` or `1`. This - argument is optional. - -You can use it with key bindings like these: - - -- Non-empty tag browsing - awful.key({ altkey }, "Left", function () lain.util.tag_view_nonempty(-1) end), - awful.key({ altkey }, "Right", function () lain.util.tag_view_nonempty(1) end), - -where `altkey = "Mod1"`. - -menu\_clients\_current\_tags ----------------------------- - -Similar to `awful.menu.clients`, but this menu only shows the clients -of currently visible tags. Use it with a key binding like this: - - awful.key({ "Mod1" }, "Tab", - function() - awful.menu.menu_keys.down = { "Down", "Alt_L", "Tab", "j" } - awful.menu.menu_keys.up = { "Up", "k" } - lain.util.menu_clients_current_tags({ width = 350 }, { keygrabber = true }) - end), - -magnify\_client ---------------- - -Set a client to floating and resize it in the same way the "magnifier" -layout does it. Place it on the "current" screen (derived from the mouse -position). This allows you to magnify any client you wish, regardless of -the currently used layout. Use it with a client keybinding like this: - - clientkeys = awful.util.table.join( - ... - awful.key({ modkey, "Control" }, "m", lain.util.magnify_client), - ... - ) - -If you want to "de-magnify" it, just retype the keybinding. - -niceborder\_{focus, unfocus} ----------------------------- - -By default, your `rc.lua` contains something like this: - - client.connect_signal("focus", function(c) c.border_color = beautiful.border_focus end) - client.connect_signal("unfocus", function(c) c.border_color = beautiful.border_normal end) - -You can change it to this: - - client.connect_signal("focus", lain.util.niceborder_focus(c)) - client.connect_signal("unfocus", lain.util.niceborder_unfocus(c)) - -Now, when a client is focused or unfocused, Awesome will look up its -nice value in `/proc//stat`. If it's less than 0, the client is -classified as "high priority"; if it's greater than 0, the client is -classified as "low priority". If it's equal to 0, nothing special -happens. - -This requires to define additional colors in your `theme.lua`. For example: - - theme.border_focus_highprio = "#FF0000" - theme.border_normal_highprio = "#A03333" - - theme.border_focus_lowprio = "#3333FF" - theme.border_normal_lowprio = "#333366" \ No newline at end of file diff --git a/Widgets.md b/Widgets.md deleted file mode 100644 index 5917aac..0000000 --- a/Widgets.md +++ /dev/null @@ -1,53 +0,0 @@ -General usage -------------- - -Every widget is output by a `function`. - -For some widgets, `function` returns a `wibox.widget.textbox`, for others a table to be used for notification and update purposes. - -Every widget may take either a table or a list of variables as argument. - -If it takes a table, you have to define a function variable called `settings` in it, in order to make your customizations. - -To markup the textbox, call `widget:set_markup(...)` within `settings`. - -You can feed `set_markup` with predefined arguments, see the sections for all the details. - -`widget` is a textbox, so you can threat it like any other `wibox.widget.textbox`. - -Here follows an example: - - mycpu = lain.widgets.cpu({ - timeout = 4, - settings = function() - widget:set_markup("Cpu " .. cpu_now.usage) - end - }) - -If you want to see more complex applications, check [awesome-copycats](https://github.com/copycat-killer/awesome-copycats). - -Index ------ - -- [alsa](https://github.com/copycat-killer/lain/wiki/alsa) -- [alsabar](https://github.com/copycat-killer/lain/wiki/alsabar) -- [bat](https://github.com/copycat-killer/lain/wiki/bat) -- [borderbox](https://github.com/copycat-killer/lain/wiki/borderbox) -- [calendar](https://github.com/copycat-killer/lain/wiki/calendar) -- [cpu](https://github.com/copycat-killer/lain/wiki/cpu) -- [fs](https://github.com/copycat-killer/lain/wiki/fs) -- [imap](https://github.com/copycat-killer/lain/wiki/imap) -- [maildir](https://github.com/copycat-killer/lain/wiki/maildir) -- [mem](https://github.com/copycat-killer/lain/wiki/mem) -- [mpd](https://github.com/copycat-killer/lain/wiki/mpd) -- [net](https://github.com/copycat-killer/lain/wiki/net) -- [sysload](https://github.com/copycat-killer/lain/wiki/sysload) -- [temp](https://github.com/copycat-killer/lain/wiki/temp) -- [yawn](https://github.com/copycat-killer/lain/wiki/yawn) - -Users contributed ----------------- - -- [task](https://github.com/copycat-killer/lain/wiki/task) -- [tpbat](https://github.com/copycat-killer/lain/wiki/tpbat) -- [brightness](https://github.com/copycat-killer/lain/wiki/brightness) \ No newline at end of file diff --git a/alsa.md b/alsa.md deleted file mode 100644 index daf4016..0000000 --- a/alsa.md +++ /dev/null @@ -1,53 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows and controls alsa volume with a textbox. - - volumewidget = lain.widgets.alsa() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 5 -`channel` | Mixer channel | string | "Master" -`settings` | User settings | function | empty function - -`settings` can use the following variables: - -Variable | Meaning | Type | Values ---- | --- | --- | --- -`volume_now.level` | Self explained | int | 0-100 -`volume_now.status` | Device status | string | "on", "off" - -### output table - -Variable | Meaning | Type ---- | --- | --- -`widget` | The widget | `wibox.widget.textbox` -`update` | Update `widget` | function - -You can control the widget with key bindings like these: - - -- Volume control - awful.key({ altkey }, "Up", - function () - awful.util.spawn("amixer set Master 1%+") - volumewidget.update() - end), - awful.key({ altkey }, "Down", - function () - awful.util.spawn("amixer set Master 1%-") - volumewidget.update() - end), - awful.key({ altkey }, "m", - function () - awful.util.spawn("amixer set Master playback toggle") - volumewidget.update() - end), - awful.key({ altkey, "Control" }, "m", - function () - awful.util.spawn("amixer set Master playback 100%", false ) - volumewidget.update() - end), - -where `altkey = "Mod1"`. \ No newline at end of file diff --git a/alsabar.md b/alsabar.md deleted file mode 100644 index 6138f2c..0000000 --- a/alsabar.md +++ /dev/null @@ -1,85 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows and controls alsa volume with a progressbar; provides tooltips, notifications, and color changes at mute/unmute switch. - - volume = lain.widgets.alsabar() - -* Left click: Launch `alsamixer` in your `terminal`. -* Right click: Mute/unmute. -* Scroll wheel: Increase/decrase volume. - -The function takes a table as optional argument, which can contain: - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 4 -`settings` | User settings | function | empty function -`width` | Bar width | int | 63 -`height` | Bar height | int | 1 -`ticks` | Set bar ticks on | boolean | false -`ticks_size` | Ticks size | int | 7 -`vertical` | Set the bar vertical | boolean | false -`channel` | Mixer channel | string | "Master" -`step` | Step at which volume is increased/decreased | string | "5%" -`colors` | Bar colors | table | see **colors** -`notifications` | Notifications settings | table | see **notifications** - -### colors - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`background` | Bar backgrund color | string | `beautiful.bg_normal` -`mute` | Bar mute color | string | "#EB8F8F" -`unmute` | Bar unmute color | string | "#A4CE8A" - -### notifications - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`font` | Notifications font | string | The one defined in `beautiful.font` -`font_size` | Notifications font size | string | "11" -`color` | Notifications color | string | `beautiful.fg_normal` -`bar_size` | Wibox height | int | 18 - -It's **crucial** to set `notifications.bar_size` to your `mywibox[s]` height. - -`settings` can use the following variables: - -Variable | Meaning | Type | Values ---- | --- | --- | --- -`volume_now.level` | Self explained | int | 0-100 -`volume_now.status` | Device status | string | "on", "off" -### output table - -Variable | Meaning | Type ---- | --- | --- -`bar` | The widget | `awful.widget.progressbar` -`channel` | Alsa channel | string -`step` | Increase/decrease step | string -`notify` | The notification | function - -You can control the widget with key bindings like these: - - -- ALSA volume control - awful.key({ altkey }, "Up", - function () - awful.util.spawn("amixer -q set " .. volume.channel .. " " .. volume.step .. "+") - volume.notify() - end), - awful.key({ altkey }, "Down", - function () - awful.util.spawn("amixer -q set " .. volume.channel .. " " .. volume.step .. "-") - volume.notify() - end), - awful.key({ altkey }, "m", - function () - awful.util.spawn("amixer -q set " .. volume.channel .. " playback toggle") - volume.notify() - end), - awful.key({ altkey, "Control" }, "m", - function () - awful.util.spawn("amixer -q set " .. volume.channel .. " playback 100%") - volume.notify() - end), - -where `altkey = "Mod1"`. \ No newline at end of file diff --git a/bat.md b/bat.md deleted file mode 100644 index 6bbb21e..0000000 --- a/bat.md +++ /dev/null @@ -1,30 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows in a textbox the remaining time and percentage capacity of your laptop battery, as well as -the current wattage. - -Displays a notification when battery is low or critical. - - mybattery = lain.widgets.bat() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 30 -`battery` | Identifier of the battery | string | "BAT0" -`notify` | Enable notifications | string | "on" -`settings` | User settings | function | empty function - -`settings` can use the `bat_now` table, which contains the following strings: - -- `status` ("Not present", "Charging", "Discharging"); -- `perc`; -- `time`; -- `watt`. - -To disable warning notifications, set `notify` to `"off"`. - -### output - -A textbox. \ No newline at end of file diff --git a/borderbox.md b/borderbox.md deleted file mode 100644 index a56026a..0000000 --- a/borderbox.md +++ /dev/null @@ -1,49 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Creates a thin wibox at a position relative to another wibox. - -This allows to create "borders" for your wiboxes. - - lain.widget.borderbox(relbox, s, args) - -`relbox` and `s` (an integer being screen number) are required arguments, `args` is an optional table -which can contain: - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`position` | Position of the additional box | string | "above" -`color` | Color of the additional box | string | `#FFFFFF` -`size` | Size in pixels of the additional box | int | 1 - -Possible values for `.position`: `top`, `bottom`, `left` and `right`. - -### Example usage - -Think of this as a wibox: - - [======================] - -If `args.position = "above"`, then you'll get an additional wibox below -the existing one: - - ________________________ - [======================] - -It'll match position and size of the existing wibox. - -If your main wiboxes are stored in a table called `mywibox` (one wibox -for each screen) and are located at the bottom of your screen, then this -adds a borderbox on top of them: - - -- Layout section - for s = 1, screen.count() do - ... - - -- Most likely, you'll want to do this as well: - awful.screen.padding(screen[s], "bottom") - - -- Create the box and place it above the existing box. - lain.widgets.borderbox(mywibox[s], s ) - - ... - end \ No newline at end of file diff --git a/brightness.md b/brightness.md deleted file mode 100644 index 4cd4f8e..0000000 --- a/brightness.md +++ /dev/null @@ -1,40 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows the current level of screen brightness in a textbox. - - brightnesswidget = lain.widgets.contrib.brightness() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 5 -`backlight` | Backlight video | string | "acpi_video0" -`settings` | User settings | function | empty function - -`settings` can use the following variables: - -Variable | Meaning | Type | Values ---- | --- | --- | --- -`brightness_now` | Brightness level | int | 0-100 - -### output table - -Variable | Meaning | Type ---- | --- | --- -`widget` | The widget | `wibox.widget.textbox` -`update` | Update `widget` | function - -You can control the widget with key bindings like these: - - -- Brightness control - awful.key({}, "XF86MonBrightnessUp", - function () - awful.util.spawn("xbacklight -inc 1") - brightnesswidget.update() - end), - awful.key({}, "XF86MonBrightnessDown", - function () - awful.util.spawn("xbacklight -dec 1") - brightnesswidget.update() - end), \ No newline at end of file diff --git a/calendar.md b/calendar.md deleted file mode 100644 index b06c453..0000000 --- a/calendar.md +++ /dev/null @@ -1,31 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Attaches a calendar notification to a widget. - - lain.widgets.calendar:attach(widget, args) - -- Left click: switch to previous month. -- Right click: switch to next month. - -`args` is an optional table which can contain: - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`icons` | Path to calendar icons | string | [lain/icons/cal/white](https://github.com/copycat-killer/lain/tree/master/icons/cal/white) -`font_size` | Calendar font size | int | 12 -`fg` | Calendar foreground color | string | `beautiful.fg_normal` -`bg` | Calendar background color | string | `beautiful.bg_normal` -`position` | Calendar position | string | "top_right" - -`position` possible values are defined [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify). - -Notification will show an icon displaying current day, and formatted output -from ``cal`` with current day highlighted. - -You can call the notification with a key binding like this: - - awful.key({ altkey }, "c", function () lain.widgets.calendar:show(7) end), - -where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds. - -**Note that** this widget exploits ``cal`` to do the alignment, in order to avoid more dozens of code lines, but this requires that your system font is monospaced. \ No newline at end of file diff --git a/cpu.md b/cpu.md deleted file mode 100644 index e42180c..0000000 --- a/cpu.md +++ /dev/null @@ -1,18 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows in a textbox the average CPU usage percent for a given amount of time. - - mycpuusage = lain.widgets.cpu() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 5 -`settings` | User settings | function | empty function - -`settings` can use the string `cpu_now.usage`, which is the cpu use percentage. - -### output - -A textbox. \ No newline at end of file diff --git a/fs.md b/fs.md deleted file mode 100644 index 1e34f86..0000000 --- a/fs.md +++ /dev/null @@ -1,45 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows disk space usage for a set partition. - -Displays a notification when the partition is full or has low space. - - mypartition = lain.widgets.fs() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds -| int | 600 -`partition` | Partition to monitor | string | "/" -`settings` | User settings | function | empty function - -`settings` can use the following `partition` related float values: `fs_now.used`, `fs_now.available`, `fs_now.size_mb`, `fs_now.size_gb`. - -It can also use value strings in these formats: - - fs_info[p .. "used_p"] - fs_info[p .. "avail_p"] - fs_info[p .. "size_mb"] - fs_info[p .. "size_gb"] - -where `p` is the last column of `df` command ("/", "/home", "/boot", ...). - -This means you can set the widget for a certain partition, but you can look up at others too. - -Finally, `settings` can modify `fs_notification_preset` table too. This table will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: - - fs_notification_preset = { fg = beautiful.fg_normal } - -### output table - -Variable | Meaning | Type ---- | --- | --- -`widget` | The widget | `wibox.widget.textbox` -`show` | The notification | function - -You can display the notification with a key binding like this: - - awful.key({ altkey }, "h", function () mypartition.show(7) end), - -where ``altkey = "Mod1"`` and ``show`` argument is an optional integer, meaning timeout seconds. \ No newline at end of file diff --git a/imap.md b/imap.md deleted file mode 100644 index 403a61a..0000000 --- a/imap.md +++ /dev/null @@ -1,68 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows mail count in a textbox fetching over IMAP. - - myimapcheck = lain.widgets.imap(args) - -New mails are notified like this: - - +--------------------------------------------+ - | +---+ | - | |\ /| donald@disney.org has 3 new messages | - | +---+ | - +--------------------------------------------+ - -The function takes a table as argument. Required table parameters are: - -Variable | Meaning | Type ---- | --- | --- -`server` | Mail server | string -`mail` | User mail | string -`password` | User password | string - -while the optional are: - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`port` | IMAP port | int | 993 -`timeout` | Refresh timeout seconds | int | 60 -`is_plain` | Define whether `password` is a plain password (true) or a function that retrieves it (false) | boolean | false -`settings` | User settings | function - -Let's focus better on `is_plain`. - -The reason why it's false by default is to discourage the habit of storing passwords in plain. - -So you can set your password in plain like this: - - myimapcheck = lain.widgets.imap({ - is_plain = true, - password = "myplainpassword", - [...] - }) - -and you'll have the same security provided by `~/.netrc`. - -**Or** you can use a keyring, like [python keyring](https://pypi.python.org/pypi/keyring): - - myimapcheck = lain.widgets.imap({ - password = "keyring get mymail", - [...] - }) - -When `is_plain == false`, it *executes* `password` before using it, so you can also use whatever password fetching solution you want. - -`settings` can use the value `mailcount`, an integer greater or equal to zero, and can modify `mail_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. - -Default definition: - - mail_notification _preset = { - icon = lain/icons/mail.png, - position = "top_left" - } - -Note that `mailcount` is 0 either if there are no new mails or credentials are invalid, so make sure you get the right settings. - -### output - -A textbox. \ No newline at end of file diff --git a/maildir.md b/maildir.md deleted file mode 100644 index 355ecdd..0000000 --- a/maildir.md +++ /dev/null @@ -1,39 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows maildirs status in a textbox. - -Maildirs are structured as follows: - - ~/Mail - . - |-- arch - | |-- cur - | |-- new - | `-- tmp - |-- gmail - | |-- cur - | |-- new - | `-- tmp - . - . - . - -therefore the widget checks whether there are files in the `new` directories. -If there's new mails, the textbox will say something like "mail: bugs(3), system(1)", otherwise it says -"no mail". - - mymaildir = lain.widgets.maildir("/path/to/my/maildir") - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 60 -`mailpath` | Path to your maildir | string | "~/Mail" -`settings` | User settings | function | empty function - -`settings` can use the string `newmail`, which format will be something like defined above, or "no mail". - -### output - -A textbox. \ No newline at end of file diff --git a/mem.md b/mem.md deleted file mode 100644 index 84b7ad2..0000000 --- a/mem.md +++ /dev/null @@ -1,18 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows memory status (in MiB) in a textbox. - - mymem = lain.widgets.mem() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 3 -`settings` | User settings | function | empty function - -`settings` can use the strings `mem_now.used` (memory used MB) and `mem_now.swapused` (swap used MB). - -### output - -A textbox. \ No newline at end of file diff --git a/mpd.md b/mpd.md deleted file mode 100644 index 646b690..0000000 --- a/mpd.md +++ /dev/null @@ -1,85 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows MPD status in a textbox. - - mpdwidget = lain.widgets.mpd() - -Now playing songs are notified like this: - - +--------------------------------------------------------+ - | +-------+ | - | |/^\_/^\| Now playing | - | |\ O O /| Cannibal Corpse (Hammer Smashed Face) - 1993 | - | | '.o.' | Hammer Smashed Face (Radio Disney Version) | - | +-------+ | - +--------------------------------------------------------+ - -You need a file like this - - (Front|front|Cover|cover|Art|art|Folder|folder)\.(jpg|jpeg|png|gif) - -in the album folder in order to show album art too. - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 1 -`password` | MPD password | string | "" -`host` | MPD server | string | "127.0.0.1" -`port` | MPD port | string | "6600" -`music_dir` | Music directory | string | "~/Music" -`cover_size` | Album art notification size | int | 100 -`default_art` | Default art | string | "" -`settings` | User settings | function | empty function - -`settings` can use `mpd_now` table, which contains the following string values: - -- state (possible values: "play", "pause", "stop") -- file -- artist -- title -- album -- date - -and can modify `mpd_notification_preset` table, which will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. Default definition: - - mpd_notification_preset = { - title = "Now playing", - timeout = 6, - text = string.format("%s (%s) - %s\n%s", mpd_now.artist, - mpd_now.album, mpd_now.date, mpd_now.title) - } - -### output table - -Variable | Meaning | Type ---- | --- | --- -`widget` | The textbox | `wibox.widget.textbox` -`update` | The notification | function - -You can control the widget with key bindings like these: - - -- MPD control - awful.key({ altkey, "Control" }, "Up", - function () - awful.util.spawn_with_shell("mpc toggle || ncmpcpp toggle || ncmpc toggle || pms toggle") - mpdwidget.update() - end), - awful.key({ altkey, "Control" }, "Down", - function () - awful.util.spawn_with_shell("mpc stop || ncmpcpp stop || ncmpc stop || pms stop") - mpdwidget.update() - end), - awful.key({ altkey, "Control" }, "Left", - function () - awful.util.spawn_with_shell("mpc prev || ncmpcpp prev || ncmpc prev || pms prev") - mpdwidget.update() - end), - awful.key({ altkey, "Control" }, "Right", - function () - awful.util.spawn_with_shell("mpc next || ncmpcpp next || ncmpc next || pms next") - mpdwidget.update() - end), - -where `altkey = "Mod1"`. \ No newline at end of file diff --git a/net.md b/net.md deleted file mode 100644 index f857239..0000000 --- a/net.md +++ /dev/null @@ -1,26 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Monitors network interfaces and shows current traffic in a textbox. - - mynet = lain.widgets.net() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 2 -`iface` | Network device | string | autodetected -`units` | Units | int | 1024 (kilobytes) -`settings` | User settings | function | empty function - -Possible other values for `units` are 1 (byte) or multiple of 1024: 1024^2 (mb), 1024^3 (gb), and so on. - -`settings` can use the following `iface` related strings: - -- `net_now.carrier` ("0", "1"); -- `net_now.state` ("up", "down"); -- `net_now.sent` and `net_now.received` (numbers). - -### output - -A textbox. \ No newline at end of file diff --git a/sysload.md b/sysload.md deleted file mode 100644 index 3e53881..0000000 --- a/sysload.md +++ /dev/null @@ -1,18 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows the current system load. - - mysysload = lain.widgets.sysload() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 5 -`settings` | User settings | function | empty function - -`settings` can use strings `load_1`, `load_5` and `load_15`, which are loadavg over 1, 5, and 15 minutes. - -### output - -A textbox. \ No newline at end of file diff --git a/task.md b/task.md deleted file mode 100644 index b4bc7f0..0000000 --- a/task.md +++ /dev/null @@ -1,30 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Attaches a [taskwarrior](http://taskwarrior.org/projects/show/taskwarrior) notification to a widget, and lets to add/search tasks from the promptbox. - - lain.widgets.contrib.task:attach(widget, args) - -`args` is an optional table which can contain: - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`font_size` | Calendar font size | int | 12 -`fg` | Calendar foreground color | string | `beautiful.fg_normal` -`bg` | Calendar background color | string | `beautiful.bg_normal` -`position` | Calendar position | string | "top_right" -`timeout` | Notification timeout seconds | int | 7 - -`position` possible values are defined [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify). - -Notification will show the output of `task` command. - -You can call the notification with a key binding like this: - - awful.key({ modkey, altkey }, "t", lain.widgets.contrib.task.show), - -where ``altkey = "Mod1"``. - -And you can prompt to add/search a task with key bindings like these: - - awful.key({ modkey, }, "t", lain.widgets.contrib.task.prompt_add), - awful.key({ modkey, "Shift" }, "t", lain.widgets.contrib.task.prompt_search), \ No newline at end of file diff --git a/temp.md b/temp.md deleted file mode 100644 index 91f3031..0000000 --- a/temp.md +++ /dev/null @@ -1,20 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -Shows the current core temperature in a textbox. - -Reads from `/sys/class/thermal`, so value is expressed in Celsius. - - mytemp = lain.widgets.temp() - -### input table - -Variable | Meaning | Type | Default ---- | --- | --- | --- -`timeout` | Refresh timeout seconds | int | 5 -`settings` | User settings | function | empty function - -`settings` can use the string `coretemp_now`, which means current core temperature, expressed in Celsius (linux standard). - -### output - -A textbox. \ No newline at end of file diff --git a/tpbat.md b/tpbat.md deleted file mode 100644 index 5a7ba0c..0000000 --- a/tpbat.md +++ /dev/null @@ -1,9 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -A battery widget that works with Lenovo ThinkPad laptops using [tp_smapi](http://www.thinkwiki.org/wiki/Tp_smapi). - -Includes hover notification with more details. - - tpbatwidget = lain.widgets.contrib.tpbat() - -Configuration is identical to [standard battery widget's](https://github.com/copycat-killer/lain/wiki/bat). \ No newline at end of file diff --git a/wiki b/wiki index f996cdb..2fe55cb 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit f996cdb74e7583534256d82706ef63d2b9811b42 +Subproject commit 2fe55cb50b4192866551d50dce563a52234961c7 diff --git a/yawn.md b/yawn.md deleted file mode 100644 index 30d160c..0000000 --- a/yawn.md +++ /dev/null @@ -1,93 +0,0 @@ -[<- widgets](https://github.com/copycat-killer/lain/wiki/Widgets) - -(YAhoo! Weather Notification) - -Yawn provides brief and compact Yahoo! Weather notification. - -Usage ------ - -You can ``register`` Yawn to get a set of widgets, or ``attach`` it to -an existent widget. - -### register - - yawn = lain.widgets.yawn(id, args) - -- ``id`` - - An integer that defines the WOEID code of your city. - To obtain it you can google 'yahoo weather %CITYNAME%' and follow the first link. - It will look like: - - http://weather.yahoo.com/united-states/california/san-diego-2487889/ - - and the last number in that link will be the ID you need. - -- ``args`` - - A required table which can contain: - - Variables | Meaning | Type | Possible values | Default value - --- | --- | --- | --- | --- - `u` | Units | string | "c" (Celsius), "f" (Fahrenheit) | "c" - `timeout` | Refresh timeout seconds | int | integers | 600 - `settings` | User settings | function | function | empty function - - `settings` can use strings `forecast`, `units`, and can modify `yawn_notification_preset` table, which - will be the preset for the naughty notifications. Check [here](http://awesome.naquadah.org/doc/api/modules/naughty.html#notify) for the list of variables it can contain. - -The function `register` creates an imagebox icon and a textbox widget. Add them to you wibox like this: - - right_layout:add(yawn.icon) - right_layout:add(yawn.widget) - -Hovering over ``yawn.icon`` will display the notification. - -### attach - - lain.widgets.yawn.attach(widget, id, args) - -Arguments: - -- ``widget`` - - The widget which you want to attach Yawn to. - -- ``id`` - - Same as in ``register``. - -- ``args`` - - Same as in ``register``. - -Hovering over ``widget`` will display the notification. - -Popup shortcut --------------- - -You can also create a keybinding for the weather popup like this: - - awful.key( { "Mod1" }, "w", function () yawn.show(5) end ) - -where ``show`` argument is an integer defining timeout seconds. - -Localization ------------- - -Default language is English, but Yawn can be localized. - -Move to `localizations` subdirectory and fill `localization_template`. - -Once you're done, rename it like your locale id. In my case: - - $ lua - Lua 5.2.2 Copyright (C) 1994-2013 Lua.org, PUC-Rio - > print(os.getenv("LANG"):match("(%S*$*)[.]")) - it_IT - > - -hence I named my file "it_IT" (Italian localization). - -**NOTE:** If you create a localization, feel free to send me! I will add it. \ No newline at end of file From 89d557638deb75bc3d0e6c8890cb7eec59ab0ce2 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 29 Jan 2014 11:56:32 +0100 Subject: [PATCH 390/546] new I/O file helper functions --- helpers.lua | 45 ++++++++++++++++++++++++++++++++----------- widgets/maildir.lua | 1 + widgets/yawn/init.lua | 1 + wiki | 2 +- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/helpers.lua b/helpers.lua index c42ce61..08aba0d 100644 --- a/helpers.lua +++ b/helpers.lua @@ -10,7 +10,8 @@ local debug = require("debug") local capi = { timer = timer } -local io = { open = io.open } +local io = { open = io.open, + lines = io.lines } local rawget = rawget -- Lain helper functions for internal use @@ -30,18 +31,40 @@ end -- }}} --- {{{ Read the first line of a file or return nil +-- {{{ File operations -function helpers.first_line(f) - local fp = io.open(f) - if not fp - then - return nil - end +-- see if the file exists +function helpers.file_exists(file) + local f = io.open(file, "rb") + if f then f:close() end + return f ~= nil +end - local content = fp:read("*l") - fp:close() - return content + +-- get all lines from a file, returns an empty +-- list/table if the file does not exist +function helpers.lines_from(file) + if not helpers.file_exists(file) then return {} end + lines = {} + for line in io.lines(file) do + lines[#lines + 1] = line + end + return lines +end + +-- get first line of a file, return nil if +-- the file does not exist +function helpers.first_line(file) + return helpers.lines_from(file)[1] +end + +-- get first non empty line from a file, +-- returns nil otherwise +function helpers.first_nonempty_line(file) + for k,v in pairs(lines_from(file)) do + if #v then return v end + end + return nil end -- }}} diff --git a/widgets/maildir.lua b/widgets/maildir.lua index 5cb6840..d460881 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -1,3 +1,4 @@ + --[[ Licensed under GNU General Public License v2 diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 36cdf54..b4d9c05 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -1,3 +1,4 @@ + --[[ Licensed under GNU General Public License v2 diff --git a/wiki b/wiki index 2fe55cb..6825e84 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 2fe55cb50b4192866551d50dce563a52234961c7 +Subproject commit 6825e84bb73415c4cbf5fcd903ea4987976e4be3 From 11656d7713b53f30841c5c302d9f1d44f23df439 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 29 Jan 2014 20:08:16 +0100 Subject: [PATCH 391/546] fixed typo in helpers.lua --- helpers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helpers.lua b/helpers.lua index 08aba0d..af6443f 100644 --- a/helpers.lua +++ b/helpers.lua @@ -61,7 +61,7 @@ end -- get first non empty line from a file, -- returns nil otherwise function helpers.first_nonempty_line(file) - for k,v in pairs(lines_from(file)) do + for k,v in pairs(helpers.lines_from(file)) do if #v then return v end end return nil From e530ec7fcde3245484a739f077d3f0f907a7d87a Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 4 Feb 2014 08:59:00 +0100 Subject: [PATCH 392/546] bat: little fixes --- widgets/bat.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 48a14fb..21b5c43 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -59,7 +59,7 @@ local function worker(args) bat_now.status = first_line(bstr .. "/status") or "N/A" - rate = tonumber(rate) + rate = tonumber(rate) or 1 ratev = tonumber(ratev) rem = tonumber(rem) tot = tonumber(tot) From b40a0e83e0a79d587c9390de52c455fca7a8c589 Mon Sep 17 00:00:00 2001 From: Lukas Geis Date: Sun, 2 Feb 2014 14:29:44 +0100 Subject: [PATCH 393/546] Bat.lua: Adding naughty presets for customizable notifications --- widgets/bat.lua | 63 ++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 21b5c43..4526c85 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -32,6 +32,22 @@ local function worker(args) bat.widget = wibox.widget.textbox('') + bat_notification_low_preset = { + title = "Battery low", + text = "Plug the cable!", + timeout = 15, + fg = "#202020", + bg = "#CDCDCD" + } + + bat_notification_critical_preset = { + title = "Battery exhausted", + text = "Shutdown imminent", + timeout = 15, + fg = "#000000", + bg = "#FFFFFF" + } + function update() bat_now = { status = "Not present", @@ -96,39 +112,28 @@ local function worker(args) bat_now.watt = "N/A" end - -- notifications for low and critical states - if bat_now.status == "Discharging" and notify == "on" - then - if tonumber(bat_now.perc) <= 5 - then - bat.id = naughty.notify({ - text = "shutdown imminent", - title = "battery nearly exhausted", - position = "top_right", - timeout = 15, - fg="#000000", - bg="#ffffff", - ontop = true, - replaces_id = bat.id - }).id - elseif tonumber(bat_now.perc) <= 15 - then - bat.id = naughty.notify({ - text = "plug the cable", - title = "battery low", - position = "top_right", - timeout = 15, - fg="#202020", - bg="#cdcdcd", - ontop = true, - replaces_id = bat.id - }).id - end - end end widget = bat.widget settings() + + -- notifications for low and critical states + if bat_now.status == "Discharging" and notify == "on" + then + if tonumber(bat_now.perc) <= 5 + then + bat.id = naughty.notify({ + preset = bat_notification_critical_preset, + replaces_id = bat.id + }).id + elseif tonumber(bat_now.perc) <= 15 + then + bat.id = naughty.notify({ + preset = bat_notification_low_preset, + replaces_id = bat.id + }).id + end + end end newtimer("bat", timeout, update) From 6b91332a38dfd5f8758b170c592faec8b3a544fe Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 4 Feb 2014 09:22:22 +0100 Subject: [PATCH 394/546] calendar: font variable added --- widgets/calendar.lua | 29 +++++++++++++++-------------- wiki | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index f684fd7..c9e265a 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -38,9 +38,6 @@ function calendar:show(t_out, inc_offset) local f, c_text local today = tonumber(os.date('%d')) local init_t = '/usr/bin/cal | sed -r -e "s/(^| )( ' - -- let's take font only, font size is set in calendar table - local font = beautiful.font:sub(beautiful.font:find(""), - beautiful.font:find(" ")) if offs == 0 then -- current month showing, today highlighted @@ -86,7 +83,7 @@ function calendar:show(t_out, inc_offset) f = io.popen('/usr/bin/cal ' .. month .. ' ' .. year) end - c_text = "" .. f:read() .. "\n\n" .. f:read() .. "\n" @@ -94,21 +91,25 @@ function calendar:show(t_out, inc_offset) .. "" f:close() - cal_notification = naughty.notify({ text = c_text, - icon = calendar.notify_icon, - position = calendar.position, - fg = calendar.fg, - bg = calendar.bg, - timeout = tims }) + cal_notification = naughty.notify({ + text = c_text, + icon = calendar.notify_icon, + position = calendar.position, + fg = calendar.fg, + bg = calendar.bg, + timeout = tims + }) end function calendar:attach(widget, args) local args = args or {} - calendar.icons = args.icons or icons_dir .. "cal/white/" + calendar.icons = args.icons or icons_dir .. "cal/white/" + calendar.font = args.font or beautiful.font:sub(beautiful.font:find(""), + beautiful.font:find(" ")) calendar.font_size = tonumber(args.font_size) or 11 - calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" - calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF" - calendar.position = args.position or "top_right" + calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" + calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF" + calendar.position = args.position or "top_right" calendar.offset = 0 calendar.notify_icon = nil diff --git a/wiki b/wiki index 6825e84..d424887 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 6825e84bb73415c4cbf5fcd903ea4987976e4be3 +Subproject commit d4248875dcd12ceb300c8a876001ce68f5405758 From 96df4b879033f447d494dfc9928d97cc34e5473b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 7 Feb 2014 12:39:18 +0100 Subject: [PATCH 395/546] #25 fix attempt --- widgets/net.lua | 6 ++---- widgets/yawn/init.lua | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/widgets/net.lua b/widgets/net.lua index d79e117..af97201 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -35,7 +35,7 @@ function net.get_device() if ws ~= nil then return ws:gsub(": UP", "") else - return "" + return "network off" end end @@ -80,10 +80,8 @@ local function worker(args) then if helpers.get_map(iface) then - n_title = iface - if n_title == "" then n_title = "network" end naughty.notify({ - title = n_title, + title = iface, text = "no carrier", timeout = 7, position = "top_left", diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index b4d9c05..af7befc 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -58,12 +58,12 @@ local function fetch_weather() yawn.icon:set_image(icon_path .. "na.png") if text == "" then weather_data = "Service not available at the moment." - yawn.widget:set_text(" N/A") + yawn.widget:set_text(" N/A ") else weather_data = "City not found!\n" .. "Are you sure " .. city_id .. " is your Yahoo city ID?" - yawn.widget:set_text(" ?") + yawn.widget:set_text(" ? ") end return end From 940a900b9a74fa2d39b9e05262d74158bd2a0d64 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 8 Feb 2014 11:44:09 +0100 Subject: [PATCH 396/546] 26# fix attempt --- widgets/bat.lua | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 4526c85..c2a6587 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -97,13 +97,17 @@ local function worker(args) bat_now.time = string.format("%02d:%02d", hrs, min) - local perc = (rem / tot) * 100 - if perc <= 100 then - bat_now.perc = string.format("%d", perc) - elseif perc > 100 then - bat_now.perc = "100" - elseif perc < 0 then - bat_now.perc = "0" + bat_now.perc = first_line(bstr .. "/capacity") + + if not bat_now.perc then + local perc = (rem / tot) * 100 + if perc <= 100 then + bat_now.perc = string.format("%d", perc) + elseif perc > 100 then + bat_now.perc = "100" + elseif perc < 0 then + bat_now.perc = "0" + end end if rate ~= nil and ratev ~= nil then @@ -118,7 +122,7 @@ local function worker(args) settings() -- notifications for low and critical states - if bat_now.status == "Discharging" and notify == "on" + if bat_now.status == "Discharging" and notify == "on" and bat_now.perc ~= nil then if tonumber(bat_now.perc) <= 5 then From 9cd85a25829cc600c05622c1f92a97b257918835 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 8 Feb 2014 12:10:13 +0100 Subject: [PATCH 397/546] #25 fix attempt 2 --- helpers.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helpers.lua b/helpers.lua index af6443f..f2bd5e4 100644 --- a/helpers.lua +++ b/helpers.lua @@ -35,12 +35,11 @@ end -- see if the file exists function helpers.file_exists(file) - local f = io.open(file, "rb") + local f = io.open(file) if f then f:close() end return f ~= nil end - -- get all lines from a file, returns an empty -- list/table if the file does not exist function helpers.lines_from(file) From 0dfbb462e898605d19d8657505763f6cc3d93d3f Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 9 Feb 2014 10:36:40 +0100 Subject: [PATCH 398/546] #25 blueluke's fix attempt --- helpers.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/helpers.lua b/helpers.lua index f2bd5e4..863bb87 100644 --- a/helpers.lua +++ b/helpers.lua @@ -3,7 +3,6 @@ Licensed under GNU General Public License v2 * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann --]] @@ -33,10 +32,14 @@ end -- {{{ File operations --- see if the file exists +-- see if the file exists and is readable function helpers.file_exists(file) local f = io.open(file) - if f then f:close() end + if f then + local s = f:read() + f:close() + f = s + end return f ~= nil end From ddeb786a75215efc3bd47b5b7f29a2ac19b06d28 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 9 Feb 2014 17:44:28 +0100 Subject: [PATCH 399/546] #26 fix attempt 2 --- widgets/bat.lua | 5 +++-- widgets/yawn/init.lua | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index c2a6587..485fd57 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -122,15 +122,16 @@ local function worker(args) settings() -- notifications for low and critical states + bat_now.perc = tonumber(bat_now.perc) if bat_now.status == "Discharging" and notify == "on" and bat_now.perc ~= nil then - if tonumber(bat_now.perc) <= 5 + if bat_now.perc <= 5 then bat.id = naughty.notify({ preset = bat_notification_critical_preset, replaces_id = bat.id }).id - elseif tonumber(bat_now.perc) <= 15 + elseif bat_now.perc <= 15 then bat.id = naughty.notify({ preset = bat_notification_low_preset, diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index af7befc..3f08cd5 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -75,7 +75,7 @@ local function fetch_weather() -- may still happens in case of bad connectivity if weather_data == "" then yawn.icon:set_image(icon_path .. "na.png") - yawn.widget:set_text(" ?") + yawn.widget:set_text(" ? ") return end From 5b67a36d52c9d5a8f925ca4d0c02094894198e77 Mon Sep 17 00:00:00 2001 From: aaron-lebo Date: Mon, 10 Feb 2014 03:02:14 -0600 Subject: [PATCH 400/546] Create acw.lua --- widgets/contrib/acw.lua | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 widgets/contrib/acw.lua diff --git a/widgets/contrib/acw.lua b/widgets/contrib/acw.lua new file mode 100644 index 0000000..0c3ae3f --- /dev/null +++ b/widgets/contrib/acw.lua @@ -0,0 +1,69 @@ +-[[ + + Licensed under GNU General Public License v2 + * (c) 2014, Aaron Lebo + +--]] + +local newtimer = require("lain.helpers").newtimer +local wibox = require("wibox") +local json = require("dkjson") + +-- acw (awesome crypto widget) +-- diplays BTC/USD and DOGE/USD using Coinbase and Cryptsy APIs +-- requires http://dkolf.de/src/dkjson-lua.fsl/home +-- based upon http://awesome.naquadah.org/wiki/Bitcoin_Price_Widget +-- lain.widgets.contrib.acw + +acw = {widget=wibox.widget.textbox('')} + +local function get(url) + f = io.popen('curl -m 5 -s "' .. url .. '"') + if (not f) then return 0 end + return f:read("*all") +end + +local function parse(j) + local obj, pos, err = json.decode (j, 1, nil) + if err thenfunction worker(args) + return nil + else + return obj + end +end + +function worker(args) + local args = args or {} + local timeout = args.timeout or 600 + local settings = args.settings or function() end + + + local function update() + btc = parse(get("https://coinbase.com/api/v1/prices/buy")) + if btc then + btc = tonumber(btc["subtotal"]["amount"]) + btc_display = "$" .. btc + else + btc_display = "N/A" + end + doge = parse(get("http://pubapi.cryptsy.com/api.php?method=singlemarketdata&marketid=132")) + if doge and btc then + doge = tonumber(doge["return"]["markets"]["DOGE"]["lasttradeprice"]) + doge_display = string.format("$%.4f", btc * doge) + else + doge_display = "N/A" + end + prices = btc_display .. " " .. doge_display + prices_now = {} + prices_now.prices = prices + + widget = acw.widget + settings() + end + + newtimer("acw", timeout, update) + + return acw.widget +end + +return setmetatable(acw, { __call = function(_, ...) return worker(...) end }) From 3e8754c217fa770f86dae53b27bae14663118bae Mon Sep 17 00:00:00 2001 From: aaron-lebo Date: Mon, 10 Feb 2014 03:06:50 -0600 Subject: [PATCH 401/546] Update acw.lua --- widgets/contrib/acw.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/widgets/contrib/acw.lua b/widgets/contrib/acw.lua index 0c3ae3f..c06de57 100644 --- a/widgets/contrib/acw.lua +++ b/widgets/contrib/acw.lua @@ -37,7 +37,6 @@ function worker(args) local timeout = args.timeout or 600 local settings = args.settings or function() end - local function update() btc = parse(get("https://coinbase.com/api/v1/prices/buy")) if btc then From 80b5351dc784fa659ed04dafc4838ae9bc67f712 Mon Sep 17 00:00:00 2001 From: Aaron Lebo Date: Mon, 10 Feb 2014 05:49:49 -0600 Subject: [PATCH 402/546] Moved acw from single file to folder. --- widgets/contrib/{acw.lua => acw/init.lua} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename widgets/contrib/{acw.lua => acw/init.lua} (100%) diff --git a/widgets/contrib/acw.lua b/widgets/contrib/acw/init.lua similarity index 100% rename from widgets/contrib/acw.lua rename to widgets/contrib/acw/init.lua From 45c077f02e7eac4be29c12652bcc8f20d8683b17 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 10 Feb 2014 19:17:47 +0100 Subject: [PATCH 403/546] moved acw/init to ccurr + code revision --- widgets/contrib/acw/init.lua | 68 ------------------------------- widgets/contrib/ccurr.lua | 78 ++++++++++++++++++++++++++++++++++++ wiki | 2 +- 3 files changed, 79 insertions(+), 69 deletions(-) delete mode 100644 widgets/contrib/acw/init.lua create mode 100644 widgets/contrib/ccurr.lua diff --git a/widgets/contrib/acw/init.lua b/widgets/contrib/acw/init.lua deleted file mode 100644 index c06de57..0000000 --- a/widgets/contrib/acw/init.lua +++ /dev/null @@ -1,68 +0,0 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2014, Aaron Lebo - ---]] - -local newtimer = require("lain.helpers").newtimer -local wibox = require("wibox") -local json = require("dkjson") - --- acw (awesome crypto widget) --- diplays BTC/USD and DOGE/USD using Coinbase and Cryptsy APIs --- requires http://dkolf.de/src/dkjson-lua.fsl/home --- based upon http://awesome.naquadah.org/wiki/Bitcoin_Price_Widget --- lain.widgets.contrib.acw - -acw = {widget=wibox.widget.textbox('')} - -local function get(url) - f = io.popen('curl -m 5 -s "' .. url .. '"') - if (not f) then return 0 end - return f:read("*all") -end - -local function parse(j) - local obj, pos, err = json.decode (j, 1, nil) - if err thenfunction worker(args) - return nil - else - return obj - end -end - -function worker(args) - local args = args or {} - local timeout = args.timeout or 600 - local settings = args.settings or function() end - - local function update() - btc = parse(get("https://coinbase.com/api/v1/prices/buy")) - if btc then - btc = tonumber(btc["subtotal"]["amount"]) - btc_display = "$" .. btc - else - btc_display = "N/A" - end - doge = parse(get("http://pubapi.cryptsy.com/api.php?method=singlemarketdata&marketid=132")) - if doge and btc then - doge = tonumber(doge["return"]["markets"]["DOGE"]["lasttradeprice"]) - doge_display = string.format("$%.4f", btc * doge) - else - doge_display = "N/A" - end - prices = btc_display .. " " .. doge_display - prices_now = {} - prices_now.prices = prices - - widget = acw.widget - settings() - end - - newtimer("acw", timeout, update) - - return acw.widget -end - -return setmetatable(acw, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/contrib/ccurr.lua b/widgets/contrib/ccurr.lua new file mode 100644 index 0000000..b9a4f42 --- /dev/null +++ b/widgets/contrib/ccurr.lua @@ -0,0 +1,78 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, Aaron Lebo + +--]] + +local newtimer = require("lain.helpers").newtimer +local wibox = require("wibox") +local json = require("dkjson") + +-- Crypto currencies widget +-- lain.widgets.contrib.ccurr +local ccurr = {} + +-- Currently gets +-- * BTC/USD +-- * DOGE/USD +-- using Coinbase and Cryptsy APIs. + +-- requires http://dkolf.de/src/dkjson-lua.fsl/home +-- based upon http://awesome.naquadah.org/wiki/Bitcoin_Price_Widget + +local function get(url) + local f = io.popen('curl -m 5 -s "' .. url .. '"') + if not f then + return 0 + else + local s = f:read("*all") + f:close() + return s + end +end + +local function parse(j) + local obj, pos, err = json.decode(j, 1, nil) + if err then + return nil + else + return obj + end +end + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 600 + local btc_url = args.btc_url or "https://coinbase.com/api/v1/prices/buy" + local doge_url = args.doge_url or "http://pubapi.cryptsy.com/api.php?method=singlemarketdata&marketid=132" + local settings = args.settings or function() end + + ccurr.widget = wibox.widget.textbox('') + + local function update() + price_now = { + btc = "N/A", + doge = "N/A" + } + + btc = parse(get(btc_url)) + doge = parse(get(doge_url)) + + if btc and doge then + price_now.btc = tonumber(btc["subtotal"]["amount"]) + price_now.doge = tonumber(doge["return"]["markets"]["DOGE"]["lasttradeprice"]) + price_now.doge = string.format("%.4f", price_now.btc * price_now.doge) + end + + widget = ccurr.widget + settings() + end + + newtimer("ccurr", timeout, update) + + return ccurr.widget +end + +return setmetatable(ccurr, { __call = function(_, ...) return worker(...) end }) diff --git a/wiki b/wiki index d424887..72c82d4 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit d4248875dcd12ceb300c8a876001ce68f5405758 +Subproject commit 72c82d49aa961e15440db7dfefb749fe0d2cdd02 From 58c7088f94da3d1700ad73f1cd8e829f7595b92d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 10 Feb 2014 19:24:45 +0100 Subject: [PATCH 404/546] ccurr: final fixes + wiki updated --- widgets/contrib/ccurr.lua | 4 ++++ wiki | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/widgets/contrib/ccurr.lua b/widgets/contrib/ccurr.lua index b9a4f42..f696a35 100644 --- a/widgets/contrib/ccurr.lua +++ b/widgets/contrib/ccurr.lua @@ -7,9 +7,13 @@ --]] local newtimer = require("lain.helpers").newtimer + local wibox = require("wibox") local json = require("dkjson") +local string = { format = string.format } +local tonumber = tonumber + -- Crypto currencies widget -- lain.widgets.contrib.ccurr local ccurr = {} diff --git a/wiki b/wiki index 72c82d4..1f364a9 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 72c82d49aa961e15440db7dfefb749fe0d2cdd02 +Subproject commit 1f364a97ada361c479950cf8efa3f0b752f665fc From e3234a1b91f4ea1bbda6dc1bd9f935b013258f0a Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 10 Feb 2014 19:45:25 +0100 Subject: [PATCH 405/546] wiki updated --- widgets/contrib/tpbat/init.lua | 40 +++++++++++++++++----------------- wiki | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/widgets/contrib/tpbat/init.lua b/widgets/contrib/tpbat/init.lua index dbf90aa..72d6453 100644 --- a/widgets/contrib/tpbat/init.lua +++ b/widgets/contrib/tpbat/init.lua @@ -90,16 +90,28 @@ function tpbat.register(args) tpbat.widget = wibox.widget.textbox('') + bat_notification_low_preset = { + title = "Battery low", + text = "Plug the cable!", + timeout = 15, + fg = "#202020", + bg = "#CDCDCD" + } + + bat_notification_critical_preset = { + title = "Battery exhausted", + text = "Shutdown imminent", + timeout = 15, + fg = "#000000", + bg = "#FFFFFF" + } + if bat:get('state') == nil then local n = naughty.notify({ + preset = bat_notification_low_preset, title = "SMAPI Battery Warning: Unable to read battery state!", - text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths.", - position = "top_right", - timeout = 15, - fg="#202020", - bg="#cdcdcd", - ontop = true + text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths." }) end @@ -124,25 +136,13 @@ function tpbat.register(args) if bat_now.perc <= 5 then tpbat.id = naughty.notify({ - text = "shutdown imminent", - title = "battery nearly exhausted", - position = "top_right", - timeout = 15, - fg="#000000", - bg="#ffffff", - ontop = true, + preset = bat_notification_critical_preset, replaces_id = tpbat.id }).id elseif bat_now.perc <= 15 then tpbat.id = naughty.notify({ - text = "plug the cable", - title = "battery low", - position = "top_right", - timeout = 15, - fg="#202020", - bg="#cdcdcd", - ontop = true, + preset = bat_notification_low_preset, replaces_id = tpbat.id }).id end diff --git a/wiki b/wiki index 1f364a9..60ad9c7 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 1f364a97ada361c479950cf8efa3f0b752f665fc +Subproject commit 60ad9c7c6b9fa533f10cd4ce4b2912165b76c0d9 From ec3604e73735e4b1f447f8dbac41d056e086505f Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 12 Feb 2014 12:23:02 +0100 Subject: [PATCH 406/546] base widget template added --- scripts/dfs | 10 ++++++---- wiki | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/dfs b/scripts/dfs index 1730b6e..d78d2bb 100755 --- a/scripts/dfs +++ b/scripts/dfs @@ -6,6 +6,8 @@ # Integrated into Lain in september 2013 # https://github.com/copycat-killer/lain +# Requires gawk + # ------------------------------------------------------------------------- # Decoding options # ------------------------------------------------------------------------- @@ -183,7 +185,7 @@ echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v DEBUG=$DEBUG -v PATTERN=$PATT current_date = strftime ("%d-%m-%Y @ %H:%M:%S", localtime (systime ())); free_threshold = 10; # % - printf ("\n"); + printf ("\n"); printf ( \ "\n" \ @@ -197,9 +199,9 @@ echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v DEBUG=$DEBUG -v PATTERN=$PATT "Mount point\n" \ "%% Usato (*)" \ " - %% Free (*)\n" \ - "%% Usato\n" \ - "Spazio libero\n" \ - "Spazio totale\n" \ + "%% Used\n" \ + "Free\n" \ + "Total\n" \ "\n" ); } else diff --git a/wiki b/wiki index 60ad9c7..6075408 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 60ad9c7c6b9fa533f10cd4ce4b2912165b76c0d9 +Subproject commit 60754084cf7bb69d7387484e12fa686c73cfe1bc From 9889ef5ca2e62b3cc9802a2dadff6a4ee5069114 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 13 Feb 2014 10:58:47 +0100 Subject: [PATCH 407/546] cal: --color=never added to discourage #29 --- widgets/calendar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index c9e265a..d0df17c 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -37,7 +37,7 @@ function calendar:show(t_out, inc_offset) local tims = t_out or 0 local f, c_text local today = tonumber(os.date('%d')) - local init_t = '/usr/bin/cal | sed -r -e "s/(^| )( ' + local init_t = '/usr/bin/cal --color=never | sed -r -e "s/(^| )( ' if offs == 0 then -- current month showing, today highlighted From 8147032a532a73b03bd04dee0ee959f035377526 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 13 Feb 2014 17:35:55 +0100 Subject: [PATCH 408/546] base widget added (this time for real) --- widgets/base.lua | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 widgets/base.lua diff --git a/widgets/base.lua b/widgets/base.lua new file mode 100644 index 0000000..0431d03 --- /dev/null +++ b/widgets/base.lua @@ -0,0 +1,37 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, Luke Bonham + +--]] + +local newtimer = require("lain.helpers").newtimer +local wibox = require("wibox") + +local io = io +local setmetatable = setmetatable + +-- Basic template for simple widgets +-- lain.widgets.base +local base = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 5 + local cmd = args.cmd or "" + local settings = args.settings or function() end + + base.widget = wibox.widget.textbox('') + + function update() + output = io.popen(cmd):read("*all") + widget = base.widget + settings() + end + + newtimer(cmd, timeout, update) + return base.widget +end + +return setmetatable(base, { __call = function(_, ...) return worker(...) end }) From 377b316f5d179d03378d9fa69b246f441d54fb5e Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 13 Feb 2014 18:17:48 +0100 Subject: [PATCH 409/546] base: update subfuction added; contrib/brightness removed because now redundant --- widgets/base.lua | 11 +++++---- widgets/contrib/brightness.lua | 42 ---------------------------------- wiki | 2 +- 3 files changed, 8 insertions(+), 47 deletions(-) delete mode 100644 widgets/contrib/brightness.lua diff --git a/widgets/base.lua b/widgets/base.lua index 0431d03..198b6f7 100644 --- a/widgets/base.lua +++ b/widgets/base.lua @@ -12,7 +12,7 @@ local wibox = require("wibox") local io = io local setmetatable = setmetatable --- Basic template for simple widgets +-- Basic template for custom widgets -- lain.widgets.base local base = {} @@ -24,14 +24,17 @@ local function worker(args) base.widget = wibox.widget.textbox('') - function update() - output = io.popen(cmd):read("*all") + function base.update() + local f = assert(io.popen(cmd)) + output = f:read("*all") + f:close() widget = base.widget settings() end newtimer(cmd, timeout, update) - return base.widget + + return setmetatable(base, { __index = base.widget }) end return setmetatable(base, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/contrib/brightness.lua b/widgets/contrib/brightness.lua deleted file mode 100644 index 04b8d2b..0000000 --- a/widgets/contrib/brightness.lua +++ /dev/null @@ -1,42 +0,0 @@ - ---[[ - - Licensed under GNU General Public License v2 - * (c) 2013, yawnt - ---]] - -local newtimer = require("lain.helpers").newtimer - -local wibox = require("wibox") -local io = { popen = io.popen } - -local setmetatable = setmetatable - --- Brightness level --- lain.widgets.contrib.brightness -local brightness = {} - -local function worker(args) - local args = args or {} - local backlight = args.backlight or "acpi_video0" - local timeout = args.timeout or 5 - local settings = args.settings or function() end - - brightness.widget = wibox.widget.textbox('') - - function brightness.update() - local f = assert(io.popen('cat /sys/class/backlight/' .. backlight .. "/brightness")) - brightness_now = f:read("*a") - f:close() - - widget = brightness.widget - settings() - end - - newtimer("brightness", timeout, brightness.update) - - return setmetatable(brightness, { __index = brightness.widget }) -end - -return setmetatable(brightness, { __call = function(_, ...) return worker(...) end }) diff --git a/wiki b/wiki index 6075408..b56a779 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 60754084cf7bb69d7387484e12fa686c73cfe1bc +Subproject commit b56a779e276987cb9f8f8d81785d35633db047d1 From 705c3cea9b982ec0e50c4cef18d1da0b31d4cb03 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 14 Feb 2014 18:02:02 +0100 Subject: [PATCH 410/546] base: small fix --- widgets/base.lua | 2 +- widgets/calendar.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/base.lua b/widgets/base.lua index 198b6f7..3d4ce9e 100644 --- a/widgets/base.lua +++ b/widgets/base.lua @@ -32,7 +32,7 @@ local function worker(args) settings() end - newtimer(cmd, timeout, update) + newtimer(cmd, timeout, base.update) return setmetatable(base, { __index = base.widget }) end diff --git a/widgets/calendar.lua b/widgets/calendar.lua index d0df17c..c9e265a 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -37,7 +37,7 @@ function calendar:show(t_out, inc_offset) local tims = t_out or 0 local f, c_text local today = tonumber(os.date('%d')) - local init_t = '/usr/bin/cal --color=never | sed -r -e "s/(^| )( ' + local init_t = '/usr/bin/cal | sed -r -e "s/(^| )( ' if offs == 0 then -- current month showing, today highlighted From 370a209580ee7ad57e957355e6b2e8dfadb400ab Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 16 Feb 2014 11:05:58 +0100 Subject: [PATCH 411/546] readme updated --- README.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.rst b/README.rst index f59c04d..23cfb9d 100644 --- a/README.rst +++ b/README.rst @@ -17,6 +17,8 @@ Successor of awesome-vain_, this module provides new layouts, a set of widgets a Read the wiki_ for all the info. +**Note that**: this module requires Awesome version 3.5 or higher. + Contributions ------------- From 695ea033dc1188f5c3e80bf6fc839ec332c24499 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 16 Feb 2014 11:08:21 +0100 Subject: [PATCH 412/546] readme updated --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 23cfb9d..1d15555 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ Successor of awesome-vain_, this module provides new layouts, a set of widgets a Read the wiki_ for all the info. -**Note that**: this module requires Awesome version 3.5 or higher. +**Note that** this module requires Awesome version 3.5 or higher. Contributions ------------- From a20aed82096be8e33461d078b615f788c35704f7 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 18 Feb 2014 10:47:19 +0100 Subject: [PATCH 413/546] readme updated --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 1d15555..ca6569b 100644 --- a/README.rst +++ b/README.rst @@ -34,7 +34,7 @@ Just make sure that: - You eventually update ``wiki`` submodule with a thorough section. -Contributed widgets have to be put in ``lain/widget/contrib``. +Contributed widgets have to be put in ``lain/widgets/contrib``. Screenshots ----------- From 81b4ee282b24a89646f241c34699be9cc07cd50b Mon Sep 17 00:00:00 2001 From: Ayman Khamouma Date: Tue, 18 Feb 2014 13:42:16 +0200 Subject: [PATCH 414/546] use awful.tag.gettags in order to keep compatibility with custom configs such as tyrannical --- util/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/init.lua b/util/init.lua index 1dfff65..2f28b9a 100644 --- a/util/init.lua +++ b/util/init.lua @@ -146,7 +146,7 @@ function util.tag_view_nonempty(direction, sc) local s = sc or mouse.screen or 1 local scr = screen[s] - for i = 1, #tags[s] do + for i = 1, #awful.tag.gettags(s) do awful.tag.viewidx(direction,s) if #awful.client.visible(s) > 0 then return From f614a3885a7bcde14352189e1c6cb4afb450f214 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 22 Feb 2014 14:38:19 +0100 Subject: [PATCH 415/546] readme updated --- README.rst | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index ca6569b..a06b64e 100644 --- a/README.rst +++ b/README.rst @@ -1,9 +1,9 @@ Lain ==== ---------------------------------------------- -Layouts, widgets and utilities for Awesome WM ---------------------------------------------- +-------------------------------------------------- +Layouts, widgets and utilities for Awesome WM 3.5+ +-------------------------------------------------- :Author: Luke Bonham :Version: git @@ -17,8 +17,6 @@ Successor of awesome-vain_, this module provides new layouts, a set of widgets a Read the wiki_ for all the info. -**Note that** this module requires Awesome version 3.5 or higher. - Contributions ------------- From eebe054e5af68ce52c8b46f5202b100ab9706a87 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 4 Mar 2014 09:54:43 +0100 Subject: [PATCH 416/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index b56a779..fc181b7 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit b56a779e276987cb9f8f8d81785d35633db047d1 +Subproject commit fc181b7e13ebd4b63b0e2bdc6e170101a022f783 From 6cb63ddff6d4677343fb98897c4cc6bb99c9a2f8 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 11 Mar 2014 20:31:00 +0100 Subject: [PATCH 417/546] yawn: #31 fix + zh_CN added --- widgets/yawn/init.lua | 3 +- widgets/yawn/localizations/zh_CN | 60 ++++++++++++++++++++++++++++++++ wiki | 2 +- 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 widgets/yawn/localizations/zh_CN diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 3f08cd5..86a2d0f 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -135,7 +135,8 @@ local function fetch_weather() yawn.icon:set_image(sky) widget = yawn.widget - forecast = weather_data:match(": %S.-,"):gsub(": ", ""):gsub(",", "") + _data = weather_data:match(": %S.-,") or weather_data + forecast = _data:gsub(": ", ""):gsub(",", "") units = units:gsub(" ", "") settings() diff --git a/widgets/yawn/localizations/zh_CN b/widgets/yawn/localizations/zh_CN new file mode 100644 index 0000000..681bc60 --- /dev/null +++ b/widgets/yawn/localizations/zh_CN @@ -0,0 +1,60 @@ +Now:|当前: +Sun:|周日: +Mon:|周一: +Tue:|周二: +Wed:|周三: +Thu:|周四: +Fri:|周五: +Sat:|周六: +Mostly Sunny|晴时多云 +Sunny|阳光 +Sun|太阳 +Rain/Thunder|雨/雷 +Isolated Thunderstorms|局部雷雨 +Scattered Thunderstorms|零星雷雨 +Thundershowers|雷阵雨 +Thunderstorms|雷雨 +Thunder in the Vicinity|周围有雷雨 +Thunder|雷鸣 +AM|上午 +PM|下午 +Early|早 +Late|晚 +Few|短暂 +Severe|恶劣 +Clear|晴朗 +Fair|晴 +Partly|局部 +Mostly|大部 +Cloudy|多云 +Clouds|有云 +Scattered Showers|零星阵雨 +Light Snow Showers|小阵雪 +Snow Showers|阵雪 +Heavy Snow|大雪 +Scattered Snow Showers|零星阵雪 +Mixed Rain And Snow|雨夹雪 +Mixed Rain And Sleet|雨加雹 +Mixed Snow And Sleet|雪加雹 +Mixed Rain And Hail|雨加冰雹 +Snow Flurries|阵雪 +Blowing Snow|风吹雪 +Blowing Rain|风吹雨 +Heavy Rain|大雨 +Freezing Rain|冻雨 +Showers|阵雨 +Light Rain|小雨 +Heavy|大 +Rain|雨 +Windy|有风 +Wind|风 +Snow|雪 +Sleet|雹 +Freezing Drizzle|冻毛雨 +Light Drizzle|微雨 +Drizzle|毛毛雨 +Hail|冰雹 +Fog|雾 +Foggy|有雾 +Haze|薄雾 +Light|小 \ No newline at end of file diff --git a/wiki b/wiki index fc181b7..434d32a 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit fc181b7e13ebd4b63b0e2bdc6e170101a022f783 +Subproject commit 434d32a7dac5770ed7ddd1581967df7d7aeb76be From 4f0aff52ebd296b84d9fcbc6432dd1384ddb820f Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 11 Mar 2014 21:35:43 +0100 Subject: [PATCH 418/546] typos --- widgets/imap.lua | 2 +- widgets/yawn/localizations/zh_CN | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/imap.lua b/widgets/imap.lua index 39518bd..febff23 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -67,7 +67,7 @@ local function worker(args) widget = imap.widget settings() - if mailcount > helpers.get_map(mail) and mailcount >= 1 + if mailcount >= 1 and mailcount > helpers.get_map(mail) then if mailcount == 1 then nt = mail .. " has one new message" diff --git a/widgets/yawn/localizations/zh_CN b/widgets/yawn/localizations/zh_CN index 681bc60..20de61e 100644 --- a/widgets/yawn/localizations/zh_CN +++ b/widgets/yawn/localizations/zh_CN @@ -57,4 +57,4 @@ Hail|冰雹 Fog|雾 Foggy|有雾 Haze|薄雾 -Light|小 \ No newline at end of file +Light|小 From 8ef1e77de978c984b0e9c7982c87cc9514c45cbc Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 11 Mar 2014 21:38:49 +0100 Subject: [PATCH 419/546] typos --- widgets/yawn/localizations/zh_CN | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widgets/yawn/localizations/zh_CN b/widgets/yawn/localizations/zh_CN index 20de61e..ae8dfdf 100644 --- a/widgets/yawn/localizations/zh_CN +++ b/widgets/yawn/localizations/zh_CN @@ -58,3 +58,5 @@ Fog|雾 Foggy|有雾 Haze|薄雾 Light|小 + + From ee70f4834d39083cdaa47cd66d7fb1a942990150 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 11 Mar 2014 21:44:22 +0100 Subject: [PATCH 420/546] #32 fix attempt --- widgets/bat.lua | 6 +++--- widgets/yawn/localizations/zh_CN | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index 485fd57..cc0eac1 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -122,16 +122,16 @@ local function worker(args) settings() -- notifications for low and critical states - bat_now.perc = tonumber(bat_now.perc) + local nperc = tonumber(bat_now.perc) if bat_now.status == "Discharging" and notify == "on" and bat_now.perc ~= nil then - if bat_now.perc <= 5 + if nperc <= 5 then bat.id = naughty.notify({ preset = bat_notification_critical_preset, replaces_id = bat.id }).id - elseif bat_now.perc <= 15 + elseif nperc <= 15 then bat.id = naughty.notify({ preset = bat_notification_low_preset, diff --git a/widgets/yawn/localizations/zh_CN b/widgets/yawn/localizations/zh_CN index ae8dfdf..20de61e 100644 --- a/widgets/yawn/localizations/zh_CN +++ b/widgets/yawn/localizations/zh_CN @@ -58,5 +58,3 @@ Fog|雾 Foggy|有雾 Haze|薄雾 Light|小 - - From 4e37cf0b229de355f1f83778ae002597fdc8d028 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 11 Mar 2014 21:50:44 +0100 Subject: [PATCH 421/546] #32 fix attempt --- widgets/bat.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index cc0eac1..c14e94c 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -122,9 +122,9 @@ local function worker(args) settings() -- notifications for low and critical states - local nperc = tonumber(bat_now.perc) if bat_now.status == "Discharging" and notify == "on" and bat_now.perc ~= nil then + local nperc = tonumber(bat_now.perc) if nperc <= 5 then bat.id = naughty.notify({ From 07c4b8c5ce42d2cad3c0745ea1510d8a566bd8df Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 15 Mar 2014 11:13:26 +0100 Subject: [PATCH 422/546] #32 fix attempt 2 --- widgets/bat.lua | 2 +- wiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/bat.lua b/widgets/bat.lua index c14e94c..1d8f8c3 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -124,7 +124,7 @@ local function worker(args) -- notifications for low and critical states if bat_now.status == "Discharging" and notify == "on" and bat_now.perc ~= nil then - local nperc = tonumber(bat_now.perc) + local nperc = tonumber(bat_now.perc) or 100 if nperc <= 5 then bat.id = naughty.notify({ diff --git a/wiki b/wiki index 434d32a..b35f693 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 434d32a7dac5770ed7ddd1581967df7d7aeb76be +Subproject commit b35f6931d9685d53e10a051c1d558151331b041f From b0cc3f9d4079c4df94f65e12176c12f199954493 Mon Sep 17 00:00:00 2001 From: zheng Date: Fri, 14 Mar 2014 21:59:40 +0800 Subject: [PATCH 423/546] modify localization for zh_CN --- widgets/yawn/localizations/zh_CN | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/widgets/yawn/localizations/zh_CN b/widgets/yawn/localizations/zh_CN index 20de61e..53b0219 100644 --- a/widgets/yawn/localizations/zh_CN +++ b/widgets/yawn/localizations/zh_CN @@ -7,7 +7,7 @@ Thu:|周四: Fri:|周五: Sat:|周六: Mostly Sunny|晴时多云 -Sunny|阳光 +Sunny|晴朗 Sun|太阳 Rain/Thunder|雨/雷 Isolated Thunderstorms|局部雷雨 @@ -34,9 +34,9 @@ Snow Showers|阵雪 Heavy Snow|大雪 Scattered Snow Showers|零星阵雪 Mixed Rain And Snow|雨夹雪 -Mixed Rain And Sleet|雨加雹 -Mixed Snow And Sleet|雪加雹 -Mixed Rain And Hail|雨加冰雹 +Mixed Rain And Sleet|雨转雨夹雪 +Mixed Snow And Sleet|雪转雨夹雪 +Mixed Rain And Hail|雨夹冰雹 Snow Flurries|阵雪 Blowing Snow|风吹雪 Blowing Rain|风吹雨 @@ -49,12 +49,12 @@ Rain|雨 Windy|有风 Wind|风 Snow|雪 -Sleet|雹 -Freezing Drizzle|冻毛雨 -Light Drizzle|微雨 +Sleet|冻雨 +Freezing Drizzle|冻毛毛雨 +Light Drizzle|细雨 Drizzle|毛毛雨 Hail|冰雹 Fog|雾 Foggy|有雾 -Haze|薄雾 +Haze|霾 Light|小 From 284e4b434724fd8d1ee0b8d54de6b98530c5ba86 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 30 Mar 2014 12:30:59 +0200 Subject: [PATCH 424/546] calendar: cal variable added --- widgets/calendar.lua | 7 ++++--- wiki | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index c9e265a..bd7f08c 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -37,13 +37,13 @@ function calendar:show(t_out, inc_offset) local tims = t_out or 0 local f, c_text local today = tonumber(os.date('%d')) - local init_t = '/usr/bin/cal | sed -r -e "s/(^| )( ' + local init_t = calendar.cal .. ' | sed -r -e "s/(^| )( ' if offs == 0 then -- current month showing, today highlighted if today >= 10 then - init_t = '/usr/bin/cal | sed -r -e "s/(^| )(' + init_t = calendar.cal .. ' | sed -r -e "s/(^| )(' end calendar.offset = 0 @@ -80,7 +80,7 @@ function calendar:show(t_out, inc_offset) calendar.notify_icon = nil - f = io.popen('/usr/bin/cal ' .. month .. ' ' .. year) + f = io.popen(calendar.cal .. ' ' .. month .. ' ' .. year) end c_text = "= 10 then @@ -61,7 +63,6 @@ function calendar:show(t_out, inc_offset) local month = tonumber(os.date('%m')) local year = tonumber(os.date('%Y')) - calendar.offset = calendar.offset + offs month = month + calendar.offset if month > 12 then From 6983b919cd4a6c088cd899d42dddf8d7b6ff57be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=20Kl=C3=A4rner?= Date: Thu, 10 Apr 2014 12:28:20 +0200 Subject: [PATCH 428/546] ask df for a specific filesystem POSIX df supports requesting a single filesystem, so doing so will ensure that df can only get stuck if the filesystem we requested is in a hung state. --- widgets/fs.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/fs.lua b/widgets/fs.lua index 7406e05..4d9d278 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -67,7 +67,7 @@ local function worker(args) fs_info = {} fs_now = {} - local f = io.popen("LC_ALL=C df -kP") + local f = io.popen("LC_ALL=C df -kP " .. partition) for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount) local s = string.match(line, "^.-[%s]([%d]+)") From c75eff7fc0f24d80f9b7a97e87149c199fbb7cec Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 11 Apr 2014 09:36:22 +0200 Subject: [PATCH 429/546] wiki updated for pull #39 --- widgets/fs.lua | 4 +--- wiki | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/widgets/fs.lua b/widgets/fs.lua index 4d9d278..79f821e 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -50,7 +50,7 @@ function fs:show(t_out) }) end --- Units definitions +-- Unit definitions local unit = { ["mb"] = 1024, ["gb"] = 1024^2 } local function worker(args) @@ -84,8 +84,6 @@ local function worker(args) f:close() - -- chosen partition easy stuff - -- you can however check whatever partition else fs_now.used = tonumber(fs_info[partition .. " used_p"]) or 0 fs_now.available = tonumber(fs_info[partition .. " avail_p"]) or 0 fs_now.size_mb = tonumber(fs_info[partition .. " size_mb"]) or 0 diff --git a/wiki b/wiki index bff87f6..571b618 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit bff87f6bb0d1707d0f089a4449082ce43b121275 +Subproject commit 571b618dce199ba0e349c8c6498f08df45150329 From 97c30456b00d1829439eef5fab62e4ee2c5533d5 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 12 Apr 2014 15:01:43 +0200 Subject: [PATCH 430/546] revert #36; fix #41 --- widgets/mpd.lua | 3 +-- wiki | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index d8bcd78..1749b57 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -10,7 +10,6 @@ local helpers = require("lain.helpers") local escape_f = require("awful.util").escape -local surface = require("gears").surface local naughty = require("naughty") local wibox = require("wibox") @@ -92,7 +91,7 @@ local function worker(args) mpd.id = naughty.notify({ preset = mpd_notification_preset, - icon = surface.load_uncached("/tmp/mpdcover.png"), + icon = "/tmp/mpdcover.png", replaces_id = mpd.id }).id end diff --git a/wiki b/wiki index 571b618..54b3a71 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 571b618dce199ba0e349c8c6498f08df45150329 +Subproject commit 54b3a717b2f7069264ce5a20018ae4abf153e7b2 From ec7c9cd9a6ade89eefada0e04c30cd300acedd4a Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Tue, 29 Apr 2014 12:58:25 +0200 Subject: [PATCH 431/546] cpu widget calc fix --- widgets/cpu.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/cpu.lua b/widgets/cpu.lua index 0b21edc..7c1ecb0 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -43,9 +43,9 @@ local function worker(args) local total = 0 for field in string.gmatch(times, "[%s]+([^%s]+)") do - -- 3 = idle, 4 = ioWait. Essentially, the CPUs have done + -- 4 = idle, 5 = ioWait. Essentially, the CPUs have done -- nothing during these times. - if at == 3 or at == 4 + if at == 4 or at == 5 then idle = idle + field end From 6cdc863f0038910523e2bce56c9091ccc78f80e6 Mon Sep 17 00:00:00 2001 From: Andrea Scarpino Date: Sun, 13 Apr 2014 12:19:02 +0200 Subject: [PATCH 432/546] net: optional notifications --- widgets/net.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/widgets/net.lua b/widgets/net.lua index af97201..08c7366 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -44,6 +44,7 @@ local function worker(args) local timeout = args.timeout or 2 local iface = args.iface or net.get_device() local units = args.units or 1024 --kb + local notify = args.notify or "on" local settings = args.settings or function() end net.widget = wibox.widget.textbox('') @@ -76,7 +77,7 @@ local function worker(args) net.last_t = now_t net.last_r = now_r - if net_now.carrier ~= "1" + if net_now.carrier ~= "1" and notify == "on" then if helpers.get_map(iface) then From c6bb2f478287fb0a22d89b2e33f1b25692bc27fa Mon Sep 17 00:00:00 2001 From: Thomas Etcheverria Date: Sun, 20 Apr 2014 16:04:39 +0200 Subject: [PATCH 433/546] add yawn localization fr_FR --- widgets/yawn/localizations/fr_FR | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 widgets/yawn/localizations/fr_FR diff --git a/widgets/yawn/localizations/fr_FR b/widgets/yawn/localizations/fr_FR new file mode 100644 index 0000000..b88f51d --- /dev/null +++ b/widgets/yawn/localizations/fr_FR @@ -0,0 +1,60 @@ +Now:|Auj: +Sun:|Dim: +Mon:|Lun: +Tue:|Mar: +Wed:|Mer: +Thu:|Jeu: +Fri:|Ven: +Sat:|Sam: +Mostly Sunny| +Sunny|Ensoleillé +Sun|Soleil +Rain/Thunder|Pluie/Orage +Isolated Thunderstorms|Orages localisés +Scattered Thunderstorms|Orages épars +Thundershowers| +Thunderstorms|Orages +Thunder in the Vicinity|Orage aux alentours +Thunder|Orages +AM|Matinée +PM|Après-midi +Early|Tôt +Late|Tard +Few|Quelques +Severe|Sévère +Clear|Clair +Fair|Clair +Partly|Partiellement +Mostly|Très +Cloudy|Nuageux +Clouds|Nuages +Scattered Showers|Nuages épars +Light Snow Showers|Légères averses de neige +Snow Showers|Averses de neige +Heavy Snow|Neige +Scattered Snow Showers|Averses de neige localisées +Mixed Rain And Snow|Alternance de neige et de pluie +Mixed Rain And Sleet|Alternance de pluie et de neige fondue +Mixed Snow And Sleet|Alternance de neige et de neige fondue +Mixed Rain And Hail|Alternance de pluie et de grêle +Snow Flurries|Averses de neige +Blowing Snow|Neige +Blowing Rain|Pluie +Heavy Rain|Pluie forte +Freezing Rain|Pluie verglaçante +Showers|Averses +Light Rain|Pluie légère +Heavy|Forte +Rain|Pluie +Windy|Venteux +Wind|Vent +Snow|Neige +Sleet|Neige fondue +Freezing Drizzle|Bruine verglaçante +Light Drizzle|Légère bruine +Drizzle|Bruine +Hail|Grêle +Fog|Brouillard +Foggy|Brumeux +Haze|Brume +Light|Clair \ No newline at end of file From 135df3e1830cc656ae091868d4019fceb9454f5d Mon Sep 17 00:00:00 2001 From: Thomas Etcheverria Date: Mon, 21 Apr 2014 22:28:47 +0200 Subject: [PATCH 434/546] fix missing --- widgets/yawn/localizations/fr_FR | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/yawn/localizations/fr_FR b/widgets/yawn/localizations/fr_FR index b88f51d..444b02c 100644 --- a/widgets/yawn/localizations/fr_FR +++ b/widgets/yawn/localizations/fr_FR @@ -6,13 +6,13 @@ Wed:|Mer: Thu:|Jeu: Fri:|Ven: Sat:|Sam: -Mostly Sunny| +Mostly Sunny|Partiellement ensoleillé Sunny|Ensoleillé Sun|Soleil Rain/Thunder|Pluie/Orage Isolated Thunderstorms|Orages localisés Scattered Thunderstorms|Orages épars -Thundershowers| +Thundershowers|Tempête Thunderstorms|Orages Thunder in the Vicinity|Orage aux alentours Thunder|Orages From 34e47e46ff708d3b79c824dacc614b47a286eefe Mon Sep 17 00:00:00 2001 From: Thierry Ghelew Date: Wed, 7 May 2014 17:29:51 +0200 Subject: [PATCH 436/546] fix maildir and /util/init.lua which was not counting email properly and lacking function util.element_in_table function --- util/init.lua | 10 ++++++++++ widgets/maildir.lua | 9 ++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/util/init.lua b/util/init.lua index 2f28b9a..d99f007 100644 --- a/util/init.lua +++ b/util/init.lua @@ -210,4 +210,14 @@ function util.useless_gaps_resize(thatmuch) awful.layout.arrange(mouse.screen) end +-- Check if an element exist on a table +function util.element_in_table(element, tbl) + for _, i in pairs(tbl) do + if i == element then + return true + end + end + return false +end + return setmetatable(util, { __index = wrequire }) diff --git a/widgets/maildir.lua b/widgets/maildir.lua index d460881..8fe097e 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -11,6 +11,8 @@ local newtimer = require("lain.helpers").newtimer local wibox = require("wibox") +local util = require("lain.util") + local io = io local os = { getenv = os.getenv } local pairs = pairs @@ -66,15 +68,16 @@ local function worker(args) table.sort(boxes) newmail = "no mail" + --Count the total number of mails irrespective of where it was found + total = 0 - local count = 0 for box, number in pairs(boxes) do - count = count + 1 -- Add this box only if it's not to be ignored. if not util.element_in_table(box, ignore_boxes) then - if newmail == "" + total = total + number + if newmail == "no mail" then newmail = box .. "(" .. number .. ")" else From b7b019e48cbda5f5afbf724fd376191c6a440006 Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Thu, 8 May 2014 15:10:57 +0200 Subject: [PATCH 437/546] yawn: language failsafe --- widgets/yawn/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 86a2d0f..4109d6c 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -36,7 +36,7 @@ local localizations_path = project_path .. 'localizations/' local icon_path = project_path .. 'icons/' local api_url = 'http://weather.yahooapis.com/forecastrss' local units_set = '?u=c&w=' -- Default is Celsius -local language = string.match(os.getenv("LANG"), "(%S*$*)[.]") +local language = string.match(os.getenv("LANG"), "(%S*$*)[.]") or "en_US" -- if LANG is not set local weather_data = nil local notification = nil local city_id = nil From 2836fff52e31eccd159133f7ea8dc207e86c2754 Mon Sep 17 00:00:00 2001 From: Lukas Geis Date: Tue, 27 May 2014 15:54:37 +0200 Subject: [PATCH 438/546] Redshift widget and icons added --- icons/redshift/redshift_off.png | Bin 0 -> 267 bytes icons/redshift/redshift_on.png | Bin 0 -> 253 bytes widgets/contrib/redshift.lua | 79 ++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 icons/redshift/redshift_off.png create mode 100644 icons/redshift/redshift_on.png create mode 100644 widgets/contrib/redshift.lua diff --git a/icons/redshift/redshift_off.png b/icons/redshift/redshift_off.png new file mode 100644 index 0000000000000000000000000000000000000000..a92200fcde26a71dafbbc196264e9f3f7b720e93 GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|wj^(N7l!{JxM1({$v_d#0*}aI z1_o|n5N2eUHAey{$X?><>&kwQRhpNT%Pxsc5-22_84^+AoS&PUnpXnkGB7w7r6!i7 zrYMwWmSiZnd-?{X=%um)#q&K~978NlCnrd3YY>cGkaV(skxAK+1zD*Fm+#o(BzpA9 zyT02!JFXZBW^?En?$K+?bSQVsY<>0r64%xLH)7f@yWSAFd^FqV$gZ{tGM*dT_%}?* zGQP+uB)Mm5pkv|050kBXRHR$9TNf{Xaq#t`gX|1Z0mk~9wjY%NxyjSj&t;ucLK6TD C<>&kwQRhpMg;@LNqNkAdl%#er@=ltB<)VvZPmw~~#C^fMp zHASI3vm`^o-P1Q9MK6^dD4yu);uvCaIypgNTZ3Tif~1r6i%iOnEXYbdxO~SJC()x< z-u2z?*>S~4Fq=cqa1YzV%MIRrol%Xx(aj%Nwe&1k?d)g`nce9(;lzWrJzQQqoc22p ndu(#t5oA%-CAUXUs)m8#$W~?T*MDd7fn4F~>gTe~DWM4fyunhR literal 0 HcmV?d00001 diff --git a/widgets/contrib/redshift.lua b/widgets/contrib/redshift.lua new file mode 100644 index 0000000..38f1d83 --- /dev/null +++ b/widgets/contrib/redshift.lua @@ -0,0 +1,79 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, blueluke + +--]] + +local os = os +local awful = require("awful") +local spawn = awful.util.spawn_with_shell + +local setmetatable = setmetatable + +-- redshift +-- lain.widgets.contrib.redshift +local redshift = {} + +local attached = false -- true if attached to a widget +local active = false -- true if redshift is active +local running = false -- true if redshift was initialized +local update_fnct = function() end -- function that is run each time redshift is toggled. See redshift:attach(). + + +local function init() + -- As there is no way to determine if redshift was previously + -- toggled off (i.e Awesome on-the-fly restart), kill redshift to make sure + os.execute("pkill redshift") + -- Remove existing color adjustment + spawn("redshift -x") + -- (Re)start redshift + spawn("redshift") + running = true + active = true +end + +function redshift:toggle() + if running then + -- Sending -USR1 toggles redshift (See project website) + os.execute("pkill -USR1 redshift") + active = not active + else + init() + end + update_fnct() +end + +function redshift:off() + if running and active then + redshift:toggle() + end +end + +function redshift:on() + if not active then + redshift:toggle() + end +end + +function redshift:is_active() + return active +end + +-- Attach to a widget +-- Provides a button which toggles redshift on/off on click +-- @ param widget: widget to attach to +-- @ param fnct: function to be run each time redshift is toggled (optional). +-- Use it to update widget text or icons on status change. +function redshift:attach(widget, fnct) + update_fnct = fnct or function() end + if not attached then + init() + attached = true + update_fnct() + end + widget:buttons(awful.util.table.join( awful.button({}, 1, function () redshift:toggle() end) )) +end + +return setmetatable(redshift, { _call = function(_, ...) return create(...) end }) From 7ce6653828cd9f046a51b2052ce7f973b3d4ff5d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 2 Jun 2014 10:28:42 +0200 Subject: [PATCH 439/546] #49 fix --- widgets/calendar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index f3d7b8a..61451fc 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -45,7 +45,7 @@ function calendar:show(t_out, inc_offset) then -- current month showing, today highlighted if today >= 10 then - init_t = calendar.cal .. ' | sed -r -e "s/(^| )(' + init_t = calendar.cal .. ' | sed -r -e "s/_\\x08//g" | sed -r -e "s/(^| )(' end calendar.offset = 0 From ce9c97aa927a448ca4158104538118c350114b22 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 13 Jun 2014 09:44:36 +0200 Subject: [PATCH 440/546] #52 fix + multiple imap widgets feature added --- widgets/base.lua | 4 ++-- widgets/imap.lua | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/widgets/base.lua b/widgets/base.lua index 3d4ce9e..4f28e07 100644 --- a/widgets/base.lua +++ b/widgets/base.lua @@ -14,9 +14,9 @@ local setmetatable = setmetatable -- Basic template for custom widgets -- lain.widgets.base -local base = {} local function worker(args) + local base = {} local args = args or {} local timeout = args.timeout or 5 local cmd = args.cmd or "" @@ -37,4 +37,4 @@ local function worker(args) return setmetatable(base, { __index = base.widget }) end -return setmetatable(base, { __call = function(_, ...) return worker(...) end }) +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/imap.lua b/widgets/imap.lua index febff23..6104388 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -20,9 +20,9 @@ local setmetatable = setmetatable -- Mail IMAP check -- lain.widgets.imap -local imap = {} local function worker(args) + local imap = {} local args = args or {} local server = args.server @@ -81,7 +81,7 @@ local function worker(args) end helpers.newtimer(mail, timeout, update, true) - return imap.widget + return setmetatable(imap, { __index = imap.widget }) end -return setmetatable(imap, { __call = function(_, ...) return worker(...) end }) +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) From b3e4d796d0aa6e2f697aa61b6d89f5e754703d01 Mon Sep 17 00:00:00 2001 From: WooParadog Date: Sat, 19 Jul 2014 22:36:15 +0800 Subject: [PATCH 441/546] show notification window in focused screen --- widgets/alsabar.lua | 30 ++++++++++++++++-------------- widgets/bat.lua | 6 ++++-- widgets/calendar.lua | 3 ++- widgets/contrib/task.lua | 10 +++++++--- widgets/contrib/tpbat/init.lua | 12 ++++++++---- widgets/fs.lua | 7 ++++--- widgets/imap.lua | 6 +++++- widgets/mpd.lua | 3 ++- widgets/net.lua | 3 ++- widgets/yawn/init.lua | 3 ++- 10 files changed, 52 insertions(+), 31 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 365ac2d..4ae12e5 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -54,22 +54,22 @@ local alsabar = function alsabar.notify() alsabar.update() - local preset = - { + local preset = + { title = "", text = "", timeout = 4, font = alsabar.notifications.font .. " " .. alsabar.notifications.font_size, fg = alsabar.notifications.color - } + } - if alsabar._muted + if alsabar._muted then - preset.title = alsabar.channel .. " - Muted" - else - preset.title = alsabar.channel .. " - " .. alsabar._current_level * 100 .. "%" - end + preset.title = alsabar.channel .. " - Muted" + else + preset.title = alsabar.channel .. " - " .. alsabar._current_level * 100 .. "%" + end int = math.modf(alsabar._current_level * alsabar.notifications.bar_size) preset.text = "[" @@ -78,15 +78,17 @@ function alsabar.notify() .. "]" if alsabar._notify ~= nil then - alsabar._notify = naughty.notify ({ + alsabar._notify = naughty.notify ({ replaces_id = alsabar._notify.id, - preset = preset + preset = preset, + screen = client.focus and client.focus.screen or 1 }) - else - alsabar._notify = naughty.notify ({ - preset = preset + else + alsabar._notify = naughty.notify ({ + preset = preset, + screen = client.focus and client.focus.screen or 1 }) - end + end end local function worker(args) diff --git a/widgets/bat.lua b/widgets/bat.lua index 1d8f8c3..2ace758 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -129,13 +129,15 @@ local function worker(args) then bat.id = naughty.notify({ preset = bat_notification_critical_preset, - replaces_id = bat.id + replaces_id = bat.id, + screen = client.focus and client.focus.screen or 1 }).id elseif nperc <= 15 then bat.id = naughty.notify({ preset = bat_notification_low_preset, - replaces_id = bat.id + replaces_id = bat.id, + screen = client.focus and client.focus.screen or 1 }).id end end diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 61451fc..4e6eda7 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -98,7 +98,8 @@ function calendar:show(t_out, inc_offset) position = calendar.position, fg = calendar.fg, bg = calendar.bg, - timeout = tims + timeout = tims, + screen = client.focus and client.focus.screen or 1 }) end diff --git a/widgets/contrib/task.lua b/widgets/contrib/task.lua index a6c9f31..6e6ebae 100644 --- a/widgets/contrib/task.lua +++ b/widgets/contrib/task.lua @@ -51,7 +51,9 @@ function task:show() position = task.position, fg = task.fg, bg = task.bg, - timeout = task.timeout }) + timeout = task.timeout, + screen = client.focus and client.focus.screen or 1 + }) end function task:prompt_add() @@ -72,7 +74,8 @@ function task:prompt_add() position = task.position, fg = task.fg, bg = task.bg, - timeout = task.timeout + timeout = task.timeout, + screen = client.focus and client.focus.screen or 1 }) end, nil, @@ -105,7 +108,8 @@ function task:prompt_search() position = task.position, fg = task.fg, bg = task.bg, - timeout = task.timeout + timeout = task.timeout, + screen = client.focus and client.focus.screen or 1 }) end, nil, diff --git a/widgets/contrib/tpbat/init.lua b/widgets/contrib/tpbat/init.lua index 72d6453..782bf35 100644 --- a/widgets/contrib/tpbat/init.lua +++ b/widgets/contrib/tpbat/init.lua @@ -75,7 +75,8 @@ function tpbat:show(t_out) tpbat_notification = naughty.notify({ preset = { fg = beautiful.fg_normal }, text = str, - timeout = t_out + timeout = t_out, + screen = client.focus and client.focus.screen or 1 }) end @@ -111,7 +112,8 @@ function tpbat.register(args) local n = naughty.notify({ preset = bat_notification_low_preset, title = "SMAPI Battery Warning: Unable to read battery state!", - text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths." + text = "This widget is intended for ThinkPads. Is tp_smapi installed? Check your configs & paths.", + screen = client.focus and client.focus.screen or 1 }) end @@ -137,13 +139,15 @@ function tpbat.register(args) then tpbat.id = naughty.notify({ preset = bat_notification_critical_preset, - replaces_id = tpbat.id + replaces_id = tpbat.id, + screen = client.focus and client.focus.screen or 1 }).id elseif bat_now.perc <= 15 then tpbat.id = naughty.notify({ preset = bat_notification_low_preset, - replaces_id = tpbat.id + replaces_id = tpbat.id, + screen = client.focus and client.focus.screen or 1 }).id end end diff --git a/widgets/fs.lua b/widgets/fs.lua index 79f821e..867ce3f 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -46,7 +46,8 @@ function fs:show(t_out) notification = naughty.notify({ preset = fs_notification_preset, text = ws, - timeout = t_out + timeout = t_out, + screen = client.focus and client.focus.screen or 1 }) end @@ -66,7 +67,6 @@ local function worker(args) function update() fs_info = {} fs_now = {} - local f = io.popen("LC_ALL=C df -kP " .. partition) for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount) @@ -99,7 +99,8 @@ local function worker(args) text = partition .. " ran out!\nmake some room", timeout = 8, fg = "#000000", - bg = "#FFFFFF" + bg = "#FFFFFF", + screen = client.focus and client.focus.screen or 1 }) helpers.set_map("fs", true) else diff --git a/widgets/imap.lua b/widgets/imap.lua index 6104388..c404032 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -74,7 +74,11 @@ local function worker(args) else nt = mail .. " has " .. mailcount .. " new messages" end - naughty.notify({ preset = mail_notification_preset, text = nt }) + naughty.notify({ + preset = mail_notification_preset, + text = nt, + screen = client.focus and client.focus.screen or 1 + }) end helpers.set_map(mail, mailcount) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 1749b57..73efebb 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -92,7 +92,8 @@ local function worker(args) mpd.id = naughty.notify({ preset = mpd_notification_preset, icon = "/tmp/mpdcover.png", - replaces_id = mpd.id + replaces_id = mpd.id, + screen = client.focus and client.focus.screen or 1 }).id end elseif mpd_now.state ~= "pause" diff --git a/widgets/net.lua b/widgets/net.lua index 08c7366..1e59731 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -87,7 +87,8 @@ local function worker(args) timeout = 7, position = "top_left", icon = helpers.icons_dir .. "no_net.png", - fg = notify_fg or "#FFFFFF" + fg = notify_fg or "#FFFFFF", + screen = client.focus and client.focus.screen or 1 }) helpers.set_map(iface, false) end diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 4109d6c..da2b856 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -161,7 +161,8 @@ function yawn.show(t_out) preset = yawn_notification_preset, text = weather_data, icon = sky, - timeout = t_out + timeout = t_out, + screen = client.focus and client.focus.screen or 1 }) end From a776679884b5d5f6ea026cc215d262b036f6b8b5 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 21 Jul 2014 13:34:40 +0200 Subject: [PATCH 442/546] #54 fix attempt --- widgets/alsabar.lua | 84 +++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 4ae12e5..4430e76 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -24,70 +24,66 @@ local setmetatable = setmetatable -- ALSA volume bar -- lain.widgets.alsabar -local alsabar = -{ - channel = "Master", - step = "5%", +local alsabar = { + channel = "Master", + step = "5%", - colors = - { - background = beautiful.bg_normal, - mute = "#EB8F8F", - unmute = "#A4CE8A" - }, + colors = { + background = beautiful.bg_normal, + mute = "#EB8F8F", + unmute = "#A4CE8A" + }, - terminal = terminal or "xterm", - mixer = terminal .. " -e alsamixer", + terminal = terminal or "xterm", + mixer = terminal .. " -e alsamixer", - notifications = - { - font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), - font_size = "11", - color = beautiful.fg_normal, - bar_size = 18 - }, + notifications = { + font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), + font_size = "11", + color = beautiful.fg_normal, + bar_size = 18 + }, - _current_level = 0, - _muted = false + _current_level = 0, + _muted = false } function alsabar.notify() - alsabar.update() + alsabar.update() - local preset = - { - title = "", - text = "", - timeout = 4, - font = alsabar.notifications.font .. " " .. - alsabar.notifications.font_size, - fg = alsabar.notifications.color + local preset = { + title = "", + text = "", + timeout = 4, + font = alsabar.notifications.font .. " " .. + alsabar.notifications.font_size, + fg = alsabar.notifications.color } if alsabar._muted - then + then preset.title = alsabar.channel .. " - Muted" else - preset.title = alsabar.channel .. " - " .. alsabar._current_level * 100 .. "%" + preset.title = alsabar.channel .. " - " .. alsabar._current_level .. "%" end - int = math.modf(alsabar._current_level * alsabar.notifications.bar_size) - preset.text = "[" + int = math.modf((alsabar._current_level / 100) * alsabar.notifications.bar_size) + preset.text = "[" .. string.rep("|", int) .. string.rep(" ", alsabar.notifications.bar_size - int) .. "]" - if alsabar._notify ~= nil then + if alsabar._notify ~= nil then alsabar._notify = naughty.notify ({ - replaces_id = alsabar._notify.id, - preset = preset, - screen = client.focus and client.focus.screen or 1 - }) + replaces_id = alsabar._notify.id, + preset = preset, + screen = client.focus and client.focus.screen or 1 + }) else alsabar._notify = naughty.notify ({ - preset = preset, - screen = client.focus and client.focus.screen or 1 - }) + preset = preset, + screen = client.focus and client.focus.screen or 1 + }) end end @@ -131,8 +127,8 @@ local function worker(args) mute = "off" end - alsabar._current_level = tonumber(volu) / 100 - alsabar.bar:set_value(alsabar._current_level) + alsabar._current_level = tonumber(volu) + alsabar.bar:set_value(alsabar._current_level / 100) if not mute and tonumber(volu) == 0 or mute == "off" then From b9e2596cbddd1d932aa4b6bbd2226a6016b1004e Mon Sep 17 00:00:00 2001 From: WooParadog Date: Sat, 26 Jul 2014 10:17:49 +0800 Subject: [PATCH 443/546] Add -M to amixer. -M Use the mapped volume for evaluating the percentage representation like alsamixer, to be more natural for human ear. --- widgets/alsa.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 28bb05c..4ed4f9c 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -29,7 +29,7 @@ local function worker(args) alsa.widget = wibox.widget.textbox('') function alsa.update() - local f = assert(io.popen('amixer get ' .. channel)) + local f = assert(io.popen('amixer -M get ' .. channel)) local mixer = f:read("*all") f:close() From 7efdce351006dca20d56ef943819f416e4c41e00 Mon Sep 17 00:00:00 2001 From: WooParadog Date: Sat, 26 Jul 2014 10:24:38 +0800 Subject: [PATCH 444/546] pass -M to amixer in alsabar --- widgets/alsabar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 4430e76..e185c76 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -115,7 +115,7 @@ local function worker(args) function alsabar.update() -- Get mixer control contents - local f = io.popen("amixer get " .. alsabar.channel) + local f = io.popen("amixer -M get " .. alsabar.channel) local mixer = f:read("*all") f:close() From b7c3cb77a1ca72ab8fb91c8618f8703e3c1e446c Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 5 Aug 2014 12:59:19 +0200 Subject: [PATCH 445/546] IMAP wiget is now asynchronous --- asyncshell.lua | 80 ++++++++++++++++++++++++++++++++++++++++++++ widgets/alsa.lua | 2 +- widgets/alsabar.lua | 2 +- widgets/base.lua | 2 +- widgets/calendar.lua | 2 +- widgets/cpu.lua | 2 +- widgets/fs.lua | 2 +- widgets/imap.lua | 47 ++++++++++++++------------ widgets/maildir.lua | 2 +- widgets/net.lua | 2 +- widgets/sysload.lua | 2 +- widgets/temp.lua | 2 +- 12 files changed, 115 insertions(+), 32 deletions(-) create mode 100644 asyncshell.lua diff --git a/asyncshell.lua b/asyncshell.lua new file mode 100644 index 0000000..c05fb6b --- /dev/null +++ b/asyncshell.lua @@ -0,0 +1,80 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2013, Alexander Yakushev + +--]] + +-- Asynchronous io.popen for Awesome WM. +-- How to use... +-- ...asynchronously: +-- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end) +-- ...synchronously +-- wwidget.text = asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error" + +local spawn = require('awful.util').spawn + +asyncshell = {} +asyncshell.request_table = {} +asyncshell.id_counter = 0 +asyncshell.folder = "/tmp/asyncshell" +asyncshell.file_template = asyncshell.folder .. '/req' + +-- Create a directory for asynchell response files +os.execute("mkdir -p " .. asyncshell.folder) + +-- Returns next tag - unique identifier of the request +local function next_id() + asyncshell.id_counter = (asyncshell.id_counter + 1) % 100000 + return asyncshell.id_counter +end + +-- Sends an asynchronous request for an output of the shell command. +-- @param command Command to be executed and taken output from +-- @param callback Function to be called when the command finishes +-- @return Request ID +function asyncshell.request(command, callback) + local id = next_id() + local tmpfname = asyncshell.file_template .. id + asyncshell.request_table[id] = {callback = callback} + local req = + string.format("bash -c '%s > %s; " .. + 'echo "asyncshell.deliver(%s)" | ' .. + "awesome-client' 2> /dev/null", + string.gsub(command, "'", "'\\''"), tmpfname, + id, tmpfname) + spawn(req, false) + return id +end + +-- Calls the remembered callback function on the output of the shell +-- command. +-- @param id Request ID +-- @param output The output file of the shell command to be delievered +function asyncshell.deliver(id) + if asyncshell.request_table[id] and + asyncshell.request_table[id].callback then + local output = io.open(asyncshell.file_template .. id, 'r') + asyncshell.request_table[id].callback(output) + end +end + +-- Sends a synchronous request for an output of the command. Waits for +-- the output, but if the given timeout expires returns nil. +-- @param command Command to be executed and taken output from +-- @param timeout Maximum amount of time to wait for the result +-- @return File handler on success, nil otherwise +function asyncshell.demand(command, timeout) + local id = next_id() + local tmpfname = asyncshell.file_template .. id + local f = io.popen(string.format("(%s > %s; echo asyncshell_done) & " .. + "(sleep %s; echo asynchell_timeout)", + command, tmpfname, timeout)) + local result = f:read("*line") + if result == "asyncshell_done" then + return io.open(tmpfname) + end +end + +return asyncshell diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 4ed4f9c..f62a150 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -30,7 +30,7 @@ local function worker(args) function alsa.update() local f = assert(io.popen('amixer -M get ' .. channel)) - local mixer = f:read("*all") + local mixer = f:read("*a") f:close() volume_now = {} diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index e185c76..8675cb5 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -116,7 +116,7 @@ local function worker(args) function alsabar.update() -- Get mixer control contents local f = io.popen("amixer -M get " .. alsabar.channel) - local mixer = f:read("*all") + local mixer = f:read("*a") f:close() -- Capture mixer control state: [5%] ... ... [on] diff --git a/widgets/base.lua b/widgets/base.lua index 4f28e07..6b808b7 100644 --- a/widgets/base.lua +++ b/widgets/base.lua @@ -26,7 +26,7 @@ local function worker(args) function base.update() local f = assert(io.popen(cmd)) - output = f:read("*all") + output = f:read("*a") f:close() widget = base.widget settings() diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 4e6eda7..c690e3f 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -88,7 +88,7 @@ function calendar:show(t_out, inc_offset) .. calendar.font_size .. "'>" .. f:read() .. "\n\n" .. f:read() .. "\n" - .. f:read("*all"):gsub("\n*$", "") + .. f:read("*a"):gsub("\n*$", "") .. "" f:close() diff --git a/widgets/cpu.lua b/widgets/cpu.lua index 7c1ecb0..96e0d3b 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -58,7 +58,7 @@ local function worker(args) local dactive = active - cpu.last_active local dtotal = total - cpu.last_total - cpu_now = {} + cpu_noj = {} cpu_now.usage = tostring(math.ceil((dactive / dtotal) * 100)) widget = cpu.widget diff --git a/widgets/fs.lua b/widgets/fs.lua index 867ce3f..8127c28 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -40,7 +40,7 @@ function fs:show(t_out) fs:hide() local f = io.popen(helpers.scripts_dir .. "dfs") - ws = f:read("*all"):gsub("\n*$", "") + ws = f:read("*a"):gsub("\n*$", "") f:close() notification = naughty.notify({ diff --git a/widgets/imap.lua b/widgets/imap.lua index c404032..1dca87c 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -7,11 +7,11 @@ --]] local helpers = require("lain.helpers") +local async = require("lain.asyncshell") local naughty = require("naughty") local wibox = require("wibox") -local io = { popen = io.popen } local string = { format = string.format, gsub = string.gsub } local tonumber = tonumber @@ -42,7 +42,7 @@ local function worker(args) if not is_plain then local f = io.popen(password) - password = f:read("*all"):gsub("\n", "") + password = f:read("*a"):gsub("\n", "") f:close() end @@ -57,34 +57,37 @@ local function worker(args) curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%s %s -k", head_command, server, port, mail, password, request) - f = io.popen(curl) - ws = f:read("*all") - f:close() + async.request(curl, function(f) + ws = f:read("*a") + f:close() - _, mailcount = string.gsub(ws, "%d+", "") - _ = nil + _, mailcount = string.gsub(ws, "%d+", "") + _ = nil - widget = imap.widget - settings() + widget = imap.widget + settings() - if mailcount >= 1 and mailcount > helpers.get_map(mail) - then - if mailcount == 1 then - nt = mail .. " has one new message" - else - nt = mail .. " has " .. mailcount .. " new messages" + if mailcount >= 1 and mailcount > helpers.get_map(mail) + then + if mailcount == 1 then + nt = mail .. " has one new message" + else + nt = mail .. " has " .. mailcount .. " new messages" + end + naughty.notify({ + preset = mail_notification_preset, + text = nt, + screen = client.focus and client.focus.screen or 1 + }) end - naughty.notify({ - preset = mail_notification_preset, - text = nt, - screen = client.focus and client.focus.screen or 1 - }) - end - helpers.set_map(mail, mailcount) + helpers.set_map(mail, mailcount) + end) + end helpers.newtimer(mail, timeout, update, true) + return setmetatable(imap, { __index = imap.widget }) end diff --git a/widgets/maildir.lua b/widgets/maildir.lua index 8fe097e..bd79221 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -53,7 +53,7 @@ local function worker(args) local np = io.popen("find " .. line .. "/new -mindepth 1 -type f " .. "-not -name '.*' -printf a") - local mailstring = np:read("*all") + local mailstring = np:read("*a") -- Strip off leading mailpath. local box = string.match(line, mailpath .. "/*([^/]+)") diff --git a/widgets/net.lua b/widgets/net.lua index 1e59731..7851d5a 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -29,7 +29,7 @@ local net = { function net.get_device() f = io.popen("ip link show | cut -d' ' -f2,9") - ws = f:read("*all") + ws = f:read("*a") f:close() ws = ws:match("%w+: UP") if ws ~= nil then diff --git a/widgets/sysload.lua b/widgets/sysload.lua index 2abac33..b15b1bf 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -30,7 +30,7 @@ local function worker(args) function update() local f = io.open("/proc/loadavg") - local ret = f:read("*all") + local ret = f:read("*a") f:close() load_1, load_5, load_15 = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") diff --git a/widgets/temp.lua b/widgets/temp.lua index 61a9aa5..4ae1c04 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -31,7 +31,7 @@ local function worker(args) local f = io.open(tempfile) if f ~= nil then - coretemp_now = tonumber(f:read("*all")) / 1000 + coretemp_now = tonumber(f:read("*a")) / 1000 f:close() else coretemp_now = "N/A" From 3e735d3effeb1c3c94c6c7f01b99d49e31a0d712 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 7 Aug 2014 12:21:02 +0200 Subject: [PATCH 446/546] small fixes --- widgets/yawn/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index da2b856..148f547 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -48,7 +48,7 @@ yawn_notification_preset = {} local function fetch_weather() local url = api_url .. units_set .. city_id local f = io.popen("curl --connect-timeout 1 -fsm 3 '" .. url .. "'" ) - local text = f:read("*all") + local text = f:read("*a") f:close() -- In case of no connection or invalid city ID From c14436760d6e9b61dcf8a25b826b0464be21f612 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 7 Aug 2014 12:21:30 +0200 Subject: [PATCH 447/546] small fixes --- asyncshell.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asyncshell.lua b/asyncshell.lua index c05fb6b..4eb8d2e 100644 --- a/asyncshell.lua +++ b/asyncshell.lua @@ -39,7 +39,7 @@ function asyncshell.request(command, callback) local tmpfname = asyncshell.file_template .. id asyncshell.request_table[id] = {callback = callback} local req = - string.format("bash -c '%s > %s; " .. + string.format("sh -c '%s > %s; " .. 'echo "asyncshell.deliver(%s)" | ' .. "awesome-client' 2> /dev/null", string.gsub(command, "'", "'\\''"), tmpfname, From e00ee3436e0a01827eeda3b5360304eea2a6fb92 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 7 Aug 2014 13:37:24 +0200 Subject: [PATCH 448/546] mpd and yawn widget are now asynchronous --- asyncshell.lua | 2 + widgets/mpd.lua | 81 ++++++++++--------- widgets/yawn/init.lua | 178 +++++++++++++++++++++--------------------- 3 files changed, 133 insertions(+), 128 deletions(-) diff --git a/asyncshell.lua b/asyncshell.lua index 4eb8d2e..51885e8 100644 --- a/asyncshell.lua +++ b/asyncshell.lua @@ -13,6 +13,8 @@ -- ...synchronously -- wwidget.text = asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error" +-- This makes things faster, but puts weight on sysload and is more cpu demanding. + local spawn = require('awful.util').spawn asyncshell = {} diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 73efebb..385b5bb 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -8,6 +8,7 @@ --]] local helpers = require("lain.helpers") +local async = require("lain.asyncshell") local escape_f = require("awful.util").escape local naughty = require("naughty") @@ -50,56 +51,54 @@ local function worker(args) helpers.set_map("current mpd track", nil) function mpd.update() - mpd_now = { - state = "N/A", - file = "N/A", - artist = "N/A", - title = "N/A", - album = "N/A", - date = "N/A" - } + async.request(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh, function (f) + mpd_now = { + state = "N/A", + file = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", + date = "N/A" + } - local f = io.popen(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh) - - for line in f:lines() do - for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do - if k == "state" then mpd_now.state = v - elseif k == "file" then mpd_now.file = v - elseif k == "Artist" then mpd_now.artist = escape_f(v) - elseif k == "Title" then mpd_now.title = escape_f(v) - elseif k == "Album" then mpd_now.album = escape_f(v) - elseif k == "Date" then mpd_now.date = escape_f(v) + for line in f:lines() do + for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do + if k == "state" then mpd_now.state = v + elseif k == "file" then mpd_now.file = v + elseif k == "Artist" then mpd_now.artist = escape_f(v) + elseif k == "Title" then mpd_now.title = escape_f(v) + elseif k == "Album" then mpd_now.album = escape_f(v) + elseif k == "Date" then mpd_now.date = escape_f(v) + end end end - end - f:close() + mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist, + mpd_now.album, mpd_now.date, mpd_now.title) + widget = mpd.widget + settings() - mpd_notification_preset.text = string.format("%s (%s) - %s\n%s", mpd_now.artist, - mpd_now.album, mpd_now.date, mpd_now.title) - widget = mpd.widget - settings() - - if mpd_now.state == "play" - then - if mpd_now.title ~= helpers.get_map("current mpd track") + if mpd_now.state == "play" then - helpers.set_map("current mpd track", mpd_now.title) + if mpd_now.title ~= helpers.get_map("current mpd track") + then + helpers.set_map("current mpd track", mpd_now.title) - os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir, - mpd_now.file, cover_size, default_art)) + os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir, + mpd_now.file, cover_size, default_art)) - mpd.id = naughty.notify({ - preset = mpd_notification_preset, - icon = "/tmp/mpdcover.png", - replaces_id = mpd.id, - screen = client.focus and client.focus.screen or 1 - }).id + mpd.id = naughty.notify({ + preset = mpd_notification_preset, + icon = "/tmp/mpdcover.png", + replaces_id = mpd.id, + screen = client.focus and client.focus.screen or 1 + }).id + end + elseif mpd_now.state ~= "pause" + then + helpers.set_map("current mpd track", nil) end - elseif mpd_now.state ~= "pause" - then - helpers.set_map("current mpd track", nil) - end + end) end helpers.newtimer("mpd", timeout, mpd.update) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 148f547..033254e 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -7,6 +7,7 @@ --]] local newtimer = require("lain.helpers").newtimer +local async = require("lain.asyncshell") local naughty = require("naughty") local wibox = require("wibox") @@ -47,99 +48,102 @@ yawn_notification_preset = {} local function fetch_weather() local url = api_url .. units_set .. city_id - local f = io.popen("curl --connect-timeout 1 -fsm 3 '" .. url .. "'" ) - local text = f:read("*a") - f:close() + local cmd = "curl --connect-timeout 1 -fsm 3 '" .. url .. "'" - -- In case of no connection or invalid city ID - -- widgets won't display - if text == "" or text:match("City not found") - then - yawn.icon:set_image(icon_path .. "na.png") - if text == "" then - weather_data = "Service not available at the moment." - yawn.widget:set_text(" N/A ") - else - weather_data = "City not found!\n" .. - "Are you sure " .. city_id .. - " is your Yahoo city ID?" - yawn.widget:set_text(" ? ") - end - return - end - - -- Processing raw data - weather_data = text:gsub("<.->", "") - weather_data = weather_data:match("Current Conditions:.-Full") or "" - - -- may still happens in case of bad connectivity - if weather_data == "" then - yawn.icon:set_image(icon_path .. "na.png") - yawn.widget:set_text(" ? ") - return - end - - weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ") - weather_data = weather_data:gsub("Forecast:.-\n", "") - weather_data = weather_data:gsub("\nFull", "") - weather_data = weather_data:gsub("[\n]$", "") - weather_data = weather_data:gsub(" [-] " , ": ") - weather_data = weather_data:gsub("[.]", ",") - weather_data = weather_data:gsub("High: ", "") - weather_data = weather_data:gsub(" Low: ", " - ") - - -- Getting info for text widget - local now = weather_data:sub(weather_data:find("Now:")+5, - weather_data:find("\n")-1) - forecast = now:sub(1, now:find(",")-1) - units = now:sub(now:find(",")+2, -2) - - -- Day/Night icon change - local hour = tonumber(os.date("%H")) - sky = icon_path - - if forecast == "Clear" or - forecast == "Fair" or - forecast == "Partly Cloudy" or - forecast == "Mostly Cloudy" - then - if hour >= 6 and hour <= 18 - then - sky = sky .. "Day" - else - sky = sky .. "Night" - end - end - - sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png" - - -- In case there's no defined icon for current forecast - if io.open(sky) == nil then - sky = icon_path .. "na.png" - end - - -- Localization - local f = io.open(localizations_path .. language, "r") - if language:find("en_") == nil and f ~= nil - then + async.request(cmd, function(f) + local text = f:read("*a") f:close() - for line in io.lines(localizations_path .. language) - do - word = string.sub(line, 1, line:find("|")-1) - translation = string.sub(line, line:find("|")+1) - weather_data = string.gsub(weather_data, word, translation) + + -- In case of no connection or invalid city ID + -- widgets won't display + if text == "" or text:match("City not found") + then + yawn.icon:set_image(icon_path .. "na.png") + if text == "" then + weather_data = "Service not available at the moment." + yawn.widget:set_text(" N/A ") + else + weather_data = "City not found!\n" .. + "Are you sure " .. city_id .. + " is your Yahoo city ID?" + yawn.widget:set_text(" ? ") + end + return end - end - -- Finally setting infos - yawn.icon:set_image(sky) - widget = yawn.widget + -- Processing raw data + weather_data = text:gsub("<.->", "") + weather_data = weather_data:match("Current Conditions:.-Full") or "" - _data = weather_data:match(": %S.-,") or weather_data - forecast = _data:gsub(": ", ""):gsub(",", "") - units = units:gsub(" ", "") + -- may still happens in case of bad connectivity + if weather_data == "" then + yawn.icon:set_image(icon_path .. "na.png") + yawn.widget:set_text(" ? ") + return + end - settings() + weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ") + weather_data = weather_data:gsub("Forecast:.-\n", "") + weather_data = weather_data:gsub("\nFull", "") + weather_data = weather_data:gsub("[\n]$", "") + weather_data = weather_data:gsub(" [-] " , ": ") + weather_data = weather_data:gsub("[.]", ",") + weather_data = weather_data:gsub("High: ", "") + weather_data = weather_data:gsub(" Low: ", " - ") + + -- Getting info for text widget + local now = weather_data:sub(weather_data:find("Now:")+5, + weather_data:find("\n")-1) + forecast = now:sub(1, now:find(",")-1) + units = now:sub(now:find(",")+2, -2) + + -- Day/Night icon change + local hour = tonumber(os.date("%H")) + sky = icon_path + + if forecast == "Clear" or + forecast == "Fair" or + forecast == "Partly Cloudy" or + forecast == "Mostly Cloudy" + then + if hour >= 6 and hour <= 18 + then + sky = sky .. "Day" + else + sky = sky .. "Night" + end + end + + sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png" + + -- In case there's no defined icon for current forecast + if io.open(sky) == nil then + sky = icon_path .. "na.png" + end + + -- Localization + local f = io.open(localizations_path .. language, "r") + if language:find("en_") == nil and f ~= nil + then + f:close() + for line in io.lines(localizations_path .. language) + do + word = string.sub(line, 1, line:find("|")-1) + translation = string.sub(line, line:find("|")+1) + weather_data = string.gsub(weather_data, word, translation) + end + end + + -- Finally setting infos + yawn.icon:set_image(sky) + widget = yawn.widget + + _data = weather_data:match(": %S.-,") or weather_data + forecast = _data:gsub(": ", ""):gsub(",", "") + units = units:gsub(" ", "") + + settings() + end) end function yawn.hide() From 44facf162420816bdcfc851d4ff5e033996fa948 Mon Sep 17 00:00:00 2001 From: Axujen Date: Wed, 30 Jul 2014 14:37:20 +0000 Subject: [PATCH 449/546] Use the first client(master) as the central window --- layout/centerwork.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/centerwork.lua b/layout/centerwork.lua index b8175ea..939f18c 100644 --- a/layout/centerwork.lua +++ b/layout/centerwork.lua @@ -37,7 +37,7 @@ function centerwork.arrange(p) if #cls > 0 then -- Main column, fixed width and height. - local c = cls[#cls] + local c = cls[1] local g = {} local mainwid = math.floor(wa.width * mwfact) local slavewid = wa.width - mainwid @@ -57,7 +57,7 @@ function centerwork.arrange(p) if #cls > 1 then local at = 0 - for i = (#cls - 1),1,-1 + for i = (#cls),2,-1 do -- It's all fixed. If there are more than 5 clients, -- those additional clients will float. This is From d2b3a0804d6f12d1b5a37c444936c37a7a70c0ae Mon Sep 17 00:00:00 2001 From: Chris Morin Date: Thu, 7 Aug 2014 17:13:32 -0400 Subject: [PATCH 450/546] fix typo --- widgets/cpu.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/cpu.lua b/widgets/cpu.lua index 96e0d3b..7c1ecb0 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -58,7 +58,7 @@ local function worker(args) local dactive = active - cpu.last_active local dtotal = total - cpu.last_total - cpu_noj = {} + cpu_now = {} cpu_now.usage = tostring(math.ceil((dactive / dtotal) * 100)) widget = cpu.widget From ece196a6b092b8d90218a920d1e1a43e51a367f2 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 8 Aug 2014 14:10:25 +0200 Subject: [PATCH 451/546] abase widget added --- widgets/abase.lua | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 widgets/abase.lua diff --git a/widgets/abase.lua b/widgets/abase.lua new file mode 100644 index 0000000..20cc955 --- /dev/null +++ b/widgets/abase.lua @@ -0,0 +1,43 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, Luke Bonham + +--]] + +local newtimer = require("lain.helpers").newtimer +local async = require("lain.asyncshell") +local wibox = require("wibox") + +local io = io +local setmetatable = setmetatable + +-- Basic template for custom widgets +-- Asynchronous version +-- lain.widgets.abase + +local function worker(args) + local abase = {} + local args = args or {} + local timeout = args.timeout or 5 + local cmd = args.cmd or "" + local settings = args.settings or function() end + + abase.widget = wibox.widget.textbox('') + + function abase.update() + async.request(cmd, function(f) + output = f:read("*a") + f:close() + widget = abase.widget + settings() + end) + end + + newtimer(cmd, timeout, abase.update) + + return setmetatable(abase, { __index = abase.widget }) +end + +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) From b371de56f8bf19f982a4f6887f2110444b590f74 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 8 Aug 2014 14:25:21 +0200 Subject: [PATCH 452/546] widget module loads optimization --- helpers.lua | 2 +- widgets/abase.lua | 1 - widgets/base.lua | 4 ++-- widgets/borderbox.lua | 1 + widgets/calendar.lua | 2 +- widgets/fs.lua | 2 +- widgets/imap.lua | 2 +- widgets/maildir.lua | 2 +- widgets/net.lua | 2 +- widgets/temp.lua | 2 +- widgets/yawn/init.lua | 3 ++- 11 files changed, 12 insertions(+), 11 deletions(-) diff --git a/helpers.lua b/helpers.lua index 863bb87..1dfb09b 100644 --- a/helpers.lua +++ b/helpers.lua @@ -2,7 +2,7 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham + * (c) 2013, Luke Bonham --]] diff --git a/widgets/abase.lua b/widgets/abase.lua index 20cc955..075d615 100644 --- a/widgets/abase.lua +++ b/widgets/abase.lua @@ -10,7 +10,6 @@ local newtimer = require("lain.helpers").newtimer local async = require("lain.asyncshell") local wibox = require("wibox") -local io = io local setmetatable = setmetatable -- Basic template for custom widgets diff --git a/widgets/base.lua b/widgets/base.lua index 6b808b7..39b0863 100644 --- a/widgets/base.lua +++ b/widgets/base.lua @@ -9,10 +9,10 @@ local newtimer = require("lain.helpers").newtimer local wibox = require("wibox") -local io = io +local io = { popen = io.popen } local setmetatable = setmetatable --- Basic template for custom widgets +-- Basic template for custom widgets -- lain.widgets.base local function worker(args) diff --git a/widgets/borderbox.lua b/widgets/borderbox.lua index c251ea8..cce8517 100644 --- a/widgets/borderbox.lua +++ b/widgets/borderbox.lua @@ -8,6 +8,7 @@ --]] local wibox = require("awful.wibox") + local setmetatable = setmetatable -- Creates a thin wibox at a position relative to another wibox diff --git a/widgets/calendar.lua b/widgets/calendar.lua index c690e3f..d07a5b4 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -12,7 +12,7 @@ local awful = require("awful") local beautiful = require("beautiful") local naughty = require("naughty") -local io = io +local io = { popen = io.popen } local os = { date = os.date } local tonumber = tonumber diff --git a/widgets/fs.lua b/widgets/fs.lua index 8127c28..f78cfe0 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -14,7 +14,7 @@ local beautiful = require("beautiful") local wibox = require("wibox") local naughty = require("naughty") -local io = io +local io = { popen = io.popen } local pairs = pairs local string = { match = string.match, format = string.format } diff --git a/widgets/imap.lua b/widgets/imap.lua index 1dca87c..65c425e 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -57,7 +57,7 @@ local function worker(args) curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%s %s -k", head_command, server, port, mail, password, request) - async.request(curl, function(f) + async.request(curl, function(f) ws = f:read("*a") f:close() diff --git a/widgets/maildir.lua b/widgets/maildir.lua index bd79221..246341f 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -13,7 +13,7 @@ local wibox = require("wibox") local util = require("lain.util") -local io = io +local io = { popen = io.popen } local os = { getenv = os.getenv } local pairs = pairs local string = { len = string.len, diff --git a/widgets/net.lua b/widgets/net.lua index 7851d5a..9575000 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -13,7 +13,7 @@ local notify_fg = require("beautiful").fg_focus local naughty = require("naughty") local wibox = require("wibox") -local io = io +local io = { popen = io.popen } local tostring = tostring local string = { format = string.format, gsub = string.gsub } diff --git a/widgets/temp.lua b/widgets/temp.lua index 4ae1c04..5994f59 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -10,7 +10,7 @@ local newtimer = require("lain.helpers").newtimer local wibox = require("wibox") -local io = io +local io = { open = io.open } local tonumber = tonumber local setmetatable = setmetatable diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index 033254e..aa58ed1 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -13,7 +13,8 @@ local naughty = require("naughty") local wibox = require("wibox") local debug = { getinfo = debug.getinfo } -local io = io +local io = { lines = io.lines, + open = io.open } local os = { date = os.date, getenv = os.getenv } local string = { find = string.find, From 898940858203008d7cc365dbc3156e4dde34e9eb Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 8 Sep 2014 18:51:48 +0200 Subject: [PATCH 453/546] imap: increased curl connect-timeout --- widgets/imap.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/imap.lua b/widgets/imap.lua index 65c425e..3a6da8d 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -34,7 +34,7 @@ local function worker(args) local is_plain = args.is_plain or false local settings = args.settings or function() end - local head_command = "curl --connect-timeout 1 -fsm 3" + local head_command = "curl --connect-timeout 3 -fsm 3" local request = "-X 'SEARCH (UNSEEN)'" helpers.set_map(mail, 0) From 1f19ecf03b5a70c9f88be16dcf0ea2374217bb6d Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 11 Sep 2014 16:10:22 +0200 Subject: [PATCH 454/546] yawn: new words localized --- widgets/yawn/localizations/fr_FR | 3 ++- widgets/yawn/localizations/it_IT | 1 + widgets/yawn/localizations/localization_template | 1 + widgets/yawn/localizations/zh_CN | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/widgets/yawn/localizations/fr_FR b/widgets/yawn/localizations/fr_FR index 444b02c..18a35bb 100644 --- a/widgets/yawn/localizations/fr_FR +++ b/widgets/yawn/localizations/fr_FR @@ -57,4 +57,5 @@ Hail|Grêle Fog|Brouillard Foggy|Brumeux Haze|Brume -Light|Clair \ No newline at end of file +Light|Clair +With|Avec diff --git a/widgets/yawn/localizations/it_IT b/widgets/yawn/localizations/it_IT index 70b0eef..44d010e 100644 --- a/widgets/yawn/localizations/it_IT +++ b/widgets/yawn/localizations/it_IT @@ -58,3 +58,4 @@ Fog|Nebbia Foggy|Nebbioso Haze|Nebbia Light|Leggere +With|Con diff --git a/widgets/yawn/localizations/localization_template b/widgets/yawn/localizations/localization_template index 453807e..2fbf066 100644 --- a/widgets/yawn/localizations/localization_template +++ b/widgets/yawn/localizations/localization_template @@ -58,3 +58,4 @@ Fog| Foggy| Haze| Light| +With| diff --git a/widgets/yawn/localizations/zh_CN b/widgets/yawn/localizations/zh_CN index 53b0219..61e98a4 100644 --- a/widgets/yawn/localizations/zh_CN +++ b/widgets/yawn/localizations/zh_CN @@ -58,3 +58,4 @@ Fog|雾 Foggy|有雾 Haze|霾 Light|小 +With|與 From ced8e6d8f7603892cd3ba3a2cd629e85b3c7ad91 Mon Sep 17 00:00:00 2001 From: projektile Date: Mon, 22 Sep 2014 11:25:27 -0400 Subject: [PATCH 455/546] save arezzo files --- layout/cascade.lua | 17 +++++++++++++- layout/cascadetile.lua | 38 +++++++++++++++++++++----------- layout/centerfair.lua | 46 +++++++++++++++++++++++++------------- layout/centerwork.lua | 37 +++++++++++++++++++++---------- layout/termfair.lua | 49 +++++++++++++++++++---------------------- layout/uselessfair.lua | 48 ++++++++++++++++++++-------------------- layout/uselesspiral.lua | 46 ++++++++++++++++++++++++-------------- layout/uselesstile.lua | 44 +++++++++++++++++++++++------------- 8 files changed, 203 insertions(+), 122 deletions(-) diff --git a/layout/cascade.lua b/layout/cascade.lua index cabacef..999c599 100644 --- a/layout/cascade.lua +++ b/layout/cascade.lua @@ -2,12 +2,14 @@ --[[ Licensed under GNU General Public License v2 + * (c) 2014, projektile * (c) 2013, Luke Bonham * (c) 2010-2012, Peter Hofmann --]] -local tag = require("awful.tag") +local tag = require("awful.tag") +local beautiful = require("beautiful") local cascade = { @@ -21,10 +23,23 @@ function cascade.arrange(p) -- Cascade windows. + -- A global border can be defined with + -- beautiful.global_border_width. + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Themes border width requires an offset. + local bw = tonumber(beautiful.border_width) or 0 + -- Screen. local wa = p.workarea local cls = p.clients + wa.height = wa.height - ((global_border * 2) + (bw * 2)) + wa.width = wa.width - ((global_border * 2) + (bw * 2)) + wa.x = wa.x + global_border + wa.y = wa.y + global_border + -- Opening a new window will usually force all existing windows to -- get resized. This wastes a lot of CPU time. So let's set a lower -- bound to "how_many": This wastes a little screen space but you'll diff --git a/layout/cascadetile.lua b/layout/cascadetile.lua index 98821e3..e9b9425 100644 --- a/layout/cascadetile.lua +++ b/layout/cascadetile.lua @@ -2,6 +2,7 @@ --[[ Licensed under GNU General Public License v2 + * (c) 2014, projektile * (c) 2013, Luke Bonham * (c) 2010-2012, Peter Hofmann @@ -30,25 +31,36 @@ function cascadetile.arrange(p) -- It's a bit hard to demonstrate the behaviour with ASCII-images... -- - -- (1) (2) (3) (4) - -- +-----+---+ +-----+---+ +-----+---+ +-----+---+ - -- | | | | | | | | | | | 4 | - -- | | | | | 2 | | | 3 | | | | - -- | 1 | | -> | 1 | | -> | 1 | | -> | 1 +---+ - -- | | | | +---+ | +---+ | | 3 | - -- | | | | | | | | 2 | | |---| - -- | | | | | | | |---| | | 2 | - -- | | | | | | | | | | |---| - -- +-----+---+ +-----+---+ +-----+---+ +-----+---+ + -- (1) (2) (3) (4) + -- +----------+---+ +----------+---+ +----------+---+ +----------+---+ + -- | | | | | 3 | | | 4 | | +---+| + -- | | | -> | | | -> | +---++ -> | +---+|+ + -- | 1 | 2 | | 1 +---++ | 1 | 3 || | 1 +---+|+| + -- | | | | | 2 || | +---++| | +---+|+ | + -- | | | | | || | | 2 | | | | 2 |+ | + -- +----------+---+ +---------+---++ +--------+---+-+ +------+---+---+ -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width. local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Themes border width requires an offset + local bw = tonumber(beautiful.border_width) or 0 -- Screen. local wa = p.workarea local cls = p.clients + -- Borders are factored in. + wa.height = wa.height - ((global_border * 2) + (bw * 2)) + wa.width = wa.width - ((global_border * 2) + (bw * 2)) + -- Width of main column? local t = tag.selected(p.screen) local mwfact @@ -108,8 +120,8 @@ function cascadetile.arrange(p) end g.height = wa.height - g.x = wa.x - g.y = wa.y + g.x = wa.x + global_border + g.y = wa.y + global_border if useless_gap > 0 then -- Reduce width once and move window to the right. Reduce @@ -138,7 +150,7 @@ function cascadetile.arrange(p) g.width = slavewid - current_offset_x g.height = wa.height - current_offset_y g.x = wa.x + mainwid + (how_many - i) * cascadetile.offset_x - g.y = wa.y + (i - 1) * cascadetile.offset_y + g.y = wa.y + (i - 1) * cascadetile.offset_y + global_border if useless_gap > 0 then g.width = g.width - 2 * useless_gap diff --git a/layout/centerfair.lua b/layout/centerfair.lua index 49b4a14..01a2fe0 100644 --- a/layout/centerfair.lua +++ b/layout/centerfair.lua @@ -1,11 +1,12 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - * (c) 2010, Nicolas Estibals - * (c) 2010-2012, Peter Hofmann - + + Licensed under GNU General Public License v2 + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2010, Nicolas Estibals + * (c) 2010-2012, Peter Hofmann + --]] local tag = require("awful.tag") @@ -41,15 +42,30 @@ function centerfair.arrange(p) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width . local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Themes border width requires an offset + local bw = tonumber(beautiful.border_width) or 0 -- Screen. local wa = p.workarea local cls = p.clients + -- Borders are factored in. + wa.height = wa.height - ((global_border * 2) + (bw * 2)) + wa.width = wa.width - ((global_border * 2) + (bw * 2)) + -- How many vertical columns? Read from nmaster on the tag. local t = tag.selected(p.screen) local num_x = centerfair.nmaster or tag.getnmaster(t) local ncol = centerfair.ncol or tag.getncol(t) + if num_x <= 2 then num_x = 2 end + if num_x > #cls then num_x = #cls end local width = math.floor((wa.width-(num_x+1)*useless_gap) / num_x) @@ -61,24 +77,24 @@ function centerfair.arrange(p) local g = {} g.width = width g.height = wa.height - 2*useless_gap - 2 - g.y = offset_y + g.y = offset_y + global_border for i = 1, #cls do - g.x = offset_x + (i - 1) * (width + useless_gap + 2) + g.x = offset_x + (i - 1) * (width + useless_gap + 2) + global_border cls[i]:geometry(g) end else -- More clients than the number of columns, let's arrange it! - local offset_x = wa.x + local offset_x = wa.x if useless_gap > 0 then - offset_x = offset_x + offset_x = offset_x end -- Master client deserves a special treatement local g = {} - g.width = wa.width - (num_x-1)*width -num_x*useless_gap - 2 + g.width = wa.width - (num_x - 1) * width - num_x * useless_gap g.height = wa.height - 2*useless_gap - 2 - g.x = offset_x + useless_gap - g.y = offset_y + g.x = offset_x + useless_gap + global_border + g.y = offset_y + global_border cls[1]:geometry(g) -- Treat the other clients @@ -128,8 +144,8 @@ function centerfair.arrange(p) for i = 1, (num_x-1) do to_remove = 2 - g.height = math.floor((wa.height-useless_gap)/num_y[i]) - g.y = offset_y + g.height = math.floor((wa.height - (num_y[i] * useless_gap)) / num_y[i]) + g.y = offset_y + global_border for j = 0, (num_y[i]-2) do cls[nclient]:geometry(g) nclient = nclient + 1 diff --git a/layout/centerwork.lua b/layout/centerwork.lua index 939f18c..61f4907 100644 --- a/layout/centerwork.lua +++ b/layout/centerwork.lua @@ -2,6 +2,7 @@ --[[ Licensed under GNU General Public License v2 + * (c) 2014, projektile * (c) 2013, Luke Bonham * (c) 2010-2012, Peter Hofmann @@ -26,10 +27,22 @@ function centerwork.arrange(p) -- beautiful.useless_gap_width . local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Themes border width requires an offset + local bw = tonumber(beautiful.border_width) or 0 + -- Screen. local wa = p.workarea local cls = p.clients + -- Borders are factored in. + wa.height = wa.height - ((global_border * 2) + (bw * 2)) + wa.width = wa.width - ((global_border * 2) + (bw * 2)) + -- Width of main column? local t = awful.tag.selected(p.screen) local mwfact = awful.tag.getmwfact(t) @@ -37,7 +50,7 @@ function centerwork.arrange(p) if #cls > 0 then -- Main column, fixed width and height. - local c = cls[1] + local c = cls[#cls] local g = {} local mainwid = math.floor(wa.width * mwfact) local slavewid = wa.width - mainwid @@ -48,8 +61,8 @@ function centerwork.arrange(p) g.height = wa.height - 2 * useless_gap g.width = mainwid - g.x = wa.x + slaveLwid - g.y = wa.y + useless_gap + g.x = wa.x + slaveLwid + global_border + g.y = wa.y + useless_gap + global_border c:geometry(g) @@ -57,7 +70,7 @@ function centerwork.arrange(p) if #cls > 1 then local at = 0 - for i = (#cls),2,-1 + for i = (#cls - 1),1,-1 do -- It's all fixed. If there are more than 5 clients, -- those additional clients will float. This is @@ -73,29 +86,29 @@ function centerwork.arrange(p) if at == centerwork.top_left then -- top left - g.x = wa.x + useless_gap - g.y = wa.y + useless_gap + g.x = wa.x + useless_gap + global_border + g.y = wa.y + useless_gap + global_border g.width = slaveLwid - 2 * useless_gap g.height = slaveThei - useless_gap elseif at == centerwork.top_right then -- top right - g.x = wa.x + slaveLwid + mainwid + useless_gap - g.y = wa.y + useless_gap + g.x = wa.x + slaveLwid + mainwid + useless_gap + global_border + g.y = wa.y + useless_gap + global_border g.width = slaveRwid - 2 * useless_gap g.height = slaveThei - useless_gap elseif at == centerwork.bottom_left then -- bottom left - g.x = wa.x + useless_gap - g.y = wa.y + slaveThei + useless_gap + g.x = wa.x + useless_gap + global_border + g.y = wa.y + slaveThei + useless_gap + global_border g.width = slaveLwid - 2 * useless_gap g.height = slaveBhei - 2 * useless_gap elseif at == centerwork.bottom_right then -- bottom right - g.x = wa.x + slaveLwid + mainwid + useless_gap - g.y = wa.y + slaveThei + useless_gap + g.x = wa.x + slaveLwid + mainwid + useless_gap + global_border + g.y = wa.y + slaveThei + useless_gap + global_border g.width = slaveRwid - 2 * useless_gap g.height = slaveBhei - 2 * useless_gap end diff --git a/layout/termfair.lua b/layout/termfair.lua index 89a44bb..4e45eec 100644 --- a/layout/termfair.lua +++ b/layout/termfair.lua @@ -2,6 +2,7 @@ --[[ Licensed under GNU General Public License v2 + * (c) 2014, projektile * (c) 2013, Luke Bonham * (c) 2010-2012, Peter Hofmann @@ -38,11 +39,24 @@ function termfair.arrange(p) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width. local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Themes border width requires an offset + local bw = tonumber(beautiful.border_width) or 0 -- Screen. local wa = p.workarea local cls = p.clients + -- Borders are factored in. + wa.height = wa.height - ((global_border * 2) + (bw * 2)) + wa.width = wa.width - ((global_border * 2) + (bw * 2)) + -- How many vertical columns? local t = tag.selected(p.screen) local num_x = termfair.nmaster or tag.getnmaster(t) @@ -79,43 +93,26 @@ function termfair.arrange(p) local g = {} if this_x == (num_x - 1) then - g.width = wa.width - (num_x - 1) * width + g.width = wa.width - (num_x - 1) * width - useless_gap else - g.width = width + g.width = width - useless_gap end if this_y == (num_y - 1) then - g.height = wa.height - (num_y - 1) * height + g.height = wa.height - (num_y - 1) * height - useless_gap else - g.height = height + g.height = height - useless_gap end - g.x = wa.x + this_x * width - g.y = wa.y + this_y * height + g.x = wa.x + this_x * width + global_border + g.y = wa.y + this_y * height + global_border if useless_gap > 0 then - -- Top and left clients are shrinked by two steps and - -- get moved away from the border. Other clients just - -- get shrinked in one direction. - - gap_factor = (useless_gap / 100) * 2 + -- All clients tile evenly. + g.x = g.x + (useless_gap / 2) + g.y = g.y + (useless_gap / 2) - if this_x == 0 - then - g.width = g.width - (2 + gap_factor) * useless_gap - g.x = g.x + useless_gap - else - g.width = g.width - (1 + gap_factor) * useless_gap - end - - if this_y == 0 - then - g.height = g.height - (2 + gap_factor) * useless_gap - g.y = g.y + useless_gap - else - g.height = g.height - (1 + gap_factor) * useless_gap - end end c:geometry(g) remaining_clients = remaining_clients - 1 diff --git a/layout/uselessfair.lua b/layout/uselessfair.lua index 6aa6666..6a386c3 100644 --- a/layout/uselessfair.lua +++ b/layout/uselessfair.lua @@ -2,6 +2,7 @@ --[[ Licensed under GNU General Public License v2 + * (c) 2014, projektile * (c) 2013, Luke Bonham * (c) 2012, Josh Komoroske * (c) 2010-2012, Peter Hofmann @@ -19,10 +20,23 @@ local function fair(p, orientation) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width. local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + -- A global border can be defined with + -- beautiful.global_border_width. + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Themes border width requires an offset. + local bw = tonumber(beautiful.border_width) or 0 + + -- get our orientation right. local wa = p.workarea local cls = p.clients + wa.height = wa.height - ((global_border * 2) + (bw * 2)) + wa.width = wa.width - ((global_border * 2) + (bw * 2)) + if #cls > 0 then local cells = math.ceil(math.sqrt(#cls)) local strips = math.ceil(#cls / cells) @@ -47,8 +61,8 @@ local function fair(p, orientation) this_x = cell this_y = strip - g.x = wa.x + cell * g.width - g.y = wa.y + strip * g.height + g.x = wa.x + cell * g.width + global_border + g.y = wa.y + strip * g.height + global_border else if #cls < (strips * cells) and strip == strips - 1 then @@ -61,34 +75,20 @@ local function fair(p, orientation) this_x = strip this_y = cell - g.x = wa.x + strip * g.width - g.y = wa.y + cell * g.height + g.x = wa.x + strip * g.width + global_border + g.y = wa.y + cell * g.height + global_border + end -- Useless gap. if useless_gap > 0 then - -- Top and left clients are shrinked by two steps and - -- get moved away from the border. Other clients just - -- get shrinked in one direction. + -- All clients tile evenly. + g.width = g.width - useless_gap + g.x = g.x + (useless_gap / 2) + g.height = g.height - useless_gap + g.y = g.y + (useless_gap / 2) - gap_factor = (useless_gap / 100) * 2 - - if this_x == 0 - then - g.width = g.width - (2 + gap_factor) * useless_gap - g.x = g.x + useless_gap - else - g.width = g.width - (1 + gap_factor) * useless_gap - end - - if this_y == 0 - then - g.height = g.height - (2 + gap_factor) * useless_gap - g.y = g.y + useless_gap - else - g.height = g.height - (1 + gap_factor) * useless_gap - end end -- End of useless gap. diff --git a/layout/uselesspiral.lua b/layout/uselesspiral.lua index 3164c75..7c72912 100644 --- a/layout/uselesspiral.lua +++ b/layout/uselesspiral.lua @@ -2,7 +2,8 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham + * (c) 2014 projektile + * (c) 2013 Luke Bonham * (c) 2009 Uli Schlachter * (c) 2008 Julien Danjolu @@ -11,6 +12,8 @@ local beautiful = require("beautiful") local ipairs = ipairs local tonumber = tonumber +local math = require("math") +local naughty = require("naughty") local uselesspiral = {} @@ -18,19 +21,32 @@ local function spiral(p, spiral) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width. local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- Themes border width requires an offset + local bw = tonumber(beautiful.border_width) or 0 + + -- get our orientation right local wa = p.workarea local cls = p.clients - local n = #cls + local n = #cls -- number of windows total; k = which window number + + wa.height = wa.height - ((global_border * 2) + (bw * 2)) + wa.width = wa.width - ((global_border * 2) + (bw * 2)) local static_wa = wa for k, c in ipairs(cls) do if k < n then if k % 2 == 0 then - wa.height = wa.height / 2 + wa.height = (wa.height / 2) else - wa.width = wa.width / 2 + wa.width = (wa.width / 2) end end @@ -49,10 +65,10 @@ local function spiral(p, spiral) end local wa2 = {} - wa2.x = wa.x - wa2.y = wa.y - wa2.height = wa.height - wa2.width = wa.width + wa2.x = wa.x + (useless_gap / 2) + global_border + wa2.y = wa.y + (useless_gap / 2) + global_border + wa2.height = wa.height - (useless_gap / 2) + wa2.width = wa.width - (useless_gap / 2) -- Useless gap. if useless_gap > 0 @@ -64,8 +80,6 @@ local function spiral(p, spiral) top = false left = false - gap_factor = (useless_gap / 100) * 2 - if wa2.y == static_wa.y then top = true end @@ -75,17 +89,17 @@ local function spiral(p, spiral) end if top then - wa2.height = wa2.height - (2 + gap_factor) * useless_gap - wa2.y = wa2.y + useless_gap + wa2.height = wa2.height - useless_gap + wa2.y = wa2.y - (useless_gap / 2) else - wa2.height = wa2.height - (1 + gap_factor) * useless_gap + wa2.height = wa2.height - (useless_gap / 2) end if left then - wa2.width = wa2.width - (2 + gap_factor) * useless_gap - wa2.x = wa2.x + useless_gap + wa2.width = wa2.width - useless_gap + wa2.x = wa2.x - (useless_gap / 2) else - wa2.width = wa2.width - (1 + gap_factor) * useless_gap + wa2.width = wa2.width - (useless_gap / 2) end end -- End of useless gap. diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index e496500..47aa4a4 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -2,12 +2,14 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham + * (c) 2014 projektile + * (c) 2013 Luke Bonham * (c) 2009 Donald Ephraim Curtis * (c) 2008 Julien Danjolu --]] +local naughty = require("naughty") local tag = require("awful.tag") local beautiful = require("beautiful") local ipairs = ipairs @@ -22,6 +24,14 @@ local function tile_group(cls, wa, orientation, fact, group) -- A useless gap (like the dwm patch) can be defined with -- beautiful.useless_gap_width . local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + + -- BW!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 -- get our orientation right local height = "height" @@ -36,7 +46,8 @@ local function tile_group(cls, wa, orientation, fact, group) end -- make this more generic (not just width) - available = wa[width] - (group.coord - wa[x]) + --if for top + available = wa[width] - (group.coord - wa[x]) -- it's truly not here -- find our total values local total_fact = 0 @@ -58,20 +69,19 @@ local function tile_group(cls, wa, orientation, fact, group) end total_fact = total_fact + fact[i] end - size = math.min(size, available) - + size = math.min(size, (available - global_border)) local coord = wa[y] local geom = {} local used_size = 0 - local unused = wa[height] + local unused = wa[height] - (global_border * 2) local stat_coord = wa[x] --stat_coord = size for c = group.first,group.last do local i = c - group.first +1 - geom[width] = size + geom[width] = size - global_border geom[height] = math.floor(unused * fact[i] / total_fact) - geom[x] = group.coord - geom[y] = coord + geom[x] = group.coord + global_border + (useless_gap / 2) + geom[y] = coord + global_border + (useless_gap / 2) coord = coord + geom[height] unused = unused - geom[height] @@ -88,8 +98,6 @@ local function tile_group(cls, wa, orientation, fact, group) top = false left = false - gap_factor = (useless_gap / 100) * 2 - if geom[y] == wa[y] then top = true end @@ -99,17 +107,17 @@ local function tile_group(cls, wa, orientation, fact, group) end if top then - geom[height] = geom[height] - (2 + gap_factor) * useless_gap + geom[height] = geom[height] - (2 * useless_gap) geom[y] = geom[y] + useless_gap else - geom[height] = geom[height] - (1 + gap_factor) * useless_gap + geom[height] = geom[height] - useless_gap end if left then - geom[width] = geom[width] - (2 + gap_factor) * useless_gap + geom[width] = geom[width] - (2 * useless_gap) geom[x] = geom[x] + useless_gap else - geom[width] = geom[width] - (1 + gap_factor) * useless_gap + geom[width] = geom[width] - useless_gap end end -- End of useless gap. @@ -136,6 +144,11 @@ local function tile(param, orientation) y = "x" end + -- A global border can be defined with + -- beautiful.global_border_width + global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + local cls = param.clients local nmaster = math.min(tag.getnmaster(t), #cls) local nother = math.max(#cls - nmaster,0) @@ -181,7 +194,7 @@ local function tile(param, orientation) end for i = 1,ncol do -- Try to get equal width among remaining columns - local size = math.min( (wasize - (coord - wa[x])) / (ncol - i + 1) ) + local size = math.min((wasize - (coord - wa[x])) / (ncol - i + 1)) --+ (global_border/(ncol))/(ncol+i^2) local first = last + 1 last = last + math.floor((#cls - last)/(ncol - i + 1)) -- tile the column and update our current x coordinate @@ -228,3 +241,4 @@ uselesstile.arrange = uselesstile.right.arrange uselesstile.name = uselesstile.right.name return uselesstile + From 4e4bf44d2ff80c1ab68f1d20e3bc115619295653 Mon Sep 17 00:00:00 2001 From: projektile Date: Mon, 22 Sep 2014 11:29:46 -0400 Subject: [PATCH 456/546] set card --- widgets/alsa.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/widgets/alsa.lua b/widgets/alsa.lua index f62a150..114e2b2 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -23,14 +23,14 @@ local alsa = {} local function worker(args) local args = args or {} local timeout = args.timeout or 5 - local channel = args.channel or "Master" + local channel = args.channel or "Master -c 1" local settings = args.settings or function() end alsa.widget = wibox.widget.textbox('') function alsa.update() - local f = assert(io.popen('amixer -M get ' .. channel)) - local mixer = f:read("*a") + local f = assert(io.popen('amixer get ' .. channel)) + local mixer = f:read("*all") f:close() volume_now = {} From cbd4099f8b5ecf5abc515c10055333d76f7e1671 Mon Sep 17 00:00:00 2001 From: projektile Date: Mon, 22 Sep 2014 11:36:50 -0400 Subject: [PATCH 457/546] fix border offset --- layout/uselesstile.lua | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index 47aa4a4..dfbaf68 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -28,10 +28,11 @@ local function tile_group(cls, wa, orientation, fact, group) -- A global border can be defined with -- beautiful.global_border_width - global_border = tonumber(beautiful.global_border_width) or 0 + local global_border = tonumber(beautiful.global_border_width) or 0 if global_border < 0 then global_border = 0 end - -- BW!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 + -- Themes border width requires an offset + local bw = tonumber(beautiful.border_width) or 0 -- get our orientation right local height = "height" @@ -78,8 +79,8 @@ local function tile_group(cls, wa, orientation, fact, group) --stat_coord = size for c = group.first,group.last do local i = c - group.first +1 - geom[width] = size - global_border - geom[height] = math.floor(unused * fact[i] / total_fact) + geom[width] = size - global_border - (bw * 2) + geom[height] = math.floor(unused * fact[i] / total_fact) - (bw * 2) geom[x] = group.coord + global_border + (useless_gap / 2) geom[y] = coord + global_border + (useless_gap / 2) @@ -144,11 +145,6 @@ local function tile(param, orientation) y = "x" end - -- A global border can be defined with - -- beautiful.global_border_width - global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end - local cls = param.clients local nmaster = math.min(tag.getnmaster(t), #cls) local nother = math.max(#cls - nmaster,0) From a693e784d05ad28b9a42fc6f6999f3fb73ac5f2c Mon Sep 17 00:00:00 2001 From: projektile Date: Mon, 22 Sep 2014 11:54:03 -0400 Subject: [PATCH 458/546] remove naughty --- layout/uselesspiral.lua | 1 - layout/uselesstile.lua | 1 - 2 files changed, 2 deletions(-) diff --git a/layout/uselesspiral.lua b/layout/uselesspiral.lua index 7c72912..ba63bca 100644 --- a/layout/uselesspiral.lua +++ b/layout/uselesspiral.lua @@ -13,7 +13,6 @@ local beautiful = require("beautiful") local ipairs = ipairs local tonumber = tonumber local math = require("math") -local naughty = require("naughty") local uselesspiral = {} diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index dfbaf68..eccfdad 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -9,7 +9,6 @@ --]] -local naughty = require("naughty") local tag = require("awful.tag") local beautiful = require("beautiful") local ipairs = ipairs From ee615272a2fcdbe62c4c45b02c3abe27ab7d4fb3 Mon Sep 17 00:00:00 2001 From: Dainese Hsiao Date: Thu, 25 Sep 2014 13:15:39 +0800 Subject: [PATCH 459/546] Add yawn localization zh_TW --- widgets/yawn/localizations/zh_TW | 61 ++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 widgets/yawn/localizations/zh_TW diff --git a/widgets/yawn/localizations/zh_TW b/widgets/yawn/localizations/zh_TW new file mode 100644 index 0000000..03644c1 --- /dev/null +++ b/widgets/yawn/localizations/zh_TW @@ -0,0 +1,61 @@ +Now:|現在: +Sun:|週日: +Mon:|週一: +Tue:|週二: +Wed:|週三: +Thu:|週四: +Fri:|週五: +Sat:|週六: +Mostly Sunny|晴時多雲 +Sunny|大太陽 +Sun|太陽 +Rain/Thunder|雨時有雷 +Isolated Thunderstorms|局部雷雨 +Scattered Thunderstorms|零星雷雨 +Thundershowers|雷陣雨 +Thunderstorms|雷雨 +Thunder in the Vicinity|局部性雷雨 +Thunder|雷嗚 +AM|上午 +PM|下午 +Early|早 +Late|晚有 +Few|短暫 +Severe|惡劣 +Clear|晴朗 +Fair|晴 +Partly|局部 +Mostly|大部 +Cloudy|多雲 +Clouds|有雲 +Scattered Showers|零星陣雨 +Light Snow Showers|小陣雪 +Snow Showers|陣雪 +Heavy Snow|大雪 +Scattered Snow Showers|零星陣雪 +Mixed Rain And Snow|雨夾雪 +Mixed Rain And Sleet|雨時雨夾雪 +Mixed Snow And Sleet|雪時雨夾雪 +Mixed Rain And Hail|雨夾冰雹 +Snow Flurries|陣雪 +Blowing Snow|風吹雪 +Blowing Rain|風吹雨 +Heavy Rain|大雨 +Freezing Rain|凍雨 +Showers|陣雨 +Light Rain|小雨 +Heavy|大 +Rain|雨 +Windy|有風 +Wind|風 +Snow|雪 +Sleet|冰珠 +Freezing Drizzle|凍毛毛雨 +Light Drizzle|細雨 +Drizzle|毛毛雨 +Hail|冰雹 +Fog|霧 +Foggy|有霧 +Haze|霾 +Light|小 +With|與 From f5d391e7b6188d1d5847d12ceb64796c56f2d9f1 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 26 Sep 2014 12:41:35 +0200 Subject: [PATCH 460/546] undo 'set card' from projektile/master --- widgets/alsa.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 114e2b2..f62a150 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -23,14 +23,14 @@ local alsa = {} local function worker(args) local args = args or {} local timeout = args.timeout or 5 - local channel = args.channel or "Master -c 1" + local channel = args.channel or "Master" local settings = args.settings or function() end alsa.widget = wibox.widget.textbox('') function alsa.update() - local f = assert(io.popen('amixer get ' .. channel)) - local mixer = f:read("*all") + local f = assert(io.popen('amixer -M get ' .. channel)) + local mixer = f:read("*a") f:close() volume_now = {} From b0bcf77ccc17dc18b6294b63de12ce3e70b53345 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 11 Oct 2014 14:17:05 +0200 Subject: [PATCH 461/546] #66 removed hardcoded screen def in widgets notification --- widgets/alsabar.lua | 2 -- widgets/bat.lua | 2 -- widgets/calendar.lua | 1 - widgets/contrib/init.lua | 1 - widgets/contrib/task.lua | 6 +----- widgets/fs.lua | 2 -- widgets/imap.lua | 1 - widgets/mpd.lua | 1 - widgets/net.lua | 1 - widgets/yawn/init.lua | 1 - 10 files changed, 1 insertion(+), 17 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 8675cb5..96d57b0 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -77,12 +77,10 @@ function alsabar.notify() alsabar._notify = naughty.notify ({ replaces_id = alsabar._notify.id, preset = preset, - screen = client.focus and client.focus.screen or 1 }) else alsabar._notify = naughty.notify ({ preset = preset, - screen = client.focus and client.focus.screen or 1 }) end end diff --git a/widgets/bat.lua b/widgets/bat.lua index 2ace758..572d099 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -130,14 +130,12 @@ local function worker(args) bat.id = naughty.notify({ preset = bat_notification_critical_preset, replaces_id = bat.id, - screen = client.focus and client.focus.screen or 1 }).id elseif nperc <= 15 then bat.id = naughty.notify({ preset = bat_notification_low_preset, replaces_id = bat.id, - screen = client.focus and client.focus.screen or 1 }).id end end diff --git a/widgets/calendar.lua b/widgets/calendar.lua index d07a5b4..f9aed39 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -99,7 +99,6 @@ function calendar:show(t_out, inc_offset) fg = calendar.fg, bg = calendar.bg, timeout = tims, - screen = client.focus and client.focus.screen or 1 }) end diff --git a/widgets/contrib/init.lua b/widgets/contrib/init.lua index 9a9fa63..ccaed82 100644 --- a/widgets/contrib/init.lua +++ b/widgets/contrib/init.lua @@ -8,7 +8,6 @@ Licensed under GNU General Public License v2 * (c) 2013, Luke Bonham - * (c) 2010-2012, Peter Hofmann --]] diff --git a/widgets/contrib/task.lua b/widgets/contrib/task.lua index 6e6ebae..2e30cdc 100644 --- a/widgets/contrib/task.lua +++ b/widgets/contrib/task.lua @@ -2,7 +2,6 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham * (c) 2013, Jan Xie --]] @@ -20,7 +19,7 @@ local tonumber = tonumber local setmetatable = setmetatable -- Taskwarrior notification --- lain.widgets.task +-- lain.widgets.contrib.task local task = {} local task_notification = nil @@ -52,7 +51,6 @@ function task:show() fg = task.fg, bg = task.bg, timeout = task.timeout, - screen = client.focus and client.focus.screen or 1 }) end @@ -75,7 +73,6 @@ function task:prompt_add() fg = task.fg, bg = task.bg, timeout = task.timeout, - screen = client.focus and client.focus.screen or 1 }) end, nil, @@ -109,7 +106,6 @@ function task:prompt_search() fg = task.fg, bg = task.bg, timeout = task.timeout, - screen = client.focus and client.focus.screen or 1 }) end, nil, diff --git a/widgets/fs.lua b/widgets/fs.lua index f78cfe0..3b99cba 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -47,7 +47,6 @@ function fs:show(t_out) preset = fs_notification_preset, text = ws, timeout = t_out, - screen = client.focus and client.focus.screen or 1 }) end @@ -100,7 +99,6 @@ local function worker(args) timeout = 8, fg = "#000000", bg = "#FFFFFF", - screen = client.focus and client.focus.screen or 1 }) helpers.set_map("fs", true) else diff --git a/widgets/imap.lua b/widgets/imap.lua index 3a6da8d..d4b4cba 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -77,7 +77,6 @@ local function worker(args) naughty.notify({ preset = mail_notification_preset, text = nt, - screen = client.focus and client.focus.screen or 1 }) end diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 385b5bb..7fd611d 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -91,7 +91,6 @@ local function worker(args) preset = mpd_notification_preset, icon = "/tmp/mpdcover.png", replaces_id = mpd.id, - screen = client.focus and client.focus.screen or 1 }).id end elseif mpd_now.state ~= "pause" diff --git a/widgets/net.lua b/widgets/net.lua index 9575000..2bfd375 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -88,7 +88,6 @@ local function worker(args) position = "top_left", icon = helpers.icons_dir .. "no_net.png", fg = notify_fg or "#FFFFFF", - screen = client.focus and client.focus.screen or 1 }) helpers.set_map(iface, false) end diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index aa58ed1..b034395 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -167,7 +167,6 @@ function yawn.show(t_out) text = weather_data, icon = sky, timeout = t_out, - screen = client.focus and client.focus.screen or 1 }) end From c043bc1059a644e5a59a314890db88f8d9ed3d48 Mon Sep 17 00:00:00 2001 From: projektile Date: Sat, 27 Sep 2014 01:07:19 -0400 Subject: [PATCH 462/546] update dynamic border change --- util/init.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/util/init.lua b/util/init.lua index d99f007..ac3afec 100644 --- a/util/init.lua +++ b/util/init.lua @@ -210,6 +210,12 @@ function util.useless_gaps_resize(thatmuch) awful.layout.arrange(mouse.screen) end +-- On the fly global border change +function util.global_border_resize(thatmuch) + beautiful.global_border_width = tonumber(beautiful.global_border_width) + thatmuch + awful.layout.arrange(mouse.screen) +end + -- Check if an element exist on a table function util.element_in_table(element, tbl) for _, i in pairs(tbl) do From ebd18c24f3ec2ea95e1ce0a30727183a0ce6b9af Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 11 Oct 2014 14:45:14 +0200 Subject: [PATCH 463/546] widgets: screen notification setting added --- widgets/alsabar.lua | 4 +++- widgets/calendar.lua | 3 ++- widgets/net.lua | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 96d57b0..65a2b33 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -41,7 +41,8 @@ local alsabar = { font = beautiful.font:sub(beautiful.font:find(""), beautiful.font:find(" ")), font_size = "11", color = beautiful.fg_normal, - bar_size = 18 + bar_size = 18, + screen = 1 }, _current_level = 0, @@ -55,6 +56,7 @@ function alsabar.notify() title = "", text = "", timeout = 4, + screen = alsabar.notifications.screen, font = alsabar.notifications.font .. " " .. alsabar.notifications.font_size, fg = alsabar.notifications.color diff --git a/widgets/calendar.lua b/widgets/calendar.lua index f9aed39..bada79e 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -30,7 +30,7 @@ function calendar:hide() end end -function calendar:show(t_out, inc_offset) +function calendar:show(t_out, inc_offset, scr) calendar:hide() local offs = inc_offset or 0 @@ -99,6 +99,7 @@ function calendar:show(t_out, inc_offset) fg = calendar.fg, bg = calendar.bg, timeout = tims, + screen = scr or 1 }) end diff --git a/widgets/net.lua b/widgets/net.lua index 2bfd375..ed6a2ef 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -45,6 +45,7 @@ local function worker(args) local iface = args.iface or net.get_device() local units = args.units or 1024 --kb local notify = args.notify or "on" + local screen = args.screen or 1 local settings = args.settings or function() end net.widget = wibox.widget.textbox('') @@ -88,6 +89,7 @@ local function worker(args) position = "top_left", icon = helpers.icons_dir .. "no_net.png", fg = notify_fg or "#FFFFFF", + screen = screen }) helpers.set_map(iface, false) end From e759a7fe23c39c69b82b3929ebe6f993eb76db09 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 11 Oct 2014 16:18:03 +0200 Subject: [PATCH 464/546] #66: screen position in calendar:attach --- widgets/calendar.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index bada79e..631b358 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -113,20 +113,21 @@ function calendar:attach(widget, args) calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF" calendar.position = args.position or "top_right" + calendar.scr_pos = args.scr_pos or 1 calendar.offset = 0 calendar.notify_icon = nil - widget:connect_signal("mouse::enter", function () calendar:show() end) + widget:connect_signal("mouse::enter", function () calendar:show(0, 0, scr_pos) end) widget:connect_signal("mouse::leave", function () calendar:hide() end) widget:buttons(awful.util.table.join( awful.button({ }, 1, function () - calendar:show(0, -1) end), + calendar:show(0, -1, scr_pos) end), awful.button({ }, 3, function () - calendar:show(0, 1) end), + calendar:show(0, 1, scr_pos) end), awful.button({ }, 4, function () - calendar:show(0, -1) end), + calendar:show(0, -1, scr_pos) end), awful.button({ }, 5, function () - calendar:show(0, 1) end))) + calendar:show(0, 1, scr_pos) end))) end return setmetatable(calendar, { __call = function(_, ...) return create(...) end }) From 1a654b327dba5afceef90595d3fc79b5ad67f7d5 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 20 Oct 2014 15:56:44 +0200 Subject: [PATCH 465/546] #68 solution attempt --- widgets/net.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/net.lua b/widgets/net.lua index ed6a2ef..84751b6 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -31,9 +31,9 @@ function net.get_device() f = io.popen("ip link show | cut -d' ' -f2,9") ws = f:read("*a") f:close() - ws = ws:match("%w+: UP") + ws = ws:match("%w+: UP") or ws:match("ppp%w+: UNKNOWN") if ws ~= nil then - return ws:gsub(": UP", "") + return ws:match("(%w+):") else return "network off" end From 317fea4ca4c999c0fef9a9f15020e8b301a1ef43 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 20 Oct 2014 18:05:47 +0200 Subject: [PATCH 466/546] #67 mpdcover lightened --- scripts/mpdcover | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mpdcover b/scripts/mpdcover index f6cf0d6..6f9062c 100755 --- a/scripts/mpdcover +++ b/scripts/mpdcover @@ -2,7 +2,7 @@ # # A simple cover fetcher script for current playing song on mpd. # -# Author : Wolfgang Mueller +# Original author: Wolfgang Mueller # # Adapted for Lain internal use. # https://github.com/copycat-killer/lain @@ -58,7 +58,7 @@ cover="${cover:=$DEFAULT_ART}" # check if art is available if [[ -n $cover ]]; then if [[ -n $COVER_RESIZE ]]; then - convert "$cover" -thumbnail $COVER_RESIZE -gravity "center" -background "$COVER_BACKGROUND" -extent $COVER_RESIZE "$TEMP_PATH" + convert "$cover" -scale $COVER_RESIZE -gravity "center" -background "$COVER_BACKGROUND" "$TEMP_PATH" cover="$TEMP_PATH" fi else From a652b7065ab2b859199c31f194c4dba31d3d9182 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 8 Nov 2014 12:06:48 +0100 Subject: [PATCH 467/546] centerfair: added no cls[1] case --- layout/centerfair.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/layout/centerfair.lua b/layout/centerfair.lua index 01a2fe0..e2ecb33 100644 --- a/layout/centerfair.lua +++ b/layout/centerfair.lua @@ -95,7 +95,10 @@ function centerfair.arrange(p) g.height = wa.height - 2*useless_gap - 2 g.x = offset_x + useless_gap + global_border g.y = offset_y + global_border - cls[1]:geometry(g) + + if cls[1] then + cls[1]:geometry(g) + end -- Treat the other clients From a8a898fabd6ab1e9add8c1235ab9ec0d78dadd8f Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 8 Nov 2014 12:44:23 +0100 Subject: [PATCH 468/546] centerfair: ncol uselessgaps fixed --- layout/centerfair.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/centerfair.lua b/layout/centerfair.lua index e2ecb33..37507d3 100644 --- a/layout/centerfair.lua +++ b/layout/centerfair.lua @@ -91,7 +91,7 @@ function centerfair.arrange(p) -- Master client deserves a special treatement local g = {} - g.width = wa.width - (num_x - 1) * width - num_x * useless_gap + g.width = wa.width - (num_x - 1) * width - num_x * 2*useless_gap - 2 g.height = wa.height - 2*useless_gap - 2 g.x = offset_x + useless_gap + global_border g.y = offset_y + global_border @@ -142,7 +142,7 @@ function centerfair.arrange(p) g.width = width if useless_gap > 0 then - g.width = g.width - useless_gap/2 - 2 + g.width = g.width + useless_gap - 2 end for i = 1, (num_x-1) do From faecd881fc44b5a045bc86f2101b89e2999d6521 Mon Sep 17 00:00:00 2001 From: Moussab Date: Mon, 10 Nov 2014 23:46:57 +0100 Subject: [PATCH 469/546] Update centerfair.lua --- layout/centerfair.lua | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/layout/centerfair.lua b/layout/centerfair.lua index 37507d3..d3225b4 100644 --- a/layout/centerfair.lua +++ b/layout/centerfair.lua @@ -65,7 +65,6 @@ function centerfair.arrange(p) local num_x = centerfair.nmaster or tag.getnmaster(t) local ncol = centerfair.ncol or tag.getncol(t) if num_x <= 2 then num_x = 2 end - if num_x > #cls then num_x = #cls end local width = math.floor((wa.width-(num_x+1)*useless_gap) / num_x) @@ -79,7 +78,7 @@ function centerfair.arrange(p) g.height = wa.height - 2*useless_gap - 2 g.y = offset_y + global_border for i = 1, #cls do - g.x = offset_x + (i - 1) * (width + useless_gap + 2) + global_border + g.x = offset_x + (#cls - i) * (width + useless_gap + 2) + global_border cls[i]:geometry(g) end else @@ -96,9 +95,7 @@ function centerfair.arrange(p) g.x = offset_x + useless_gap + global_border g.y = offset_y + global_border - if cls[1] then - cls[1]:geometry(g) - end + cls[#cls]:geometry(g) -- Treat the other clients @@ -107,7 +104,7 @@ function centerfair.arrange(p) do local remaining_clients = #cls-1 local ncol_min = math.ceil(remaining_clients/(num_x-1)) - if ncol >= ncol_min + if ncol >= ncol_min then for i = (num_x-1), 1, -1 do if (remaining_clients-i+1) < ncol @@ -137,7 +134,7 @@ function centerfair.arrange(p) end -- Compute geometry of the other clients - local nclient = 2 + local nclient = #cls-1 -- we start with the 2nd client g.x = g.x + g.width+useless_gap + 2 g.width = width @@ -149,15 +146,15 @@ function centerfair.arrange(p) to_remove = 2 g.height = math.floor((wa.height - (num_y[i] * useless_gap)) / num_y[i]) g.y = offset_y + global_border - for j = 0, (num_y[i]-2) do + for j = 1, (num_y[i]-1) do cls[nclient]:geometry(g) - nclient = nclient + 1 + nclient = nclient - 1 g.y = g.y + g.height+useless_gap + 2 to_remove = to_remove + 2 end g.height = wa.height - num_y[i]*useless_gap - (num_y[i]-1)*g.height - useless_gap - to_remove cls[nclient]:geometry(g) - nclient = nclient + 1 + nclient = nclient - 1 g.x = g.x+g.width+useless_gap + 2 end end From c87a7be2ed35b95b254509dc3b107700b82b1ec3 Mon Sep 17 00:00:00 2001 From: Moussab Date: Mon, 10 Nov 2014 23:51:11 +0100 Subject: [PATCH 470/546] Update centerfair.lua --- layout/centerfair.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/centerfair.lua b/layout/centerfair.lua index d3225b4..383bf9e 100644 --- a/layout/centerfair.lua +++ b/layout/centerfair.lua @@ -104,7 +104,7 @@ function centerfair.arrange(p) do local remaining_clients = #cls-1 local ncol_min = math.ceil(remaining_clients/(num_x-1)) - if ncol >= ncol_min + if ncol >= ncol_min then for i = (num_x-1), 1, -1 do if (remaining_clients-i+1) < ncol From 75a68eda59b3d748334c28c91a362948b3fd81e3 Mon Sep 17 00:00:00 2001 From: Moussab Date: Mon, 10 Nov 2014 23:52:00 +0100 Subject: [PATCH 471/546] Update centerfair.lua --- layout/centerfair.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/centerfair.lua b/layout/centerfair.lua index 383bf9e..67462f7 100644 --- a/layout/centerfair.lua +++ b/layout/centerfair.lua @@ -146,7 +146,7 @@ function centerfair.arrange(p) to_remove = 2 g.height = math.floor((wa.height - (num_y[i] * useless_gap)) / num_y[i]) g.y = offset_y + global_border - for j = 1, (num_y[i]-1) do + for j = 0, (num_y[i]-2) do cls[nclient]:geometry(g) nclient = nclient - 1 g.y = g.y + g.height+useless_gap + 2 From e07eee461894dd5f36e96c4162e2165c2213e098 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 15 Nov 2014 13:21:22 +0100 Subject: [PATCH 472/546] yawn: fetch_weather local -> integrated; net: iface scope fixed --- asyncshell.lua | 6 +++--- widgets/net.lua | 3 ++- widgets/yawn/init.lua | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/asyncshell.lua b/asyncshell.lua index 51885e8..4a01caa 100644 --- a/asyncshell.lua +++ b/asyncshell.lua @@ -11,9 +11,9 @@ -- ...asynchronously: -- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end) -- ...synchronously --- wwidget.text = asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error" +-- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error") --- This makes things faster, but puts weight on sysload and is more cpu demanding. +-- This is more cpu demanding, but makes things faster. local spawn = require('awful.util').spawn @@ -39,7 +39,7 @@ end function asyncshell.request(command, callback) local id = next_id() local tmpfname = asyncshell.file_template .. id - asyncshell.request_table[id] = {callback = callback} + asyncshell.request_table[id] = { callback = callback } local req = string.format("sh -c '%s > %s; " .. 'echo "asyncshell.deliver(%s)" | ' .. diff --git a/widgets/net.lua b/widgets/net.lua index 84751b6..d1179a2 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -42,12 +42,13 @@ end local function worker(args) local args = args or {} local timeout = args.timeout or 2 - local iface = args.iface or net.get_device() local units = args.units or 1024 --kb local notify = args.notify or "on" local screen = args.screen or 1 local settings = args.settings or function() end + iface = args.iface or net.get_device() + net.widget = wibox.widget.textbox('') helpers.set_map(iface, true) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index b034395..be3e614 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -45,9 +45,9 @@ local city_id = nil local sky = nil local settings = function() end -yawn_notification_preset = {} +yawn_notification_preset = {} -local function fetch_weather() +function yawn.fetch_weather() local url = api_url .. units_set .. city_id local cmd = "curl --connect-timeout 1 -fsm 3 '" .. url .. "'" @@ -157,7 +157,7 @@ end function yawn.show(t_out) if yawn.widget._layout.text:match("?") then - fetch_weather(settings) + yawn.fetch_weather() end yawn.hide() @@ -179,7 +179,7 @@ function yawn.register(id, args) city_id = id - newtimer("yawn", timeout, fetch_weather) + newtimer("yawn", timeout, yawn.fetch_weather) yawn.icon:connect_signal("mouse::enter", function() yawn.show(0) From 1d5e6f2516b5b3fd8a50d7dfe9dc7cb3ddb9ff40 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sat, 15 Nov 2014 13:38:07 +0100 Subject: [PATCH 473/546] net: iface scope fixed 2 --- widgets/net.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/widgets/net.lua b/widgets/net.lua index d1179a2..2b06622 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -16,7 +16,8 @@ local wibox = require("wibox") local io = { popen = io.popen } local tostring = tostring local string = { format = string.format, - gsub = string.gsub } + gsub = string.gsub, + match = string.match } local setmetatable = setmetatable @@ -56,7 +57,10 @@ local function worker(args) function update() net_now = {} - if iface == "" then iface = net.get_device() end + if iface == "" or string.match(iface, "network off") + then + iface = net.get_device() + end net_now.carrier = helpers.first_line('/sys/class/net/' .. iface .. '/carrier') or "0" From dba2c648f17ea9d7d65742efa0a0ca5e3e8aba87 Mon Sep 17 00:00:00 2001 From: alexey korobtsov Date: Mon, 17 Nov 2014 18:56:56 +0300 Subject: [PATCH 474/546] new file: widgets/yawn/localizations/ru_RU --- widgets/yawn/localizations/ru_RU | 61 ++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 widgets/yawn/localizations/ru_RU diff --git a/widgets/yawn/localizations/ru_RU b/widgets/yawn/localizations/ru_RU new file mode 100644 index 0000000..0b9b9e9 --- /dev/null +++ b/widgets/yawn/localizations/ru_RU @@ -0,0 +1,61 @@ +Now:|Cейчас: +Sun:|Воскресенье: +Mon:|понедельник: +Tue:|Вторник: +Wed:|Среда: +Thu:|Четверг: +Fri:|Пятница: +Sat:|Суббота: +Mostly Sunny|Премушественно солнечно +Sunny|Солнечно +Sun|Солнце +Rain/Thunder|Дождь/Гром +Isolated Thunderstorms|Изолированные грозы +Scattered Thunderstorms|Рассеянные грозы +Thundershowers|Ливни +Thunderstorms|Грозы +Thunder in the Vicinity|Гром в окрестностях +Thunder|Гром +AM|Утро +PM|Вечер +Early|Рано +Late|Поздно +Few|Мало +Severe|Тяжелый +Clear|Ясно +Fair|Светлый +Partly|Частично +Mostly|По большй части +Cloudy|Облочно +Clouds|Облока +Scattered Showers|Рассеянные ливни +Light Snow Showers|Небольшой снег +Snow Showers|Ливневый Снег +Heavy Snow|Сильный снегопад +Scattered Snow Showers|Рассеянный ливневый снег +Mixed Rain And Snow|Снег с дождём +Mixed Rain And Sleet|Дождь и мокрый снег +Mixed Snow And Sleet|Снег и мокрый снег +Mixed Rain And Hail|Дождь с градом +Snow Flurries|Снежные порывы +Blowing Snow|Снег и ветер +Blowing Rain|Дождь и ветер +Heavy Rain|Сильный дождь +Freezing Rain|Ледяной дождь +Showers|Ливени +Light Rain|Небольшой дождь +Heavy|Сильный +Rain|Дождь +Windy|Ветреный +Wind|Ветер +Snow|Снег +Sleet|Мокрый снег +Freezing Drizzle|Изморозь +Light Drizzle|Лёгкая изморось +Drizzle|Моросящий дождь +Hail|Град +Fog|Туман +Foggy|Туманно +Haze|Дымка +Light|Лёгкий +With|С From 1973b16fdc6a371e6dadcf9b8f25196202013145 Mon Sep 17 00:00:00 2001 From: Alex Kir Date: Tue, 25 Nov 2014 23:14:56 +0200 Subject: [PATCH 475/546] Some might have spaces in passwords (Like I do) and then curl fails. * Changed string formatting of password to %q to always quote password --- widgets/imap.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/imap.lua b/widgets/imap.lua index d4b4cba..1ebbb76 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -54,7 +54,7 @@ local function worker(args) position = "top_left" } - curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%s %s -k", + curl = string.format("%s --url imaps://%s:%s/INBOX -u %s:%q %s -k", head_command, server, port, mail, password, request) async.request(curl, function(f) From 576a24d6e7efd7108a52d40266081c11462791d5 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 12 Dec 2014 19:26:43 +0100 Subject: [PATCH 476/546] yawn: de_DE added --- widgets/yawn/localizations/de_DE | 61 ++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 widgets/yawn/localizations/de_DE diff --git a/widgets/yawn/localizations/de_DE b/widgets/yawn/localizations/de_DE new file mode 100644 index 0000000..82cef79 --- /dev/null +++ b/widgets/yawn/localizations/de_DE @@ -0,0 +1,61 @@ +Now:|Jetzt: +Sun:|So: +Mon:|Mo: +Tue:|Di: +Wed:|Mi: +Thu:|Do: +Fri:|Fr: +Sat:|Sa: +Mostly Sunny|Größtenteils Sonnig +Sunny|Sonnig +Sun|Sonne +Rain/Thunder|Regen/Donner +Isolated Thunderstorms|Vereinzelte Gewitter +Scattered Thunderstorms|Aufgelockertes Gewitter +Thundershowers|Gewitterschauer +Thunderstorms|Gewitter +Thunder in the Vicinity|Donner in der Umgebung +Thunder|Donner +AM|Vormittags +PM|Nachmittags +Early|Früh +Late|Spät +Few|einige +Severe|starker +Clear|Klar +Fair|Heiter +Partly|teilweise +Mostly|größtenteils +Cloudy|Wolkig +Clouds|Wolken +Scattered Showers|Vereinzelte Schauer +Light Snow Showers|Leichter Schneeregen +Snow Showers|Schneeregen +Heavy Snow|Starker Schneefall +Scattered Snow Showers|Vereinzelter Schneefall +Mixed Rain And Snow|Gemischter Regen und Schnee +Mixed Rain And Sleet|Gemischter Regen und Graupel +Mixed Snow And Sleet|Gemischter Schnee und Graupel +Mixed Rain And Hail|Gemischter Regen und Hagel +Snow Flurries|Schneegestöber +Blowing Snow|Schneetreiben +Blowing Rain|Treibender Regen +Heavy Rain|Starke Regenfälle +Freezing Rain|Eisregen +Showers|Schauer +Light Rain|Leichter Regen +Heavy|Starker +Rain|Regen +Windy|Windig +Wind|Wind +Snow|Schnee +Sleet|Graupel +Freezing Drizzle|Gefrierender Sprühregen +Light Drizzle|Leichter Sprühregen +Drizzle|Sprühregen +Hail|Hagel +Fog|Nebel +Foggy|Nebelig +Haze|Dunst +Light|leichter +With|mit \ No newline at end of file From b9c5e5a2cf7860edb1e1dd9df0e32350b7b9a985 Mon Sep 17 00:00:00 2001 From: loudcry Date: Mon, 1 Dec 2014 17:07:29 +0500 Subject: [PATCH 477/546] Some words' fixes I fixed some words. --- widgets/yawn/localizations/ru_RU | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/widgets/yawn/localizations/ru_RU b/widgets/yawn/localizations/ru_RU index 0b9b9e9..0b2ae23 100644 --- a/widgets/yawn/localizations/ru_RU +++ b/widgets/yawn/localizations/ru_RU @@ -1,12 +1,12 @@ Now:|Cейчас: Sun:|Воскресенье: -Mon:|понедельник: +Mon:|Понедельник: Tue:|Вторник: Wed:|Среда: Thu:|Четверг: Fri:|Пятница: Sat:|Суббота: -Mostly Sunny|Премушественно солнечно +Mostly Sunny|Преимущественно солнечно Sunny|Солнечно Sun|Солнце Rain/Thunder|Дождь/Гром @@ -25,9 +25,9 @@ Severe|Тяжелый Clear|Ясно Fair|Светлый Partly|Частично -Mostly|По большй части -Cloudy|Облочно -Clouds|Облока +Mostly|По большей части +Cloudy|Облачно +Clouds|Облака Scattered Showers|Рассеянные ливни Light Snow Showers|Небольшой снег Snow Showers|Ливневый Снег @@ -42,7 +42,7 @@ Blowing Snow|Снег и ветер Blowing Rain|Дождь и ветер Heavy Rain|Сильный дождь Freezing Rain|Ледяной дождь -Showers|Ливени +Showers|Ливни Light Rain|Небольшой дождь Heavy|Сильный Rain|Дождь From 2e266a88d99114b769df282455126d972b8493fa Mon Sep 17 00:00:00 2001 From: themarcq Date: Mon, 8 Dec 2014 16:32:44 +0100 Subject: [PATCH 478/546] Now gaps between windows and screen borders and gaps vetween windows and windows are the same. --- layout/uselesstile.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index eccfdad..65ce9b5 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -80,8 +80,8 @@ local function tile_group(cls, wa, orientation, fact, group) local i = c - group.first +1 geom[width] = size - global_border - (bw * 2) geom[height] = math.floor(unused * fact[i] / total_fact) - (bw * 2) - geom[x] = group.coord + global_border + (useless_gap / 2) - geom[y] = coord + global_border + (useless_gap / 2) + geom[x] = group.coord + global_border + geom[y] = coord + global_border coord = coord + geom[height] unused = unused - geom[height] From 9e72153c6dba0f7bf919effc3494b1a12e2e45d9 Mon Sep 17 00:00:00 2001 From: Rongzhou Shen Date: Sat, 27 Dec 2014 12:14:13 -0800 Subject: [PATCH 479/546] Adding a moc widget to lain --- widgets/moc.lua | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 widgets/moc.lua diff --git a/widgets/moc.lua b/widgets/moc.lua new file mode 100644 index 0000000..9b1380a --- /dev/null +++ b/widgets/moc.lua @@ -0,0 +1,90 @@ +local helpers = require("lain.helpers") +local async = require("lain.asyncshell") + +local escape_f = require("awful.util").escape +local naughty = require("naughty") +local wibox = require("wibox") + +local io = { popen = io.popen } +local os = { execute = os.execute, + getenv = os.getenv } +local string = { format = string.format, + gmatch = string.gmatch } + +local setmetatable = setmetatable + +local moc = {} + +local function worker(args) + local args = args or {} + local timeout = args.timeout or 2 + local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" + local cover_size = args.cover_size or 100 + local default_art = args.default_art or "" + local settings = args.settings or function() end + + local mpdcover = helpers.scripts_dir .. "mpdcover" + + moc.widget = wibox.widget.textbox('') + + moc_notification_preset = { + title = "Now playing", + timeout = 6 + } + + helpers.set_map("current moc track", nil) + + function moc.update() + async.request("mocp -i", function(f) + moc_now = { + state = "N/A", + file = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", + elapsed = "N/A", + total = "N/A" + } + + for line in f:lines() do + for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do + if k == "State" then moc_now.state = v + elseif k == "File" then moc_now.file = v + elseif k == "Artist" then moc_now.artist = escape_f(v) + elseif k == "SongTitle" then moc_now.title = escape_f(v) + elseif k == "Album" then moc_now.album = escape_f(v) + elseif k == "CurrentTime" then moc_now.elapsed = escape_f(v) + elseif k == "TotalTime" then moc_now.total = escape_f(v) + end + end + end + + moc_notification_preset.text = string.format("%s (%s) - %s\n%s", moc_now.artist, + moc_now.album, moc_now.total, moc_now.title) + widget = moc.widget + settings() + + if moc_now.state == "PLAY" then + if moc_now.title ~= helpers.get_map("current moc track") then + helpers.set_map("current moc track", moc_now.title) + os.execute(string.format("%s %q %q %d %q", mpdcover, "", + moc_now.file, cover_size, default_art)) + + moc.id = naughty.notify({ + preset = moc_notification_preset, + icon = "/tmp/mpdcover.png", + replaces_id = moc.id, + }).id + end + elseif moc_now.state ~= "PAUSE" then + helpers.set_map("current moc track", nil) + end + end) + end + + helpers.newtimer("moc", timeout, moc.update) + + return setmetatable(moc, { __index = moc.widget }) +end + +return setmetatable(moc, { __call = function(_, ...) return worker(...) end }) From bb5204a72237b7bc3731517988769f19fffd7ae5 Mon Sep 17 00:00:00 2001 From: Rongzhou Shen Date: Sat, 27 Dec 2014 12:58:56 -0800 Subject: [PATCH 480/546] Moving moc to contrib and adding license information --- widgets/{ => contrib}/moc.lua | 36 +++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) rename widgets/{ => contrib}/moc.lua (76%) diff --git a/widgets/moc.lua b/widgets/contrib/moc.lua similarity index 76% rename from widgets/moc.lua rename to widgets/contrib/moc.lua index 9b1380a..84c618b 100644 --- a/widgets/moc.lua +++ b/widgets/contrib/moc.lua @@ -1,3 +1,11 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2014, anticlockwise + +--]] + local helpers = require("lain.helpers") local async = require("lain.asyncshell") @@ -16,34 +24,38 @@ local setmetatable = setmetatable local moc = {} local function worker(args) - local args = args or {} - local timeout = args.timeout or 2 - local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" - local cover_size = args.cover_size or 100 + local args = args or {} + local timeout = args.timeout or 2 + local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" + local cover_size = args.cover_size or 100 local default_art = args.default_art or "" - local settings = args.settings or function() end + local settings = args.settings or function() end local mpdcover = helpers.scripts_dir .. "mpdcover" moc.widget = wibox.widget.textbox('') moc_notification_preset = { - title = "Now playing", + title = "Now playing", timeout = 6 } helpers.set_map("current moc track", nil) function moc.update() + -- mocp -i will produce output like: + -- Artist: Travis + -- Album: The Man Who + -- etc. async.request("mocp -i", function(f) moc_now = { - state = "N/A", - file = "N/A", - artist = "N/A", - title = "N/A", - album = "N/A", + state = "N/A", + file = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", elapsed = "N/A", - total = "N/A" + total = "N/A" } for line in f:lines() do From 1f02db5e241f1435c2f4ab5dd8978db31a8755cd Mon Sep 17 00:00:00 2001 From: worron Date: Mon, 5 Jan 2015 23:31:52 +0300 Subject: [PATCH 481/546] Window border width issue fixes in uselessfair --- layout/uselessfair.lua | 55 ++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 34 deletions(-) diff --git a/layout/uselessfair.lua b/layout/uselessfair.lua index 6a386c3..058dae6 100644 --- a/layout/uselessfair.lua +++ b/layout/uselessfair.lua @@ -1,12 +1,12 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2014, projektile - * (c) 2013, Luke Bonham - * (c) 2012, Josh Komoroske - * (c) 2010-2012, Peter Hofmann - + + Licensed under GNU General Public License v2 + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2012, Josh Komoroske + * (c) 2010-2012, Peter Hofmann + --]] local beautiful = require("beautiful") @@ -30,12 +30,17 @@ local function fair(p, orientation) -- Themes border width requires an offset. local bw = tonumber(beautiful.border_width) or 0 + -- Total window size extend + local ext = 2 * bw + useless_gap + -- get our orientation right. local wa = p.workarea local cls = p.clients - wa.height = wa.height - ((global_border * 2) + (bw * 2)) - wa.width = wa.width - ((global_border * 2) + (bw * 2)) + wa.height = wa.height - 2 * global_border - useless_gap + wa.width = wa.width - 2 * global_border - useless_gap + wa.x = wa.x + useless_gap + global_border + wa.y = wa.y + useless_gap + global_border if #cls > 0 then local cells = math.ceil(math.sqrt(#cls)) @@ -45,10 +50,7 @@ local function fair(p, orientation) local strip = 0 for k, c in ipairs(cls) do local g = {} - -- Save actual grid index for use in the useless_gap - -- routine. - local this_x = 0 - local this_y = 0 + if ( orientation == "east" and #cls > 2 ) or ( orientation == "south" and #cls <= 2 ) then if #cls < (strips * cells) and strip == strips - 1 then @@ -58,11 +60,8 @@ local function fair(p, orientation) end g.height = wa.height / strips - this_x = cell - this_y = strip - - g.x = wa.x + cell * g.width + global_border - g.y = wa.y + strip * g.height + global_border + g.x = wa.x + cell * g.width + g.y = wa.y + strip * g.height else if #cls < (strips * cells) and strip == strips - 1 then @@ -72,25 +71,13 @@ local function fair(p, orientation) end g.width = wa.width / strips - this_x = strip - this_y = cell - - g.x = wa.x + strip * g.width + global_border - g.y = wa.y + cell * g.height + global_border + g.x = wa.x + strip * g.width + g.y = wa.y + cell * g.height end - -- Useless gap. - if useless_gap > 0 - then - -- All clients tile evenly. - g.width = g.width - useless_gap - g.x = g.x + (useless_gap / 2) - g.height = g.height - useless_gap - g.y = g.y + (useless_gap / 2) - - end - -- End of useless gap. + g.width = g.width - ext + g.height = g.height - ext c:geometry(g) From 0156dc9046310fcd25b9f773fa6cad80bcd800eb Mon Sep 17 00:00:00 2001 From: worron Date: Tue, 6 Jan 2015 01:53:09 +0300 Subject: [PATCH 482/546] Window border width issue fixes in uselesstile --- layout/uselesstile.lua | 97 ++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 60 deletions(-) diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index 65ce9b5..5bb0c05 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -1,12 +1,12 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2014 projektile - * (c) 2013 Luke Bonham - * (c) 2009 Donald Ephraim Curtis - * (c) 2008 Julien Danjolu - + + Licensed under GNU General Public License v2 + * (c) 2014 projektile + * (c) 2013 Luke Bonham + * (c) 2009 Donald Ephraim Curtis + * (c) 2008 Julien Danjolu + --]] local tag = require("awful.tag") @@ -19,16 +19,7 @@ local tonumber = tonumber local uselesstile = {} -local function tile_group(cls, wa, orientation, fact, group) - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width . - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - if useless_gap < 0 then useless_gap = 0 end - - -- A global border can be defined with - -- beautiful.global_border_width - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end +local function tile_group(cls, wa, orientation, fact, group, gap) -- Themes border width requires an offset local bw = tonumber(beautiful.border_width) or 0 @@ -69,58 +60,28 @@ local function tile_group(cls, wa, orientation, fact, group) end total_fact = total_fact + fact[i] end - size = math.min(size, (available - global_border)) + size = math.min(size, available) local coord = wa[y] local geom = {} local used_size = 0 - local unused = wa[height] - (global_border * 2) + local unused = wa[height] local stat_coord = wa[x] --stat_coord = size for c = group.first,group.last do local i = c - group.first +1 - geom[width] = size - global_border - (bw * 2) + geom[width] = size - (bw * 2) geom[height] = math.floor(unused * fact[i] / total_fact) - (bw * 2) - geom[x] = group.coord + global_border - geom[y] = coord + global_border + geom[x] = group.coord + geom[y] = coord - coord = coord + geom[height] - unused = unused - geom[height] + coord = coord + geom[height] + 2 * bw + unused = unused - geom[height] - 2 * bw total_fact = total_fact - fact[i] - used_size = math.max(used_size, geom[width]) + used_size = math.max(used_size, geom[width] + 2 * bw) - -- Useless gap - if useless_gap > 0 - then - -- Top and left clients are shrinked by two steps and - -- get moved away from the border. Other clients just - -- get shrinked in one direction. - - top = false - left = false - - if geom[y] == wa[y] then - top = true - end - - if geom[x] == 0 or geom[x] == wa[x] then - left = true - end - - if top then - geom[height] = geom[height] - (2 * useless_gap) - geom[y] = geom[y] + useless_gap - else - geom[height] = geom[height] - useless_gap - end - - if left then - geom[width] = geom[width] - (2 * useless_gap) - geom[x] = geom[x] + useless_gap - else - geom[width] = geom[width] - useless_gap - end - end - -- End of useless gap. + -- Useless gap correction + geom.width = geom.width - gap + geom.height = geom.height - gap geom = cls[c]:geometry(geom) end @@ -132,6 +93,16 @@ local function tile(param, orientation) local t = tag.selected(param.screen) orientation = orientation or "right" + -- A useless gap (like the dwm patch) can be defined with + -- beautiful.useless_gap_width . + local useless_gap = tonumber(beautiful.useless_gap_width) or 0 + if useless_gap < 0 then useless_gap = 0 end + + -- A global border can be defined with + -- beautiful.global_border_width + local global_border = tonumber(beautiful.global_border_width) or 0 + if global_border < 0 then global_border = 0 end + -- this handles are different orientations local height = "height" local width = "width" @@ -152,6 +123,12 @@ local function tile(param, orientation) local wa = param.workarea local ncol = tag.getncol(t) + -- Workarea size correction + wa.height = wa.height - 2 * global_border - useless_gap + wa.width = wa.width - 2 * global_border - useless_gap + wa.x = wa.x + useless_gap + global_border + wa.y = wa.y + useless_gap + global_border + local data = tag.getdata(t).windowfact if not data then @@ -176,7 +153,7 @@ local function tile(param, orientation) if not data[0] then data[0] = {} end - coord = coord + tile_group(cls, wa, orientation, data[0], {first=1, last=nmaster, coord = coord, size = size}) + coord = coord + tile_group(cls, wa, orientation, data[0], {first=1, last=nmaster, coord = coord, size = size}, useless_gap) end if not place_master and nother > 0 then @@ -196,7 +173,7 @@ local function tile(param, orientation) if not data[i] then data[i] = {} end - coord = coord + tile_group(cls, wa, orientation, data[i], { first = first, last = last, coord = coord, size = size }) + coord = coord + tile_group(cls, wa, orientation, data[i], { first = first, last = last, coord = coord, size = size }, useless_gap) end end place_master = not place_master From 143f7ad830c28dd65189ac5a3a1d5ad7250aa45b Mon Sep 17 00:00:00 2001 From: worron Date: Sat, 10 Jan 2015 19:51:12 +0300 Subject: [PATCH 483/546] Uselessfair code refactoring --- layout/uselessfair.lua | 142 ++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/layout/uselessfair.lua b/layout/uselessfair.lua index 058dae6..ee3aa40 100644 --- a/layout/uselessfair.lua +++ b/layout/uselessfair.lua @@ -2,7 +2,7 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2014, projektile + * (c) 2014, projektile, worron * (c) 2013, Luke Bonham * (c) 2012, Josh Komoroske * (c) 2010-2012, Peter Hofmann @@ -11,98 +11,98 @@ local beautiful = require("beautiful") local ipairs = ipairs -local math = { ceil = math.ceil, sqrt = math.sqrt } +local math = { ceil = math.ceil, sqrt = math.sqrt, floor = math.floor, max = math.max } local tonumber = tonumber local uselessfair = {} +-- Transformation functions +local function swap(geometry) + return { x = geometry.y, y = geometry.x, width = geometry.height, height = geometry.width } +end + +-- Client geometry correction depending on useless gap and window border +local function size_correction(c, geometry, useless_gap) + geometry.width = math.max(geometry.width - 2 * c.border_width - useless_gap, 1) + geometry.height = math.max(geometry.height - 2 * c.border_width - useless_gap, 1) + geometry.x = geometry.x + useless_gap / 2 + geometry.y = geometry.y + useless_gap / 2 +end + +-- Main tiling function local function fair(p, orientation) - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width. - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - if useless_gap < 0 then useless_gap = 0 end - -- A global border can be defined with - -- beautiful.global_border_width. - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end + -- Theme vars + local useless_gap = beautiful.useless_gap_width or 0 + local global_border = beautiful.global_border_width or 0 - -- Themes border width requires an offset. - local bw = tonumber(beautiful.border_width) or 0 - - -- Total window size extend - local ext = 2 * bw + useless_gap - - -- get our orientation right. + -- Aliases local wa = p.workarea local cls = p.clients + -- Nothing to tile here + if #cls == 0 then return end + + -- Workarea size correction depending on useless gap and global border wa.height = wa.height - 2 * global_border - useless_gap wa.width = wa.width - 2 * global_border - useless_gap - wa.x = wa.x + useless_gap + global_border - wa.y = wa.y + useless_gap + global_border + wa.x = wa.x + useless_gap / 2 + global_border + wa.y = wa.y + useless_gap / 2 + global_border - if #cls > 0 then - local cells = math.ceil(math.sqrt(#cls)) - local strips = math.ceil(#cls / cells) + -- Geometry calculation + local row, col = 0, 0 - local cell = 0 - local strip = 0 - for k, c in ipairs(cls) do - local g = {} + local rows = math.ceil(math.sqrt(#cls)) + local cols = math.ceil(#cls / rows) - if ( orientation == "east" and #cls > 2 ) - or ( orientation == "south" and #cls <= 2 ) then - if #cls < (strips * cells) and strip == strips - 1 then - g.width = wa.width / (cells - ((strips * cells) - #cls)) - else - g.width = wa.width / cells - end - g.height = wa.height / strips + for i, c in ipairs(cls) do + local g = {} - g.x = wa.x + cell * g.width - g.y = wa.y + strip * g.height + -- find tile orientation for current client and swap geometry if need + local need_swap = (orientation == "east" and #cls <= 2) or (orientation == "south" and #cls > 2) + local area = need_swap and swap(wa) or wa - else - if #cls < (strips * cells) and strip == strips - 1 then - g.height = wa.height / (cells - ((strips * cells) - #cls)) - else - g.height = wa.height / cells - end - g.width = wa.width / strips - - g.x = wa.x + strip * g.width - g.y = wa.y + cell * g.height - - end - - g.width = g.width - ext - g.height = g.height - ext - - c:geometry(g) - - cell = cell + 1 - if cell == cells then - cell = 0 - strip = strip + 1 - end + -- calculate geometry + if #cls < (cols * rows) and row == cols - 1 then + g.width = area.width / (rows - ((cols * rows) - #cls)) + else + g.width = area.width / rows end + + g.height = area.height / cols + g.x = area.x + col * g.width + g.y = area.y + row * g.height + + -- turn back to real if geometry was swapped + if need_swap then g = swap(g) end + + -- window size correction depending on useless gap and window border + size_correction(c, g, useless_gap) + + -- set geometry + c:geometry(g) + + -- update tile grid coordinates + col = i % rows + row = math.floor(i / rows) end end ---- Horizontal fair layout. --- @param screen The screen to arrange. -uselessfair.horizontal = {} -uselessfair.horizontal.name = "uselessfairh" -function uselessfair.horizontal.arrange(p) - return fair(p, "east") +-- Layout constructor +local function construct_layout(name, direction) + return { + name = name, + -- @p screen The screen number to tile + arrange = function(p) return fair(p, direction) end + } end --- Vertical fair layout. --- @param screen The screen to arrange. -uselessfair.name = "uselessfair" -function uselessfair.arrange(p) - return fair(p, "south") -end +-- Build layouts with different tile direction +uselessfair.vertical = construct_layout("uselessfair", "south") +uselessfair.horizontal = construct_layout("uselessfairh", "east") + +-- Module aliase +uselessfair.arrange = uselessfair.vertical.arrange +uselessfair.name = uselessfair.vertical.name return uselessfair From 605ab1f899b8cc5b1c3257b64f9076a755879e0a Mon Sep 17 00:00:00 2001 From: worron Date: Sat, 10 Jan 2015 19:52:08 +0300 Subject: [PATCH 484/546] Uselesstile code refactoring --- layout/uselesstile.lua | 316 +++++++++++++++++++---------------------- 1 file changed, 146 insertions(+), 170 deletions(-) diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index 5bb0c05..d244f43 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -2,7 +2,7 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2014 projektile + * (c) 2014 projektile, worron * (c) 2013 Luke Bonham * (c) 2009 Donald Ephraim Curtis * (c) 2008 Julien Danjolu @@ -13,204 +13,180 @@ local tag = require("awful.tag") local beautiful = require("beautiful") local ipairs = ipairs local math = { floor = math.floor, + ceil = math.ceil, max = math.max, min = math.min } local tonumber = tonumber local uselesstile = {} -local function tile_group(cls, wa, orientation, fact, group, gap) - - -- Themes border width requires an offset - local bw = tonumber(beautiful.border_width) or 0 - - -- get our orientation right - local height = "height" - local width = "width" - local x = "x" - local y = "y" - if orientation == "top" or orientation == "bottom" then - height = "width" - width = "height" - x = "y" - y = "x" - end - - -- make this more generic (not just width) - --if for top - available = wa[width] - (group.coord - wa[x]) -- it's truly not here - - -- find our total values - local total_fact = 0 - local min_fact = 1 - local size = group.size - for c = group.first,group.last do - -- determine the width/height based on the size_hint - local i = c - group.first +1 - local size_hints = cls[c].size_hints - local size_hint = size_hints["min_"..width] or size_hints["base_"..width] or 0 - size_hint = size_hint + cls[c].border_width*2 - size = math.max(size_hint, size) - - -- calculate the height - if not fact[i] then - fact[i] = min_fact - else - min_fact = math.min(fact[i],min_fact) - end - total_fact = total_fact + fact[i] - end - size = math.min(size, available) - local coord = wa[y] - local geom = {} - local used_size = 0 - local unused = wa[height] - local stat_coord = wa[x] - --stat_coord = size - for c = group.first,group.last do - local i = c - group.first +1 - geom[width] = size - (bw * 2) - geom[height] = math.floor(unused * fact[i] / total_fact) - (bw * 2) - geom[x] = group.coord - geom[y] = coord - - coord = coord + geom[height] + 2 * bw - unused = unused - geom[height] - 2 * bw - total_fact = total_fact - fact[i] - used_size = math.max(used_size, geom[width] + 2 * bw) - - -- Useless gap correction - geom.width = geom.width - gap - geom.height = geom.height - gap - - geom = cls[c]:geometry(geom) - end - - return used_size +-- Transformation functions +local function flip(canvas, geometry) + return { + -- vertical only + x = 2 * canvas.x + canvas.width - geometry.x - geometry.width, + y = geometry.y, + width = geometry.width, + height = geometry.height + } end -local function tile(param, orientation) - local t = tag.selected(param.screen) - orientation = orientation or "right" +local function swap(geometry) + return { x = geometry.y, y = geometry.x, width = geometry.height, height = geometry.width } +end - -- A useless gap (like the dwm patch) can be defined with - -- beautiful.useless_gap_width . - local useless_gap = tonumber(beautiful.useless_gap_width) or 0 - if useless_gap < 0 then useless_gap = 0 end +-- Find geometry for column/row tiling +local function cut_area(wa, total, index, is_horizontal) + local wa = is_horizontal and swap(wa) or wa + local height = wa.height / total - -- A global border can be defined with - -- beautiful.global_border_width - local global_border = tonumber(beautiful.global_border_width) or 0 - if global_border < 0 then global_border = 0 end + local area = { + x = wa.x, + y = wa.y + (index - 1) * height, + width = wa.width, + height = height + } - -- this handles are different orientations - local height = "height" - local width = "width" - local x = "x" - local y = "y" - if orientation == "top" or orientation == "bottom" then - height = "width" - width = "height" - x = "y" - y = "x" + if is_horizontal then area = swap(area) end + + return area +end + +-- Client geometry correction depending on useless gap and window border +local function size_correction(c, geometry, useless_gap) + geometry.width = math.max(geometry.width - 2 * c.border_width - useless_gap, 1) + geometry.height = math.max(geometry.height - 2 * c.border_width - useless_gap, 1) + geometry.x = geometry.x + useless_gap / 2 + geometry.y = geometry.y + useless_gap / 2 +end + +-- Tile group of clients in given area +-- @canvas need for proper transformation only +local function tile_column(canvas, area, list, useless_gap, transformation) + for i, c in ipairs(list) do + local g = cut_area(area, #list, i) + + -- swap workarea dimensions + if transformation.flip then g = flip(canvas, g) end + if transformation.swap then g = swap(g) end + + -- useless gap and border correction + size_correction(c, g, useless_gap) + + c:geometry(g) + end +end + +--Main tile function +local function tile(p, orientation) + + -- Theme vars + local useless_gap = beautiful.useless_gap_width or 0 + local global_border = beautiful.global_border_width or 0 + + -- Aliases + local wa = p.workarea + local cls = p.clients + local t = tag.selected(p.screen) + + -- Nothing to tile here + if #cls == 0 then return end + + -- Get tag prop + local nmaster = math.min(tag.getnmaster(t), #cls) + local mwfact = tag.getmwfact(t) + + if nmaster == 0 then + mwfact = 0 + elseif nmaster == #cls then + mwfact = 1 end - local cls = param.clients - local nmaster = math.min(tag.getnmaster(t), #cls) - local nother = math.max(#cls - nmaster,0) - - local mwfact = tag.getmwfact(t) - local wa = param.workarea - local ncol = tag.getncol(t) - - -- Workarea size correction + -- Workarea size correction depending on useless gap and global border wa.height = wa.height - 2 * global_border - useless_gap wa.width = wa.width - 2 * global_border - useless_gap - wa.x = wa.x + useless_gap + global_border - wa.y = wa.y + useless_gap + global_border + wa.x = wa.x + useless_gap / 2 + global_border + wa.y = wa.y + useless_gap / 2 + global_border - local data = tag.getdata(t).windowfact + -- Find which transformation we need for given orientation + local transformation = { + swap = orientation == 'top' or orientation == 'bottom', + flip = orientation == 'left' or orientation == 'top' + } - if not data then - data = {} - tag.getdata(t).windowfact = data + -- Swap workarea dimensions if orientation vertical + if transformation.swap then wa = swap(wa) end + + -- Split master and other windows + local cls_master, cls_other = {}, {} + + for i, c in ipairs(cls) do + if i <= nmaster then + table.insert(cls_master, c) + else + table.insert(cls_other, c) + end end - local coord = wa[x] - local place_master = true - if orientation == "left" or orientation == "top" then - -- if we are on the left or top we need to render the other windows first - place_master = false - end + -- Tile master windows + local master_area = { + x = wa.x, + y = wa.y, + width = nmaster > 0 and wa.width * mwfact or 0, + height = wa.height + } - -- this was easier than writing functions because there is a lot of data we need - for d = 1,2 do - if place_master and nmaster > 0 then - local size = wa[width] - if nother > 0 then - size = math.min(wa[width] * mwfact, wa[width] - (coord - wa[x])) - end - if not data[0] then - data[0] = {} - end - coord = coord + tile_group(cls, wa, orientation, data[0], {first=1, last=nmaster, coord = coord, size = size}, useless_gap) + tile_column(wa, master_area, cls_master, useless_gap, transformation) + + -- Tile other windows + local other_area = { + x = wa.x + master_area.width, + y = wa.y, + width = wa.width - master_area.width, + height = wa.height + } + + -- get column number for other windows + local ncol = math.min(tag.getncol(t), #cls_other) + + -- split other windows to column groups + local last_small_column = ncol - #cls_other % ncol + local rows_min = math.floor(#cls_other / ncol) + + local client_index = 1 + for i = 1, ncol do + local position = transformation.flip and ncol - i + 1 or i + local rows = i <= last_small_column and rows_min or rows_min + 1 + local column = {} + + for j = 1, rows do + table.insert(column, cls_other[client_index]) + client_index = client_index + 1 end - if not place_master and nother > 0 then - local last = nmaster - - -- we have to modify the work area size to consider left and top views - local wasize = wa[width] - if nmaster > 0 and (orientation == "left" or orientation == "top") then - wasize = wa[width] - wa[width]*mwfact - end - for i = 1,ncol do - -- Try to get equal width among remaining columns - local size = math.min((wasize - (coord - wa[x])) / (ncol - i + 1)) --+ (global_border/(ncol))/(ncol+i^2) - local first = last + 1 - last = last + math.floor((#cls - last)/(ncol - i + 1)) - -- tile the column and update our current x coordinate - if not data[i] then - data[i] = {} - end - coord = coord + tile_group(cls, wa, orientation, data[i], { first = first, last = last, coord = coord, size = size }, useless_gap) - end - end - place_master = not place_master + -- and tile + local column_area = cut_area(other_area, ncol, position, true) + tile_column(wa, column_area, column, useless_gap, transformation) end - end -uselesstile.right = {} -uselesstile.right.name = "uselesstile" -uselesstile.right.arrange = tile - ---- The main tile algo, on left. --- @param screen The screen number to tile. -uselesstile.left = {} -uselesstile.left.name = "uselesstileleft" -function uselesstile.left.arrange(p) - return tile(p, "left") +-- Layout constructor +local function construct_layout(name, orientation) + return { + name = name, + -- @p screen number to tile + arrange = function(p) return tile(p, orientation) end + } end ---- The main tile algo, on bottom. --- @param screen The screen number to tile. -uselesstile.bottom = {} -uselesstile.bottom.name = "uselesstilebottom" -function uselesstile.bottom.arrange(p) - return tile(p, "bottom") -end - ---- The main tile algo, on top. --- @param screen The screen number to tile. -uselesstile.top = {} -uselesstile.top.name = "uselesstiletop" -function uselesstile.top.arrange(p) - return tile(p, "top") -end +-- Build layouts with different tile direction +uselesstile.right = construct_layout("uselesstile", "right") +uselesstile.left = construct_layout("uselesstileleft", "left") +uselesstile.bottom = construct_layout("uselesstilebottom", "bottom") +uselesstile.top = construct_layout("uselesstiletop", "top") +-- Module aliase uselesstile.arrange = uselesstile.right.arrange uselesstile.name = uselesstile.right.name return uselesstile - From b2d2d6117e07790ef0493686bd743cb78361a276 Mon Sep 17 00:00:00 2001 From: Yuexiao Guo Date: Mon, 12 Jan 2015 18:27:39 -0500 Subject: [PATCH 485/546] fixed mount point length calculation and misalignment of 4-digit size numbers --- scripts/dfs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/dfs b/scripts/dfs index d78d2bb..f04b051 100755 --- a/scripts/dfs +++ b/scripts/dfs @@ -107,7 +107,7 @@ fi # Computing mount point max length # ------------------------------------------------------------------------- MOUNT_POINT_MAX_LENGTH=` \ - echo $SORTED_FILE_SYSTEMS_INFO | $AWK_COMMAND -v PATTERN=$PATTERN \ + echo "$SORTED_FILE_SYSTEMS_INFO" | $AWK_COMMAND -v PATTERN=$PATTERN \ ' BEGIN { mount_point_length_max = 15; @@ -364,22 +364,22 @@ $0 ~ PATTERN { if (total_size > 1 * t_bytes) printf ( \ - "| %3d%% %5.1f %5.1f Tb\n", \ + "| %3d%% %6.1f %6.1f Tb\n", \ percentage_occupied, free_size / t_bytes, total_size / t_bytes \ ); else if (total_size > 1 * g_bytes) printf ( \ - "| %3d%% %5.1f %5.1f Gb\n", \ + "| %3d%% %6.1f %6.1f Gb\n", \ percentage_occupied, free_size / g_bytes, total_size / g_bytes \ ); else if (total_size > 1 * m_byptes) printf ( \ - "| %3d%% %5.1f %5.1f Mb\n", \ + "| %3d%% %6.1f %6.1f Mb\n", \ percentage_occupied, free_size / m_bytes, total_size / m_bytes \ ); else printf ( \ - "| %3d%% %5.1f %5.1f Kb\n", \ + "| %3d%% %6.1f %6.1f Kb\n", \ percentage_occupied, free_size / k_bytes, total_size / k_bytes \ ); } From 7939cfcd90809aeb746d0def75f474c2433c182f Mon Sep 17 00:00:00 2001 From: Jack Pugmire Date: Thu, 15 Jan 2015 23:44:22 -0500 Subject: [PATCH 486/546] Added keys to mpd_now for querying the length of a song and the current time (both in seconds). --- widgets/mpd.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 7fd611d..99624a2 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -58,7 +58,9 @@ local function worker(args) artist = "N/A", title = "N/A", album = "N/A", - date = "N/A" + date = "N/A", + time = "N/A", + elapsed= "N/A" } for line in f:lines() do @@ -69,6 +71,8 @@ local function worker(args) elseif k == "Title" then mpd_now.title = escape_f(v) elseif k == "Album" then mpd_now.album = escape_f(v) elseif k == "Date" then mpd_now.date = escape_f(v) + elseif k == "Time" then mpd_now.time = v + elseif k == "elapsed"then mpd_now.elapsed= math.floor(v) end end end From bbe0b1903dbf0edfa996a2ef5225f00698643edc Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 20 Jan 2015 10:16:06 +0100 Subject: [PATCH 487/546] pull #90: fixed tabs --- widgets/mpd.lua | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 99624a2..9054c22 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -53,26 +53,26 @@ local function worker(args) function mpd.update() async.request(echo .. " | curl --connect-timeout 1 -fsm 3 " .. mpdh, function (f) mpd_now = { - state = "N/A", - file = "N/A", - artist = "N/A", - title = "N/A", - album = "N/A", - date = "N/A", - time = "N/A", - elapsed= "N/A" + state = "N/A", + file = "N/A", + artist = "N/A", + title = "N/A", + album = "N/A", + date = "N/A", + time = "N/A", + elapsed = "N/A" } for line in f:lines() do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do - if k == "state" then mpd_now.state = v - elseif k == "file" then mpd_now.file = v - elseif k == "Artist" then mpd_now.artist = escape_f(v) - elseif k == "Title" then mpd_now.title = escape_f(v) - elseif k == "Album" then mpd_now.album = escape_f(v) - elseif k == "Date" then mpd_now.date = escape_f(v) - elseif k == "Time" then mpd_now.time = v - elseif k == "elapsed"then mpd_now.elapsed= math.floor(v) + if k = = "state" then mpd_now.state = v + elseif k = = "file" then mpd_now.file = v + elseif k = = "Artist" then mpd_now.artist = escape_f(v) + elseif k = = "Title" then mpd_now.title = escape_f(v) + elseif k = = "Album" then mpd_now.album = escape_f(v) + elseif k = = "Date" then mpd_now.date = escape_f(v) + elseif k = = "Time" then mpd_now.time = v + elseif k = = "elapsed" then mpd_now.elapsed = math.floor(v) end end end From 3261164a88bc052e88172b4bc73d24846ad7468e Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 20 Jan 2015 10:18:15 +0100 Subject: [PATCH 488/546] mpd: fixed bad auto-fixed scope --- widgets/mpd.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 9054c22..0d43e34 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -65,14 +65,14 @@ local function worker(args) for line in f:lines() do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do - if k = = "state" then mpd_now.state = v - elseif k = = "file" then mpd_now.file = v - elseif k = = "Artist" then mpd_now.artist = escape_f(v) - elseif k = = "Title" then mpd_now.title = escape_f(v) - elseif k = = "Album" then mpd_now.album = escape_f(v) - elseif k = = "Date" then mpd_now.date = escape_f(v) - elseif k = = "Time" then mpd_now.time = v - elseif k = = "elapsed" then mpd_now.elapsed = math.floor(v) + if k == "state" then mpd_now.state = v + elseif k == "file" then mpd_now.file = v + elseif k == "Artist" then mpd_now.artist = escape_f(v) + elseif k == "Title" then mpd_now.title = escape_f(v) + elseif k == "Album" then mpd_now.album = escape_f(v) + elseif k == "Date" then mpd_now.date = escape_f(v) + elseif k == "Time" then mpd_now.time = v + elseif k == "elapsed" then mpd_now.elapsed = math.floor(v) end end end From d46745e1b37c62ebc08280e1b8e7197d56016bd0 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 30 Jan 2015 14:12:13 +0100 Subject: [PATCH 489/546] mpd: mpd_now.elapsed seconds fixed --- widgets/mpd.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 0d43e34..c10eb78 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -14,10 +14,11 @@ local escape_f = require("awful.util").escape local naughty = require("naughty") local wibox = require("wibox") -local io = { popen = io.popen } local os = { execute = os.execute, getenv = os.getenv } +local math = { floor = math.floor } local string = { format = string.format, + match = string.match, gmatch = string.gmatch } local setmetatable = setmetatable @@ -72,7 +73,7 @@ local function worker(args) elseif k == "Album" then mpd_now.album = escape_f(v) elseif k == "Date" then mpd_now.date = escape_f(v) elseif k == "Time" then mpd_now.time = v - elseif k == "elapsed" then mpd_now.elapsed = math.floor(v) + elseif k == "elapsed" then mpd_now.elapsed = string.match(v, "%d+") end end end From eac077ace2153bc949a304d91fa1e899108a4b30 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 30 Jan 2015 14:26:37 +0100 Subject: [PATCH 490/546] new submodule: lain.util.separators --- util/separators.lua | 102 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 util/separators.lua diff --git a/util/separators.lua b/util/separators.lua new file mode 100644 index 0000000..0eb0658 --- /dev/null +++ b/util/separators.lua @@ -0,0 +1,102 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2015, luke bonham + * (c) 2015, plotnikovanton + +--]] + +local wibox = require("wibox") +local beautiful = require("beautiful") +local gears = require("gears") + +-- Lain cairo separators util submodule +-- lain.util.separators +local separators = {} + +local height = beautiful.awful_widget_height or 0 +local width = beautiful.separators_width or 9 + +-- [[ Arrow + +-- Right +function separators.arrow_right(col1, col2) + local widget = wibox.widget.base.make_widget() + + widget.fit = function(m, w, h) return width, height end + + widget.draw = function(mycross, wibox, cr, width, height) + if col2 ~= "alpha" then + cr:set_source_rgb(gears.color.parse_color(col2)) + cr:new_path() + cr:move_to(0, 0) + cr:line_to(width, height/2) + cr:line_to(width, 0) + cr:close_path() + cr:fill() + + cr:new_path() + cr:move_to(0, height) + cr:line_to(width, height/2) + cr:line_to(width, height) + cr:close_path() + cr:fill() + end + + if col1 ~= "alpha" then + cr:set_source_rgb(gears.color.parse_color(col1)) + cr:new_path() + cr:move_to(0, 0) + cr:line_to(width, height/2) + cr:line_to(0, height) + cr:close_path() + cr:fill() + end + end + + return widget +end + +-- Left +function separators.arrow_left(col1, col2) + local widget = wibox.widget.base.make_widget() + + widget.fit = function(m, w, h) return width, height end + + widget.draw = function(mycross, wibox, cr, width, height) + if col1 ~= "alpha" then + cr:set_source_rgb(gears.color.parse_color(col1)) + cr:new_path() + cr:move_to(width, 0) + cr:line_to(0, height/2) + cr:line_to(0, 0) + cr:close_path() + cr:fill() + + cr:new_path() + cr:move_to(width, height) + cr:line_to(0, height/2) + cr:line_to(0, height) + cr:close_path() + cr:fill() + end + + if col2 ~= "alpha" then + cr:new_path() + cr:move_to(width, 0) + cr:line_to(0, height/2) + cr:line_to(width, height) + cr:close_path() + + cr:set_source_rgb(gears.color.parse_color(col2)) + cr:fill() + end + end + + return widget +end + +-- ]] + +return separators From 527e38f4372a5821706295bf553b64abc6aa5b5a Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Thu, 5 Feb 2015 09:07:28 +0100 Subject: [PATCH 491/546] #91 pull + clean useless lines --- widgets/calendar.lua | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 631b358..cbba676 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -37,17 +37,12 @@ function calendar:show(t_out, inc_offset, scr) local tims = t_out or 0 local f, c_text local today = tonumber(os.date('%d')) - local init_t = calendar.cal .. ' | sed -r -e "s/(^| )( ' + local init_t = calendar.cal .. ' | sed -r -e "s/_\\x08//g" | sed -r -e "s/(^| )(' calendar.offset = calendar.offset + offs if offs == 0 or calendar.offset == 0 then -- current month showing, today highlighted - if today >= 10 - then - init_t = calendar.cal .. ' | sed -r -e "s/_\\x08//g" | sed -r -e "s/(^| )(' - end - calendar.offset = 0 calendar.notify_icon = calendar.icons .. today .. ".png" From 7f203ab08d80c6e7b663f184d1b34fd6d87564b3 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 1 Feb 2015 11:39:26 +0100 Subject: [PATCH 492/546] asyncshell.request: removed unused argument --- asyncshell.lua | 3 +-- helpers.lua | 2 +- util/separators.lua | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/asyncshell.lua b/asyncshell.lua index 4a01caa..36ccc47 100644 --- a/asyncshell.lua +++ b/asyncshell.lua @@ -44,8 +44,7 @@ function asyncshell.request(command, callback) string.format("sh -c '%s > %s; " .. 'echo "asyncshell.deliver(%s)" | ' .. "awesome-client' 2> /dev/null", - string.gsub(command, "'", "'\\''"), tmpfname, - id, tmpfname) + string.gsub(command, "'", "'\\''"), tmpfname, id) spawn(req, false) return id end diff --git a/helpers.lua b/helpers.lua index 1dfb09b..9c4a83f 100644 --- a/helpers.lua +++ b/helpers.lua @@ -9,7 +9,7 @@ local debug = require("debug") local capi = { timer = timer } -local io = { open = io.open, +local io = { open = io.open, lines = io.lines } local rawget = rawget diff --git a/util/separators.lua b/util/separators.lua index 0eb0658..d2a3891 100644 --- a/util/separators.lua +++ b/util/separators.lua @@ -2,7 +2,7 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2015, luke bonham + * (c) 2015, Luke Bonham * (c) 2015, plotnikovanton --]] @@ -11,7 +11,7 @@ local wibox = require("wibox") local beautiful = require("beautiful") local gears = require("gears") --- Lain cairo separators util submodule +-- Lain Cairo separators util submodule -- lain.util.separators local separators = {} From d93913253e61b1e23351ba7ef0ba54475f814be5 Mon Sep 17 00:00:00 2001 From: worron Date: Thu, 12 Feb 2015 20:16:14 +0300 Subject: [PATCH 493/546] Vertical client resizing fix --- layout/uselesstile.lua | 66 +++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index d244f43..bd365a8 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -35,19 +35,18 @@ local function swap(geometry) return { x = geometry.y, y = geometry.x, width = geometry.height, height = geometry.width } end --- Find geometry for column/row tiling -local function cut_area(wa, total, index, is_horizontal) - local wa = is_horizontal and swap(wa) or wa - local height = wa.height / total +-- Find geometry for secondary windows column +local function cut_column(wa, n, index) + local width = wa.width / n + local area = { x = wa.x + (index - 1) * width, y = wa.y, width = width, height = wa.height } - local area = { - x = wa.x, - y = wa.y + (index - 1) * height, - width = wa.width, - height = height - } + return area +end - if is_horizontal then area = swap(area) end +-- Find geometry for certain window in column +local function cut_row(wa, factor, index, used) + local height = wa.height * factor.window[index] / factor.total + local area = { x = wa.x, y = wa.y + used, width = wa.width, height = height } return area end @@ -60,11 +59,33 @@ local function size_correction(c, geometry, useless_gap) geometry.y = geometry.y + useless_gap / 2 end +-- Check size factor for group of clients and calculate total +local function calc_factor(n, winfactors) + local factor = { window = winfactors, total = 0, min = 1 } + + for i = 1, n do + if not factor.window[i] then + factor.window[i] = factor.min + else + factor.min = math.min(factor.window[i], factor.min) + if factor.window[i] < 0.05 then factor.window[i] = 0.05 end + end + factor.total = factor.total + factor.window[i] + end + + return factor +end + -- Tile group of clients in given area -- @canvas need for proper transformation only -local function tile_column(canvas, area, list, useless_gap, transformation) +-- @winfactors table with clients size factors +local function tile_column(canvas, area, list, useless_gap, transformation, winfactors) + local used = 0 + local factor = calc_factor(#list, winfactors) + for i, c in ipairs(list) do - local g = cut_area(area, #list, i) + local g = cut_row(area, factor, i, used) + used = used + g.height -- swap workarea dimensions if transformation.flip then g = flip(canvas, g) end @@ -102,6 +123,14 @@ local function tile(p, orientation) mwfact = 1 end + -- clients size factor + local data = tag.getdata(t).windowfact + + if not data then + data = {} + tag.getdata(t).windowfact = data + end + -- Workarea size correction depending on useless gap and global border wa.height = wa.height - 2 * global_border - useless_gap wa.width = wa.width - 2 * global_border - useless_gap @@ -136,7 +165,8 @@ local function tile(p, orientation) height = wa.height } - tile_column(wa, master_area, cls_master, useless_gap, transformation) + if not data[0] then data[0] = {} end + tile_column(wa, master_area, cls_master, useless_gap, transformation, data[0]) -- Tile other windows local other_area = { @@ -164,9 +194,11 @@ local function tile(p, orientation) client_index = client_index + 1 end - -- and tile - local column_area = cut_area(other_area, ncol, position, true) - tile_column(wa, column_area, column, useless_gap, transformation) + -- and tile + local column_area = cut_column(other_area, ncol, position) + + if not data[i] then data[i] = {} end + tile_column(wa, column_area, column, useless_gap, transformation, data[i]) end end From 82442ce10b2fb8406f8be3b517f1515b47c39ae3 Mon Sep 17 00:00:00 2001 From: emikkva Date: Mon, 16 Feb 2015 23:43:06 +0200 Subject: [PATCH 494/546] Add a card attribute for alsa and alsabar Currently alsa.lua and alsabar.lua do not support the amixer command line option "-c" which allows defining which card to use. For at least new Dell E-series laptops, the card is not the default (0) and therefore this functionality is required for these widgets to work. --- widgets/alsa.lua | 6 ++++-- widgets/alsabar.lua | 11 ++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/widgets/alsa.lua b/widgets/alsa.lua index f62a150..5a4335e 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -12,7 +12,8 @@ local newtimer = require("lain.helpers").newtimer local wibox = require("wibox") local io = { popen = io.popen } -local string = { match = string.match } +local string = { match = string.match, + format = string.format } local setmetatable = setmetatable @@ -22,6 +23,7 @@ local alsa = {} local function worker(args) local args = args or {} + local card = args.card or "0" local timeout = args.timeout or 5 local channel = args.channel or "Master" local settings = args.settings or function() end @@ -29,7 +31,7 @@ local function worker(args) alsa.widget = wibox.widget.textbox('') function alsa.update() - local f = assert(io.popen('amixer -M get ' .. channel)) + local f = assert(io.popen(string.format("amixer -c %s -M get %s", card, channel))) local mixer = f:read("*a") f:close() diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 65a2b33..fa10bc2 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -25,6 +25,7 @@ local setmetatable = setmetatable -- ALSA volume bar -- lain.widgets.alsabar local alsabar = { + card = "0", channel = "Master", step = "5%", @@ -97,6 +98,7 @@ local function worker(args) local ticks_size = args.ticks_size or 7 local vertical = args.vertical or false + alsabar.card = args.card or alsabar.card alsabar.channel = args.channel or alsabar.channel alsabar.step = args.step or alsabar.step alsabar.colors = args.colors or alsabar.colors @@ -115,7 +117,7 @@ local function worker(args) function alsabar.update() -- Get mixer control contents - local f = io.popen("amixer -M get " .. alsabar.channel) + local f = assert(io.popen(string.format("amixer -c %s -M get %s", alsabar.card, alsabar.channel))) local mixer = f:read("*a") f:close() @@ -129,7 +131,6 @@ local function worker(args) alsabar._current_level = tonumber(volu) alsabar.bar:set_value(alsabar._current_level / 100) - if not mute and tonumber(volu) == 0 or mute == "off" then alsabar._muted = true @@ -154,15 +155,15 @@ local function worker(args) awful.util.spawn(alsabar.mixer) end), awful.button ({}, 3, function() - awful.util.spawn(string.format("amixer set %s toggle", alsabar.channel)) + awful.util.spawn(string.format("amixer -c %s set %s toggle", alsabar.card, alsabar.channel)) alsabar.update() end), awful.button ({}, 4, function() - awful.util.spawn(string.format("amixer set %s %s+", alsabar.channel, alsabar.step)) + awful.util.spawn(string.format("amixer -c %s set %s %s+", alsabar.card, alsabar.channel, alsabar.step)) alsabar.update() end), awful.button ({}, 5, function() - awful.util.spawn(string.format("amixer set %s %s-", alsabar.channel, alsabar.step)) + awful.util.spawn(string.format("amixer -c %s set %s %s-", alsabar.card, alsabar.channel, alsabar.step)) alsabar.update() end) )) From 223125b60b652d6dd45168f02b732eca86ab8456 Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Mon, 9 Mar 2015 21:33:11 +0100 Subject: [PATCH 495/546] alsa: added card, channel to widget table --- widgets/alsa.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 5a4335e..7d25096 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -23,15 +23,16 @@ local alsa = {} local function worker(args) local args = args or {} - local card = args.card or "0" local timeout = args.timeout or 5 - local channel = args.channel or "Master" local settings = args.settings or function() end + alsa.card = args.card or "0" + alsa.channel = args.channel or "Master" + alsa.widget = wibox.widget.textbox('') function alsa.update() - local f = assert(io.popen(string.format("amixer -c %s -M get %s", card, channel))) + local f = assert(io.popen(string.format("amixer -c %s -M get %s", alsa.card, alsa.channel))) local mixer = f:read("*a") f:close() From 49221b80556abd4f0c6203fa0aafdd5436db03ce Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 25 Mar 2015 19:41:08 +0100 Subject: [PATCH 496/546] #103: revert to original fs implementation --- widgets/alsabar.lua | 2 +- widgets/fs.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index fa10bc2..b12e55c 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -27,7 +27,7 @@ local setmetatable = setmetatable local alsabar = { card = "0", channel = "Master", - step = "5%", + step = "2%", colors = { background = beautiful.bg_normal, diff --git a/widgets/fs.lua b/widgets/fs.lua index 3b99cba..8b51178 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -66,7 +66,7 @@ local function worker(args) function update() fs_info = {} fs_now = {} - local f = io.popen("LC_ALL=C df -kP " .. partition) + local f = assert(io.popen("LC_ALL=C df -kP")) for line in f:lines() do -- Match: (size) (used)(avail)(use%) (mount) local s = string.match(line, "^.-[%s]([%d]+)") From 12f2ec0817f25b8bb822ac1c3ffac0f989aee98c Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Sat, 28 Mar 2015 11:39:45 +0100 Subject: [PATCH 497/546] alsabar: string.format use for preset.text in alsabar._notify --- widgets/alsabar.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index b12e55c..d233b28 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -70,11 +70,9 @@ function alsabar.notify() preset.title = alsabar.channel .. " - " .. alsabar._current_level .. "%" end - int = math.modf((alsabar._current_level / 100) * alsabar.notifications.bar_size) - preset.text = "[" - .. string.rep("|", int) - .. string.rep(" ", alsabar.notifications.bar_size - int) - .. "]" + local int = math.modf((alsabar._current_level / 100) * alsabar.notifications.bar_size) + preset.text = string.format("[%s%s]", string.rep("|", int), + string.rep(" ", alsabar.notifications.bar_size - int)) if alsabar._notify ~= nil then alsabar._notify = naughty.notify ({ From 5e1f73369d067b5a7fcb4a6baaf782305ff291ae Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Sat, 28 Mar 2015 11:40:06 +0100 Subject: [PATCH 498/546] alsabar: string.format use for preset.text in alsabar._notify --- widgets/alsabar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index d233b28..b2cba9e 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -71,7 +71,7 @@ function alsabar.notify() end local int = math.modf((alsabar._current_level / 100) * alsabar.notifications.bar_size) - preset.text = string.format("[%s%s]", string.rep("|", int), + preset.text = string.format("[%s%s]", string.rep("|", int), string.rep(" ", alsabar.notifications.bar_size - int)) if alsabar._notify ~= nil then From e5b730dbf0408c6c1bda7d16aa02873815a79623 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 13 Apr 2015 11:38:44 +0200 Subject: [PATCH 499/546] yawn: fair/windy icon added --- widgets/yawn/icons/DayFairWindy.png | 1 + widgets/yawn/icons/NightFairWindy.png | 1 + 2 files changed, 2 insertions(+) create mode 120000 widgets/yawn/icons/DayFairWindy.png create mode 120000 widgets/yawn/icons/NightFairWindy.png diff --git a/widgets/yawn/icons/DayFairWindy.png b/widgets/yawn/icons/DayFairWindy.png new file mode 120000 index 0000000..8ee94d1 --- /dev/null +++ b/widgets/yawn/icons/DayFairWindy.png @@ -0,0 +1 @@ +DayClear.png \ No newline at end of file diff --git a/widgets/yawn/icons/NightFairWindy.png b/widgets/yawn/icons/NightFairWindy.png new file mode 120000 index 0000000..23df45a --- /dev/null +++ b/widgets/yawn/icons/NightFairWindy.png @@ -0,0 +1 @@ +NightClear.png \ No newline at end of file From 52c31db52e8ccbf99512c738b6c044784b99b94b Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Mon, 13 Apr 2015 11:49:13 +0200 Subject: [PATCH 500/546] yawn: fair/windy icon added --- widgets/yawn/init.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua index be3e614..1f6b0f4 100644 --- a/widgets/yawn/init.lua +++ b/widgets/yawn/init.lua @@ -102,10 +102,10 @@ function yawn.fetch_weather() local hour = tonumber(os.date("%H")) sky = icon_path - if forecast == "Clear" or - forecast == "Fair" or - forecast == "Partly Cloudy" or - forecast == "Mostly Cloudy" + if string.find(forecast, "Clear") or + string.find(forecast, "Fair") or + string.find(forecast, "Partly Cloudy") or + string.find(forecast, "Mostly Cloudy") then if hour >= 6 and hour <= 18 then From 312017f3699e61973cdcf87d577a8cc21a4c2dc6 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 19 May 2015 14:11:36 +0200 Subject: [PATCH 501/546] #109: catch n%0 --- layout/uselesstile.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index bd365a8..877fad1 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -179,6 +179,8 @@ local function tile(p, orientation) -- get column number for other windows local ncol = math.min(tag.getncol(t), #cls_other) + if ncol == 0 then ncol = 1 end + -- split other windows to column groups local last_small_column = ncol - #cls_other % ncol local rows_min = math.floor(#cls_other / ncol) From ea7b0dd6b131702ca92d30cd6b89114990686c55 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Sun, 17 May 2015 22:58:52 +0200 Subject: [PATCH 502/546] smapi: round remaining hour estimation --- widgets/contrib/tpbat/smapi.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/contrib/tpbat/smapi.lua b/widgets/contrib/tpbat/smapi.lua index 862d4cd..c7f093e 100644 --- a/widgets/contrib/tpbat/smapi.lua +++ b/widgets/contrib/tpbat/smapi.lua @@ -87,7 +87,7 @@ function smapi:battery(name) return "N/A" end - local hrs = mins_left / 60 + local hrs = math.floor(mins_left / 60) local min = mins_left % 60 return string.format("%02d:%02d", hrs, min) end From e79cd9c029d0aa88327e62573602aa4748006641 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Tue, 19 May 2015 15:41:33 +0200 Subject: [PATCH 503/546] net: removed 'tostring' for numbers --- widgets/mem.lua | 4 +--- widgets/net.lua | 5 ++--- widgets/sysload.lua | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/widgets/mem.lua b/widgets/mem.lua index 986fa76..46bb5f9 100644 --- a/widgets/mem.lua +++ b/widgets/mem.lua @@ -13,9 +13,7 @@ local wibox = require("wibox") local io = { lines = io.lines } local math = { floor = math.floor } -local string = { format = string.format, - gmatch = string.gmatch, - len = string.len } +local string = { gmatch = string.gmatch } local setmetatable = setmetatable diff --git a/widgets/net.lua b/widgets/net.lua index 2b06622..2585ad4 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -14,7 +14,6 @@ local naughty = require("naughty") local wibox = require("wibox") local io = { popen = io.popen } -local tostring = tostring local string = { format = string.format, gsub = string.gsub, match = string.match } @@ -71,10 +70,10 @@ local function worker(args) local now_r = helpers.first_line('/sys/class/net/' .. iface .. '/statistics/rx_bytes') or 0 - net_now.sent = tostring((now_t - net.last_t) / timeout / units) + net_now.sent = (now_t - net.last_t) / timeout / units net_now.sent = string.gsub(string.format('%.1f', net_now.sent), ",", ".") - net_now.received = tostring((now_r - net.last_r) / timeout / units) + net_now.received = (now_r - net.last_r) / timeout / units net_now.received = string.gsub(string.format('%.1f', net_now.received), ",", ".") widget = net.widget diff --git a/widgets/sysload.lua b/widgets/sysload.lua index b15b1bf..144ad0c 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -12,8 +12,7 @@ local newtimer = require("lain.helpers").newtimer local wibox = require("wibox") local io = { open = io.open } -local string = { format = string.format, - match = string.match } +local string = { match = string.match } local setmetatable = setmetatable From af516589ed883b2e2962b881287db9cdb086c371 Mon Sep 17 00:00:00 2001 From: Dmitry Nedbaylo Date: Sun, 31 May 2015 15:44:45 +0300 Subject: [PATCH 504/546] Calendar: added post calendar command for extra processing --- widgets/calendar.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index cbba676..cc0ebe7 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -37,7 +37,8 @@ function calendar:show(t_out, inc_offset, scr) local tims = t_out or 0 local f, c_text local today = tonumber(os.date('%d')) - local init_t = calendar.cal .. ' | sed -r -e "s/_\\x08//g" | sed -r -e "s/(^| )(' + local init_t = calendar.cal .. ' ' .. calendar.post_cal .. ' ' .. + ' | sed -r -e "s/_\\x08//g" | sed -r -e "s/(^| )(' calendar.offset = calendar.offset + offs @@ -76,7 +77,8 @@ function calendar:show(t_out, inc_offset, scr) calendar.notify_icon = nil - f = io.popen(calendar.cal .. ' ' .. month .. ' ' .. year) + f = io.popen(calendar.cal .. ' ' .. month .. ' ' .. year .. ' ' .. + calendar.post_cal) end c_text = " Date: Wed, 24 Jun 2015 14:05:37 +0200 Subject: [PATCH 506/546] wiki updated --- .gitmodules | 4 ++-- lain.wiki | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 160000 lain.wiki diff --git a/.gitmodules b/.gitmodules index 350c0f8..a66da18 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "wiki"] - path = wiki +[submodule "lain.wiki"] + path = lain.wiki url = https://github.com/copycat-killer/lain.wiki.git diff --git a/lain.wiki b/lain.wiki new file mode 160000 index 0000000..b011c03 --- /dev/null +++ b/lain.wiki @@ -0,0 +1 @@ +Subproject commit b011c0339e805ee1596d0b6778d6c497dab41109 From cc288d20a0abf9f8e03f951a8cfc13cb66cd215b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 24 Jun 2015 14:07:51 +0200 Subject: [PATCH 507/546] wiki submodule updated --- .gitmodules | 2 +- lain.wiki | 1 - wiki | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 160000 lain.wiki diff --git a/.gitmodules b/.gitmodules index a66da18..a50818f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "lain.wiki"] - path = lain.wiki + path = wiki url = https://github.com/copycat-killer/lain.wiki.git diff --git a/lain.wiki b/lain.wiki deleted file mode 160000 index b011c03..0000000 --- a/lain.wiki +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b011c0339e805ee1596d0b6778d6c497dab41109 diff --git a/wiki b/wiki index 54b3a71..b011c03 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 54b3a717b2f7069264ce5a20018ae4abf153e7b2 +Subproject commit b011c0339e805ee1596d0b6778d6c497dab41109 From beb196af2f0f19fd2869a45ae752243ac055d1ce Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 2 Jul 2015 12:06:07 +0200 Subject: [PATCH 508/546] better weather module: OpenWeatherMap; #105 --- asyncshell.lua | 4 +- .../openweathermap/01d.png | Bin .../openweathermap/01n.png | Bin .../openweathermap/02d.png | Bin .../openweathermap/02n.png | Bin .../openweathermap/03d.png | Bin .../openweathermap/03n.png | Bin .../openweathermap/04d.png | Bin icons/openweathermap/04n.png | 1 + .../Rain.png => icons/openweathermap/09d.png | Bin icons/openweathermap/09n.png | 1 + .../openweathermap/10d.png | Bin icons/openweathermap/10n.png | 1 + .../openweathermap/11d.png | Bin icons/openweathermap/11n.png | 1 + .../openweathermap/13d.png | Bin icons/openweathermap/13n.png | 1 + .../Foggy.png => icons/openweathermap/50d.png | Bin icons/openweathermap/50n.png | 1 + icons/openweathermap/README.md | 3 + .../icons => icons/openweathermap}/na.png | Bin util/dkjson.lua | 713 ++++++++++++++++++ widgets/contrib/ccurr.lua | 2 +- widgets/weather.lua | 125 +++ widgets/yawn/icons/BlowingSnow.png | Bin 11454 -> 0 bytes widgets/yawn/icons/DayFair.png | 1 - widgets/yawn/icons/DayFairWindy.png | 1 - widgets/yawn/icons/Drizzle.png | 1 - widgets/yawn/icons/Fog.png | 1 - widgets/yawn/icons/FreezingDrizzle.png | Bin 13166 -> 0 bytes widgets/yawn/icons/FreezingRain.png | Bin 13979 -> 0 bytes widgets/yawn/icons/Hail.png | Bin 7325 -> 0 bytes widgets/yawn/icons/Haze.png | 1 - widgets/yawn/icons/HeavyRain.png | 1 - widgets/yawn/icons/LightRain.png | 1 - widgets/yawn/icons/LightSnow.png | 1 - widgets/yawn/icons/LightSnowShowers.png | Bin 8779 -> 0 bytes widgets/yawn/icons/Mist.png | 1 - widgets/yawn/icons/MixedRainAndHail.png | Bin 9060 -> 0 bytes widgets/yawn/icons/MixedRainAndSleet.png | Bin 10978 -> 0 bytes widgets/yawn/icons/MixedRainAndSnow.png | Bin 10808 -> 0 bytes widgets/yawn/icons/NightFair.png | 1 - widgets/yawn/icons/NightFairWindy.png | 1 - widgets/yawn/icons/README.md | 6 - widgets/yawn/icons/Sleet.png | 1 - widgets/yawn/icons/Snow.png | 1 - widgets/yawn/icons/SnowFlurries.png | 1 - widgets/yawn/icons/SnowShowers.png | Bin 9961 -> 0 bytes widgets/yawn/icons/Sunny.png | Bin 14018 -> 0 bytes widgets/yawn/icons/ThunderintheVicinity.png | 1 - widgets/yawn/icons/Wind.png | Bin 8726 -> 0 bytes widgets/yawn/init.lua | 206 ----- widgets/yawn/localizations/de_DE | 61 -- widgets/yawn/localizations/fr_FR | 61 -- widgets/yawn/localizations/it_IT | 61 -- .../yawn/localizations/localization_template | 61 -- widgets/yawn/localizations/ru_RU | 61 -- widgets/yawn/localizations/zh_CN | 61 -- widgets/yawn/localizations/zh_TW | 61 -- wiki | 2 +- 60 files changed, 850 insertions(+), 659 deletions(-) rename widgets/yawn/icons/DayClear.png => icons/openweathermap/01d.png (100%) rename widgets/yawn/icons/NightClear.png => icons/openweathermap/01n.png (100%) rename widgets/yawn/icons/DayPartlyCloudy.png => icons/openweathermap/02d.png (100%) rename widgets/yawn/icons/NightPartlyCloudy.png => icons/openweathermap/02n.png (100%) rename widgets/yawn/icons/DayMostlyCloudy.png => icons/openweathermap/03d.png (100%) rename widgets/yawn/icons/NightMostlyCloudy.png => icons/openweathermap/03n.png (100%) rename widgets/yawn/icons/Cloudy.png => icons/openweathermap/04d.png (100%) create mode 120000 icons/openweathermap/04n.png rename widgets/yawn/icons/Rain.png => icons/openweathermap/09d.png (100%) create mode 120000 icons/openweathermap/09n.png rename widgets/yawn/icons/Showers.png => icons/openweathermap/10d.png (100%) create mode 120000 icons/openweathermap/10n.png rename widgets/yawn/icons/RainThunder.png => icons/openweathermap/11d.png (100%) create mode 120000 icons/openweathermap/11n.png rename widgets/yawn/icons/HeavySnow.png => icons/openweathermap/13d.png (100%) create mode 120000 icons/openweathermap/13n.png rename widgets/yawn/icons/Foggy.png => icons/openweathermap/50d.png (100%) create mode 120000 icons/openweathermap/50n.png create mode 100644 icons/openweathermap/README.md rename {widgets/yawn/icons => icons/openweathermap}/na.png (100%) create mode 100644 util/dkjson.lua create mode 100644 widgets/weather.lua delete mode 100755 widgets/yawn/icons/BlowingSnow.png delete mode 120000 widgets/yawn/icons/DayFair.png delete mode 120000 widgets/yawn/icons/DayFairWindy.png delete mode 120000 widgets/yawn/icons/Drizzle.png delete mode 120000 widgets/yawn/icons/Fog.png delete mode 100755 widgets/yawn/icons/FreezingDrizzle.png delete mode 100755 widgets/yawn/icons/FreezingRain.png delete mode 100755 widgets/yawn/icons/Hail.png delete mode 120000 widgets/yawn/icons/Haze.png delete mode 120000 widgets/yawn/icons/HeavyRain.png delete mode 120000 widgets/yawn/icons/LightRain.png delete mode 120000 widgets/yawn/icons/LightSnow.png delete mode 100755 widgets/yawn/icons/LightSnowShowers.png delete mode 120000 widgets/yawn/icons/Mist.png delete mode 100755 widgets/yawn/icons/MixedRainAndHail.png delete mode 100755 widgets/yawn/icons/MixedRainAndSleet.png delete mode 100755 widgets/yawn/icons/MixedRainAndSnow.png delete mode 120000 widgets/yawn/icons/NightFair.png delete mode 120000 widgets/yawn/icons/NightFairWindy.png delete mode 100644 widgets/yawn/icons/README.md delete mode 120000 widgets/yawn/icons/Sleet.png delete mode 120000 widgets/yawn/icons/Snow.png delete mode 120000 widgets/yawn/icons/SnowFlurries.png delete mode 100755 widgets/yawn/icons/SnowShowers.png delete mode 100755 widgets/yawn/icons/Sunny.png delete mode 120000 widgets/yawn/icons/ThunderintheVicinity.png delete mode 100755 widgets/yawn/icons/Wind.png delete mode 100644 widgets/yawn/init.lua delete mode 100644 widgets/yawn/localizations/de_DE delete mode 100644 widgets/yawn/localizations/fr_FR delete mode 100644 widgets/yawn/localizations/it_IT delete mode 100644 widgets/yawn/localizations/localization_template delete mode 100644 widgets/yawn/localizations/ru_RU delete mode 100644 widgets/yawn/localizations/zh_CN delete mode 100644 widgets/yawn/localizations/zh_TW diff --git a/asyncshell.lua b/asyncshell.lua index 36ccc47..0aafa17 100644 --- a/asyncshell.lua +++ b/asyncshell.lua @@ -10,11 +10,9 @@ -- How to use... -- ...asynchronously: -- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end) --- ...synchronously +-- ...synchronously: -- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error") --- This is more cpu demanding, but makes things faster. - local spawn = require('awful.util').spawn asyncshell = {} diff --git a/widgets/yawn/icons/DayClear.png b/icons/openweathermap/01d.png similarity index 100% rename from widgets/yawn/icons/DayClear.png rename to icons/openweathermap/01d.png diff --git a/widgets/yawn/icons/NightClear.png b/icons/openweathermap/01n.png similarity index 100% rename from widgets/yawn/icons/NightClear.png rename to icons/openweathermap/01n.png diff --git a/widgets/yawn/icons/DayPartlyCloudy.png b/icons/openweathermap/02d.png similarity index 100% rename from widgets/yawn/icons/DayPartlyCloudy.png rename to icons/openweathermap/02d.png diff --git a/widgets/yawn/icons/NightPartlyCloudy.png b/icons/openweathermap/02n.png similarity index 100% rename from widgets/yawn/icons/NightPartlyCloudy.png rename to icons/openweathermap/02n.png diff --git a/widgets/yawn/icons/DayMostlyCloudy.png b/icons/openweathermap/03d.png similarity index 100% rename from widgets/yawn/icons/DayMostlyCloudy.png rename to icons/openweathermap/03d.png diff --git a/widgets/yawn/icons/NightMostlyCloudy.png b/icons/openweathermap/03n.png similarity index 100% rename from widgets/yawn/icons/NightMostlyCloudy.png rename to icons/openweathermap/03n.png diff --git a/widgets/yawn/icons/Cloudy.png b/icons/openweathermap/04d.png similarity index 100% rename from widgets/yawn/icons/Cloudy.png rename to icons/openweathermap/04d.png diff --git a/icons/openweathermap/04n.png b/icons/openweathermap/04n.png new file mode 120000 index 0000000..b9a83df --- /dev/null +++ b/icons/openweathermap/04n.png @@ -0,0 +1 @@ +04d.png \ No newline at end of file diff --git a/widgets/yawn/icons/Rain.png b/icons/openweathermap/09d.png similarity index 100% rename from widgets/yawn/icons/Rain.png rename to icons/openweathermap/09d.png diff --git a/icons/openweathermap/09n.png b/icons/openweathermap/09n.png new file mode 120000 index 0000000..cca1f5d --- /dev/null +++ b/icons/openweathermap/09n.png @@ -0,0 +1 @@ +09d.png \ No newline at end of file diff --git a/widgets/yawn/icons/Showers.png b/icons/openweathermap/10d.png similarity index 100% rename from widgets/yawn/icons/Showers.png rename to icons/openweathermap/10d.png diff --git a/icons/openweathermap/10n.png b/icons/openweathermap/10n.png new file mode 120000 index 0000000..6e01227 --- /dev/null +++ b/icons/openweathermap/10n.png @@ -0,0 +1 @@ +10d.png \ No newline at end of file diff --git a/widgets/yawn/icons/RainThunder.png b/icons/openweathermap/11d.png similarity index 100% rename from widgets/yawn/icons/RainThunder.png rename to icons/openweathermap/11d.png diff --git a/icons/openweathermap/11n.png b/icons/openweathermap/11n.png new file mode 120000 index 0000000..b227917 --- /dev/null +++ b/icons/openweathermap/11n.png @@ -0,0 +1 @@ +11d.png \ No newline at end of file diff --git a/widgets/yawn/icons/HeavySnow.png b/icons/openweathermap/13d.png similarity index 100% rename from widgets/yawn/icons/HeavySnow.png rename to icons/openweathermap/13d.png diff --git a/icons/openweathermap/13n.png b/icons/openweathermap/13n.png new file mode 120000 index 0000000..94e5a52 --- /dev/null +++ b/icons/openweathermap/13n.png @@ -0,0 +1 @@ +13d.png \ No newline at end of file diff --git a/widgets/yawn/icons/Foggy.png b/icons/openweathermap/50d.png similarity index 100% rename from widgets/yawn/icons/Foggy.png rename to icons/openweathermap/50d.png diff --git a/icons/openweathermap/50n.png b/icons/openweathermap/50n.png new file mode 120000 index 0000000..e3ba961 --- /dev/null +++ b/icons/openweathermap/50n.png @@ -0,0 +1 @@ +50d.png \ No newline at end of file diff --git a/icons/openweathermap/README.md b/icons/openweathermap/README.md new file mode 100644 index 0000000..f908fbd --- /dev/null +++ b/icons/openweathermap/README.md @@ -0,0 +1,3 @@ +[Plain Weather Icons](http://merlinthered.deviantart.com/art/plain-weather-icons-157162192), created by [MerlinTheRed](http://merlinthered.deviantart.com/). + + diff --git a/widgets/yawn/icons/na.png b/icons/openweathermap/na.png similarity index 100% rename from widgets/yawn/icons/na.png rename to icons/openweathermap/na.png diff --git a/util/dkjson.lua b/util/dkjson.lua new file mode 100644 index 0000000..89aa2e1 --- /dev/null +++ b/util/dkjson.lua @@ -0,0 +1,713 @@ +-- Module options: +local always_try_using_lpeg = true +local register_global_module_table = false +local global_module_name = 'json' + +--[==[ + +David Kolf's JSON module for Lua 5.1/5.2 + +Version 2.5 + + +For the documentation see the corresponding readme.txt or visit +. + +You can contact the author by sending an e-mail to 'david' at the +domain 'dkolf.de'. + + +Copyright (C) 2010-2013 David Heiko Kolf + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--]==] + +-- global dependencies: +local pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset = + pairs, type, tostring, tonumber, getmetatable, setmetatable, rawset +local error, require, pcall, select = error, require, pcall, select +local floor, huge = math.floor, math.huge +local strrep, gsub, strsub, strbyte, strchar, strfind, strlen, strformat = + string.rep, string.gsub, string.sub, string.byte, string.char, + string.find, string.len, string.format +local strmatch = string.match +local concat = table.concat + +local json = { version = "dkjson 2.5" } + +if register_global_module_table then + _G[global_module_name] = json +end + +local _ENV = nil -- blocking globals in Lua 5.2 + +pcall (function() + -- Enable access to blocked metatables. + -- Don't worry, this module doesn't change anything in them. + local debmeta = require "debug".getmetatable + if debmeta then getmetatable = debmeta end +end) + +json.null = setmetatable ({}, { + __tojson = function () return "null" end +}) + +local function isarray (tbl) + local max, n, arraylen = 0, 0, 0 + for k,v in pairs (tbl) do + if k == 'n' and type(v) == 'number' then + arraylen = v + if v > max then + max = v + end + else + if type(k) ~= 'number' or k < 1 or floor(k) ~= k then + return false + end + if k > max then + max = k + end + n = n + 1 + end + end + if max > 10 and max > arraylen and max > n * 2 then + return false -- don't create an array with too many holes + end + return true, max +end + +local escapecodes = { + ["\""] = "\\\"", ["\\"] = "\\\\", ["\b"] = "\\b", ["\f"] = "\\f", + ["\n"] = "\\n", ["\r"] = "\\r", ["\t"] = "\\t" +} + +local function escapeutf8 (uchar) + local value = escapecodes[uchar] + if value then + return value + end + local a, b, c, d = strbyte (uchar, 1, 4) + a, b, c, d = a or 0, b or 0, c or 0, d or 0 + if a <= 0x7f then + value = a + elseif 0xc0 <= a and a <= 0xdf and b >= 0x80 then + value = (a - 0xc0) * 0x40 + b - 0x80 + elseif 0xe0 <= a and a <= 0xef and b >= 0x80 and c >= 0x80 then + value = ((a - 0xe0) * 0x40 + b - 0x80) * 0x40 + c - 0x80 + elseif 0xf0 <= a and a <= 0xf7 and b >= 0x80 and c >= 0x80 and d >= 0x80 then + value = (((a - 0xf0) * 0x40 + b - 0x80) * 0x40 + c - 0x80) * 0x40 + d - 0x80 + else + return "" + end + if value <= 0xffff then + return strformat ("\\u%.4x", value) + elseif value <= 0x10ffff then + -- encode as UTF-16 surrogate pair + value = value - 0x10000 + local highsur, lowsur = 0xD800 + floor (value/0x400), 0xDC00 + (value % 0x400) + return strformat ("\\u%.4x\\u%.4x", highsur, lowsur) + else + return "" + end +end + +local function fsub (str, pattern, repl) + -- gsub always builds a new string in a buffer, even when no match + -- exists. First using find should be more efficient when most strings + -- don't contain the pattern. + if strfind (str, pattern) then + return gsub (str, pattern, repl) + else + return str + end +end + +local function quotestring (value) + -- based on the regexp "escapable" in https://github.com/douglascrockford/JSON-js + value = fsub (value, "[%z\1-\31\"\\\127]", escapeutf8) + if strfind (value, "[\194\216\220\225\226\239]") then + value = fsub (value, "\194[\128-\159\173]", escapeutf8) + value = fsub (value, "\216[\128-\132]", escapeutf8) + value = fsub (value, "\220\143", escapeutf8) + value = fsub (value, "\225\158[\180\181]", escapeutf8) + value = fsub (value, "\226\128[\140-\143\168-\175]", escapeutf8) + value = fsub (value, "\226\129[\160-\175]", escapeutf8) + value = fsub (value, "\239\187\191", escapeutf8) + value = fsub (value, "\239\191[\176-\191]", escapeutf8) + end + return "\"" .. value .. "\"" +end +json.quotestring = quotestring + +local function replace(str, o, n) + local i, j = strfind (str, o, 1, true) + if i then + return strsub(str, 1, i-1) .. n .. strsub(str, j+1, -1) + else + return str + end +end + +-- locale independent num2str and str2num functions +local decpoint, numfilter + +local function updatedecpoint () + decpoint = strmatch(tostring(0.5), "([^05+])") + -- build a filter that can be used to remove group separators + numfilter = "[^0-9%-%+eE" .. gsub(decpoint, "[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0") .. "]+" +end + +updatedecpoint() + +local function num2str (num) + return replace(fsub(tostring(num), numfilter, ""), decpoint, ".") +end + +local function str2num (str) + local num = tonumber(replace(str, ".", decpoint)) + if not num then + updatedecpoint() + num = tonumber(replace(str, ".", decpoint)) + end + return num +end + +local function addnewline2 (level, buffer, buflen) + buffer[buflen+1] = "\n" + buffer[buflen+2] = strrep (" ", level) + buflen = buflen + 2 + return buflen +end + +function json.addnewline (state) + if state.indent then + state.bufferlen = addnewline2 (state.level or 0, + state.buffer, state.bufferlen or #(state.buffer)) + end +end + +local encode2 -- forward declaration + +local function addpair (key, value, prev, indent, level, buffer, buflen, tables, globalorder, state) + local kt = type (key) + if kt ~= 'string' and kt ~= 'number' then + return nil, "type '" .. kt .. "' is not supported as a key by JSON." + end + if prev then + buflen = buflen + 1 + buffer[buflen] = "," + end + if indent then + buflen = addnewline2 (level, buffer, buflen) + end + buffer[buflen+1] = quotestring (key) + buffer[buflen+2] = ":" + return encode2 (value, indent, level, buffer, buflen + 2, tables, globalorder, state) +end + +local function appendcustom(res, buffer, state) + local buflen = state.bufferlen + if type (res) == 'string' then + buflen = buflen + 1 + buffer[buflen] = res + end + return buflen +end + +local function exception(reason, value, state, buffer, buflen, defaultmessage) + defaultmessage = defaultmessage or reason + local handler = state.exception + if not handler then + return nil, defaultmessage + else + state.bufferlen = buflen + local ret, msg = handler (reason, value, state, defaultmessage) + if not ret then return nil, msg or defaultmessage end + return appendcustom(ret, buffer, state) + end +end + +function json.encodeexception(reason, value, state, defaultmessage) + return quotestring("<" .. defaultmessage .. ">") +end + +encode2 = function (value, indent, level, buffer, buflen, tables, globalorder, state) + local valtype = type (value) + local valmeta = getmetatable (value) + valmeta = type (valmeta) == 'table' and valmeta -- only tables + local valtojson = valmeta and valmeta.__tojson + if valtojson then + if tables[value] then + return exception('reference cycle', value, state, buffer, buflen) + end + tables[value] = true + state.bufferlen = buflen + local ret, msg = valtojson (value, state) + if not ret then return exception('custom encoder failed', value, state, buffer, buflen, msg) end + tables[value] = nil + buflen = appendcustom(ret, buffer, state) + elseif value == nil then + buflen = buflen + 1 + buffer[buflen] = "null" + elseif valtype == 'number' then + local s + if value ~= value or value >= huge or -value >= huge then + -- This is the behaviour of the original JSON implementation. + s = "null" + else + s = num2str (value) + end + buflen = buflen + 1 + buffer[buflen] = s + elseif valtype == 'boolean' then + buflen = buflen + 1 + buffer[buflen] = value and "true" or "false" + elseif valtype == 'string' then + buflen = buflen + 1 + buffer[buflen] = quotestring (value) + elseif valtype == 'table' then + if tables[value] then + return exception('reference cycle', value, state, buffer, buflen) + end + tables[value] = true + level = level + 1 + local isa, n = isarray (value) + if n == 0 and valmeta and valmeta.__jsontype == 'object' then + isa = false + end + local msg + if isa then -- JSON array + buflen = buflen + 1 + buffer[buflen] = "[" + for i = 1, n do + buflen, msg = encode2 (value[i], indent, level, buffer, buflen, tables, globalorder, state) + if not buflen then return nil, msg end + if i < n then + buflen = buflen + 1 + buffer[buflen] = "," + end + end + buflen = buflen + 1 + buffer[buflen] = "]" + else -- JSON object + local prev = false + buflen = buflen + 1 + buffer[buflen] = "{" + local order = valmeta and valmeta.__jsonorder or globalorder + if order then + local used = {} + n = #order + for i = 1, n do + local k = order[i] + local v = value[k] + if v then + used[k] = true + buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) + prev = true -- add a seperator before the next element + end + end + for k,v in pairs (value) do + if not used[k] then + buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) + if not buflen then return nil, msg end + prev = true -- add a seperator before the next element + end + end + else -- unordered + for k,v in pairs (value) do + buflen, msg = addpair (k, v, prev, indent, level, buffer, buflen, tables, globalorder, state) + if not buflen then return nil, msg end + prev = true -- add a seperator before the next element + end + end + if indent then + buflen = addnewline2 (level - 1, buffer, buflen) + end + buflen = buflen + 1 + buffer[buflen] = "}" + end + tables[value] = nil + else + return exception ('unsupported type', value, state, buffer, buflen, + "type '" .. valtype .. "' is not supported by JSON.") + end + return buflen +end + +function json.encode (value, state) + state = state or {} + local oldbuffer = state.buffer + local buffer = oldbuffer or {} + state.buffer = buffer + updatedecpoint() + local ret, msg = encode2 (value, state.indent, state.level or 0, + buffer, state.bufferlen or 0, state.tables or {}, state.keyorder, state) + if not ret then + error (msg, 2) + elseif oldbuffer == buffer then + state.bufferlen = ret + return true + else + state.bufferlen = nil + state.buffer = nil + return concat (buffer) + end +end + +local function loc (str, where) + local line, pos, linepos = 1, 1, 0 + while true do + pos = strfind (str, "\n", pos, true) + if pos and pos < where then + line = line + 1 + linepos = pos + pos = pos + 1 + else + break + end + end + return "line " .. line .. ", column " .. (where - linepos) +end + +local function unterminated (str, what, where) + return nil, strlen (str) + 1, "unterminated " .. what .. " at " .. loc (str, where) +end + +local function scanwhite (str, pos) + while true do + pos = strfind (str, "%S", pos) + if not pos then return nil end + local sub2 = strsub (str, pos, pos + 1) + if sub2 == "\239\187" and strsub (str, pos + 2, pos + 2) == "\191" then + -- UTF-8 Byte Order Mark + pos = pos + 3 + elseif sub2 == "//" then + pos = strfind (str, "[\n\r]", pos + 2) + if not pos then return nil end + elseif sub2 == "/*" then + pos = strfind (str, "*/", pos + 2) + if not pos then return nil end + pos = pos + 2 + else + return pos + end + end +end + +local escapechars = { + ["\""] = "\"", ["\\"] = "\\", ["/"] = "/", ["b"] = "\b", ["f"] = "\f", + ["n"] = "\n", ["r"] = "\r", ["t"] = "\t" +} + +local function unichar (value) + if value < 0 then + return nil + elseif value <= 0x007f then + return strchar (value) + elseif value <= 0x07ff then + return strchar (0xc0 + floor(value/0x40), + 0x80 + (floor(value) % 0x40)) + elseif value <= 0xffff then + return strchar (0xe0 + floor(value/0x1000), + 0x80 + (floor(value/0x40) % 0x40), + 0x80 + (floor(value) % 0x40)) + elseif value <= 0x10ffff then + return strchar (0xf0 + floor(value/0x40000), + 0x80 + (floor(value/0x1000) % 0x40), + 0x80 + (floor(value/0x40) % 0x40), + 0x80 + (floor(value) % 0x40)) + else + return nil + end +end + +local function scanstring (str, pos) + local lastpos = pos + 1 + local buffer, n = {}, 0 + while true do + local nextpos = strfind (str, "[\"\\]", lastpos) + if not nextpos then + return unterminated (str, "string", pos) + end + if nextpos > lastpos then + n = n + 1 + buffer[n] = strsub (str, lastpos, nextpos - 1) + end + if strsub (str, nextpos, nextpos) == "\"" then + lastpos = nextpos + 1 + break + else + local escchar = strsub (str, nextpos + 1, nextpos + 1) + local value + if escchar == "u" then + value = tonumber (strsub (str, nextpos + 2, nextpos + 5), 16) + if value then + local value2 + if 0xD800 <= value and value <= 0xDBff then + -- we have the high surrogate of UTF-16. Check if there is a + -- low surrogate escaped nearby to combine them. + if strsub (str, nextpos + 6, nextpos + 7) == "\\u" then + value2 = tonumber (strsub (str, nextpos + 8, nextpos + 11), 16) + if value2 and 0xDC00 <= value2 and value2 <= 0xDFFF then + value = (value - 0xD800) * 0x400 + (value2 - 0xDC00) + 0x10000 + else + value2 = nil -- in case it was out of range for a low surrogate + end + end + end + value = value and unichar (value) + if value then + if value2 then + lastpos = nextpos + 12 + else + lastpos = nextpos + 6 + end + end + end + end + if not value then + value = escapechars[escchar] or escchar + lastpos = nextpos + 2 + end + n = n + 1 + buffer[n] = value + end + end + if n == 1 then + return buffer[1], lastpos + elseif n > 1 then + return concat (buffer), lastpos + else + return "", lastpos + end +end + +local scanvalue -- forward declaration + +local function scantable (what, closechar, str, startpos, nullval, objectmeta, arraymeta) + local len = strlen (str) + local tbl, n = {}, 0 + local pos = startpos + 1 + if what == 'object' then + setmetatable (tbl, objectmeta) + else + setmetatable (tbl, arraymeta) + end + while true do + pos = scanwhite (str, pos) + if not pos then return unterminated (str, what, startpos) end + local char = strsub (str, pos, pos) + if char == closechar then + return tbl, pos + 1 + end + local val1, err + val1, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta) + if err then return nil, pos, err end + pos = scanwhite (str, pos) + if not pos then return unterminated (str, what, startpos) end + char = strsub (str, pos, pos) + if char == ":" then + if val1 == nil then + return nil, pos, "cannot use nil as table index (at " .. loc (str, pos) .. ")" + end + pos = scanwhite (str, pos + 1) + if not pos then return unterminated (str, what, startpos) end + local val2 + val2, pos, err = scanvalue (str, pos, nullval, objectmeta, arraymeta) + if err then return nil, pos, err end + tbl[val1] = val2 + pos = scanwhite (str, pos) + if not pos then return unterminated (str, what, startpos) end + char = strsub (str, pos, pos) + else + n = n + 1 + tbl[n] = val1 + end + if char == "," then + pos = pos + 1 + end + end +end + +scanvalue = function (str, pos, nullval, objectmeta, arraymeta) + pos = pos or 1 + pos = scanwhite (str, pos) + if not pos then + return nil, strlen (str) + 1, "no valid JSON value (reached the end)" + end + local char = strsub (str, pos, pos) + if char == "{" then + return scantable ('object', "}", str, pos, nullval, objectmeta, arraymeta) + elseif char == "[" then + return scantable ('array', "]", str, pos, nullval, objectmeta, arraymeta) + elseif char == "\"" then + return scanstring (str, pos) + else + local pstart, pend = strfind (str, "^%-?[%d%.]+[eE]?[%+%-]?%d*", pos) + if pstart then + local number = str2num (strsub (str, pstart, pend)) + if number then + return number, pend + 1 + end + end + pstart, pend = strfind (str, "^%a%w*", pos) + if pstart then + local name = strsub (str, pstart, pend) + if name == "true" then + return true, pend + 1 + elseif name == "false" then + return false, pend + 1 + elseif name == "null" then + return nullval, pend + 1 + end + end + return nil, pos, "no valid JSON value at " .. loc (str, pos) + end +end + +local function optionalmetatables(...) + if select("#", ...) > 0 then + return ... + else + return {__jsontype = 'object'}, {__jsontype = 'array'} + end +end + +function json.decode (str, pos, nullval, ...) + local objectmeta, arraymeta = optionalmetatables(...) + return scanvalue (str, pos, nullval, objectmeta, arraymeta) +end + +function json.use_lpeg () + local g = require ("lpeg") + + if g.version() == "0.11" then + error "due to a bug in LPeg 0.11, it cannot be used for JSON matching" + end + + local pegmatch = g.match + local P, S, R = g.P, g.S, g.R + + local function ErrorCall (str, pos, msg, state) + if not state.msg then + state.msg = msg .. " at " .. loc (str, pos) + state.pos = pos + end + return false + end + + local function Err (msg) + return g.Cmt (g.Cc (msg) * g.Carg (2), ErrorCall) + end + + local SingleLineComment = P"//" * (1 - S"\n\r")^0 + local MultiLineComment = P"/*" * (1 - P"*/")^0 * P"*/" + local Space = (S" \n\r\t" + P"\239\187\191" + SingleLineComment + MultiLineComment)^0 + + local PlainChar = 1 - S"\"\\\n\r" + local EscapeSequence = (P"\\" * g.C (S"\"\\/bfnrt" + Err "unsupported escape sequence")) / escapechars + local HexDigit = R("09", "af", "AF") + local function UTF16Surrogate (match, pos, high, low) + high, low = tonumber (high, 16), tonumber (low, 16) + if 0xD800 <= high and high <= 0xDBff and 0xDC00 <= low and low <= 0xDFFF then + return true, unichar ((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000) + else + return false + end + end + local function UTF16BMP (hex) + return unichar (tonumber (hex, 16)) + end + local U16Sequence = (P"\\u" * g.C (HexDigit * HexDigit * HexDigit * HexDigit)) + local UnicodeEscape = g.Cmt (U16Sequence * U16Sequence, UTF16Surrogate) + U16Sequence/UTF16BMP + local Char = UnicodeEscape + EscapeSequence + PlainChar + local String = P"\"" * g.Cs (Char ^ 0) * (P"\"" + Err "unterminated string") + local Integer = P"-"^(-1) * (P"0" + (R"19" * R"09"^0)) + local Fractal = P"." * R"09"^0 + local Exponent = (S"eE") * (S"+-")^(-1) * R"09"^1 + local Number = (Integer * Fractal^(-1) * Exponent^(-1))/str2num + local Constant = P"true" * g.Cc (true) + P"false" * g.Cc (false) + P"null" * g.Carg (1) + local SimpleValue = Number + String + Constant + local ArrayContent, ObjectContent + + -- The functions parsearray and parseobject parse only a single value/pair + -- at a time and store them directly to avoid hitting the LPeg limits. + local function parsearray (str, pos, nullval, state) + local obj, cont + local npos + local t, nt = {}, 0 + repeat + obj, cont, npos = pegmatch (ArrayContent, str, pos, nullval, state) + if not npos then break end + pos = npos + nt = nt + 1 + t[nt] = obj + until cont == 'last' + return pos, setmetatable (t, state.arraymeta) + end + + local function parseobject (str, pos, nullval, state) + local obj, key, cont + local npos + local t = {} + repeat + key, obj, cont, npos = pegmatch (ObjectContent, str, pos, nullval, state) + if not npos then break end + pos = npos + t[key] = obj + until cont == 'last' + return pos, setmetatable (t, state.objectmeta) + end + + local Array = P"[" * g.Cmt (g.Carg(1) * g.Carg(2), parsearray) * Space * (P"]" + Err "']' expected") + local Object = P"{" * g.Cmt (g.Carg(1) * g.Carg(2), parseobject) * Space * (P"}" + Err "'}' expected") + local Value = Space * (Array + Object + SimpleValue) + local ExpectedValue = Value + Space * Err "value expected" + ArrayContent = Value * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp() + local Pair = g.Cg (Space * String * Space * (P":" + Err "colon expected") * ExpectedValue) + ObjectContent = Pair * Space * (P"," * g.Cc'cont' + g.Cc'last') * g.Cp() + local DecodeValue = ExpectedValue * g.Cp () + + function json.decode (str, pos, nullval, ...) + local state = {} + state.objectmeta, state.arraymeta = optionalmetatables(...) + local obj, retpos = pegmatch (DecodeValue, str, pos, nullval, state) + if state.msg then + return nil, state.pos, state.msg + else + return obj, retpos + end + end + + -- use this function only once: + json.use_lpeg = function () return json end + + json.using_lpeg = true + + return json -- so you can get the module using json = require "dkjson".use_lpeg() +end + +if always_try_using_lpeg then + pcall (json.use_lpeg) +end + +return json diff --git a/widgets/contrib/ccurr.lua b/widgets/contrib/ccurr.lua index f696a35..980e19b 100644 --- a/widgets/contrib/ccurr.lua +++ b/widgets/contrib/ccurr.lua @@ -7,9 +7,9 @@ --]] local newtimer = require("lain.helpers").newtimer +local json = require("lain.util").dkjson local wibox = require("wibox") -local json = require("dkjson") local string = { format = string.format } local tonumber = tonumber diff --git a/widgets/weather.lua b/widgets/weather.lua new file mode 100644 index 0000000..d8dfd3f --- /dev/null +++ b/widgets/weather.lua @@ -0,0 +1,125 @@ + +--[[ + + Licensed under GNU General Public License v2 + * (c) 2015, Luke Bonham + +--]] + +local newtimer = require("lain.helpers").newtimer +local async = require("lain.asyncshell") +local json = require("lain.util").dkjson +local lain_icons = require("lain.helpers").icons_dir +local naughty = require("naughty") +local wibox = require("wibox") + +local math = { floor = math.floor } +local string = { format = string.format, + gsub = string.gsub } + +local setmetatable = setmetatable + +-- OpenWeatherMap +-- current weather and X-days forecast +-- lain.widgets.weather + +local function worker(args) + local weather = {} + local args = args or {} + local timeout = args.timeout or 900 -- 15 min + local timeout_forecast = args.timeout or 86400 -- 24 hrs + local current_call = "curl -s 'http://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s'" + local forecast_call = "curl -s 'http://api.openweathermap.org/data/2.5/forecast/daily?id=%s&units=%s&lang=%s&cnt=%s'" + local city_id = args.city_id + local units = args.units or "metric" + local lang = args.lang or "en" + local cnt = args.cnt or 7 + local date_cmd = args.date_cmd or "date -u -d @%d +'%%a %%d'" + local icons_path = args.icons_path or lain_icons .. "openweathermap/" + local w_notification_preset = args.w_notification_preset or {} + local settings = args.settings or function() end + + weather.widget = wibox.widget.textbox('') + weather.icon = wibox.widget.imagebox() + + function weather.show(t_out) + weather.hide() + weather.notification = naughty.notify({ + text = weather.notification_text, + icon = weather.icon_path, + timeout = t_out, + preset = w_notification_preset + }) + end + + function weather.hide() + if weather.notification ~= nil then + naughty.destroy(weather.notification) + weather.notification = nil + end + end + + function weather.attach(obj) + obj:connect_signal("mouse::enter", function() + weather.show(0) + end) + obj:connect_signal("mouse::leave", function() + weather.hide() + end) + end + + function weather.forecast_update() + local cmd = string.format(forecast_call, city_id, units, lang, cnt) + async.request(cmd, function(f) + j = f:read("*a") + f:close() + weather_now, pos, err = json.decode(j, 1, nil) + + if tonumber(weather_now["cod"]) == 200 then + weather.notification_text = '' + for i = 1, weather_now["cnt"] do + local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"]))) + day = string.gsub(f:read("a"), "\n", "") + f:close() + + tmin = math.floor(weather_now["list"][i]["temp"]["min"]) + tmax = math.floor(weather_now["list"][i]["temp"]["max"]) + desc = weather_now["list"][i]["weather"][1]["description"] + + weather.notification_text = weather.notification_text .. + string.format("%s: %s, %d - %d ", day, desc, tmin, tmax) + + if i < weather_now["cnt"] then + weather.notification_text = weather.notification_text .. "\n" + end + end + end + end) + end + + function weather.update() + local cmd = string.format(current_call, city_id, units, lang) + async.request(cmd, function(f) + j = f:read("*a") + f:close() + weather_now, pos, err = json.decode(j, 1, nil) + + if err then + weather.widget.set_text("N/A") + weather.icon:set_image(icons_path .. "na.png") + elseif tonumber(weather_now["cod"]) == 200 then + weather.icon_path = icons_path .. weather_now["weather"][1]["icon"] .. ".png" + weather.icon:set_image(weather.icon_path) + widget = weather.widget + settings() + end + end) + end + + newtimer("weather", timeout, weather.update) + newtimer("weather_forecast", timeout, weather.forecast_update) + + return setmetatable(weather, { __index = weather.widget }) +end + +return setmetatable({}, { __call = function(_, ...) return worker(...) end }) diff --git a/widgets/yawn/icons/BlowingSnow.png b/widgets/yawn/icons/BlowingSnow.png deleted file mode 100755 index 6223f8f7d2c1be89dbb216537dbfe0e97e4edd28..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11454 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 diff --git a/widgets/yawn/icons/DayFair.png b/widgets/yawn/icons/DayFair.png deleted file mode 120000 index 8ee94d1..0000000 --- a/widgets/yawn/icons/DayFair.png +++ /dev/null @@ -1 +0,0 @@ -DayClear.png \ No newline at end of file diff --git a/widgets/yawn/icons/DayFairWindy.png b/widgets/yawn/icons/DayFairWindy.png deleted file mode 120000 index 8ee94d1..0000000 --- a/widgets/yawn/icons/DayFairWindy.png +++ /dev/null @@ -1 +0,0 @@ -DayClear.png \ No newline at end of file diff --git a/widgets/yawn/icons/Drizzle.png b/widgets/yawn/icons/Drizzle.png deleted file mode 120000 index df34463..0000000 --- a/widgets/yawn/icons/Drizzle.png +++ /dev/null @@ -1 +0,0 @@ -Rain.png \ No newline at end of file diff --git a/widgets/yawn/icons/Fog.png b/widgets/yawn/icons/Fog.png deleted file mode 120000 index b615645..0000000 --- a/widgets/yawn/icons/Fog.png +++ /dev/null @@ -1 +0,0 @@ -Foggy.png \ No newline at end of file diff --git a/widgets/yawn/icons/FreezingDrizzle.png b/widgets/yawn/icons/FreezingDrizzle.png deleted file mode 100755 index 6a661408b9638977477cb5ba28c918f4e9e766c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13166 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
  • S236D+`KjrhMq5Ij+iT7#d>q&))}ssJ4g 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 SkrO_Njs%wG47yPXH|NC%vv9yM4-Q193JUov7 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 diff --git a/widgets/yawn/icons/Mist.png b/widgets/yawn/icons/Mist.png deleted file mode 120000 index b615645..0000000 --- a/widgets/yawn/icons/Mist.png +++ /dev/null @@ -1 +0,0 @@ -Foggy.png \ No newline at end of file diff --git a/widgets/yawn/icons/MixedRainAndHail.png b/widgets/yawn/icons/MixedRainAndHail.png deleted file mode 100755 index 758b01e48eaa6ad27d8b0d692e285a92e90a4ee1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9060 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 F{s-1-Kk5Jg diff --git a/widgets/yawn/icons/MixedRainAndSleet.png b/widgets/yawn/icons/MixedRainAndSleet.png deleted file mode 100755 index 7f0d252565ba1e256fc4fb281eab2ba2fbd1be12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10978 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 IvXbTf?`dGNzKt4V`T=vcm9#$5vHe4?5 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 b@c`k>S|VAx$A*JPDIsNfb-5}T^U(hTcXN<$ diff --git a/widgets/yawn/icons/NightFair.png b/widgets/yawn/icons/NightFair.png deleted file mode 120000 index 23df45a..0000000 --- a/widgets/yawn/icons/NightFair.png +++ /dev/null @@ -1 +0,0 @@ -NightClear.png \ No newline at end of file diff --git a/widgets/yawn/icons/NightFairWindy.png b/widgets/yawn/icons/NightFairWindy.png deleted file mode 120000 index 23df45a..0000000 --- a/widgets/yawn/icons/NightFairWindy.png +++ /dev/null @@ -1 +0,0 @@ -NightClear.png \ No newline at end of file diff --git a/widgets/yawn/icons/README.md b/widgets/yawn/icons/README.md deleted file mode 100644 index e4dc111..0000000 --- a/widgets/yawn/icons/README.md +++ /dev/null @@ -1,6 +0,0 @@ -Yawn icons -========== - -These are [Plain Weather Icons](http://merlinthered.deviantart.com/art/plain-weather-icons-157162192), created by [MerlinTheRed](http://merlinthered.deviantart.com/). - - diff --git a/widgets/yawn/icons/Sleet.png b/widgets/yawn/icons/Sleet.png deleted file mode 120000 index f8f9693..0000000 --- a/widgets/yawn/icons/Sleet.png +++ /dev/null @@ -1 +0,0 @@ -SnowShowers.png \ No newline at end of file diff --git a/widgets/yawn/icons/Snow.png b/widgets/yawn/icons/Snow.png deleted file mode 120000 index f8f9693..0000000 --- a/widgets/yawn/icons/Snow.png +++ /dev/null @@ -1 +0,0 @@ -SnowShowers.png \ No newline at end of file diff --git a/widgets/yawn/icons/SnowFlurries.png b/widgets/yawn/icons/SnowFlurries.png deleted file mode 120000 index 2e090cd..0000000 --- a/widgets/yawn/icons/SnowFlurries.png +++ /dev/null @@ -1 +0,0 @@ -BlowingSnow.png \ No newline at end of file diff --git a/widgets/yawn/icons/SnowShowers.png b/widgets/yawn/icons/SnowShowers.png deleted file mode 100755 index 30534a20d052bbc9c6353dd9eb950f3ea5956954..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9961 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 diff --git a/widgets/yawn/init.lua b/widgets/yawn/init.lua deleted file mode 100644 index 1f6b0f4..0000000 --- a/widgets/yawn/init.lua +++ /dev/null @@ -1,206 +0,0 @@ - ---[[ - - Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham - ---]] - -local newtimer = require("lain.helpers").newtimer -local async = require("lain.asyncshell") - -local naughty = require("naughty") -local wibox = require("wibox") - -local debug = { getinfo = debug.getinfo } -local io = { lines = io.lines, - open = io.open } -local os = { date = os.date, - getenv = os.getenv } -local string = { find = string.find, - match = string.match, - gsub = string.gsub, - sub = string.sub } -local tonumber = tonumber - -local setmetatable = setmetatable - --- YAhoo! Weather Notification --- lain.widgets.yawn -local yawn = -{ - icon = wibox.widget.imagebox(), - widget = wibox.widget.textbox('') -} - -local project_path = debug.getinfo(1, 'S').source:match[[^@(.*/).*$]] -local localizations_path = project_path .. 'localizations/' -local icon_path = project_path .. 'icons/' -local api_url = 'http://weather.yahooapis.com/forecastrss' -local units_set = '?u=c&w=' -- Default is Celsius -local language = string.match(os.getenv("LANG"), "(%S*$*)[.]") or "en_US" -- if LANG is not set -local weather_data = nil -local notification = nil -local city_id = nil -local sky = nil -local settings = function() end - -yawn_notification_preset = {} - -function yawn.fetch_weather() - local url = api_url .. units_set .. city_id - local cmd = "curl --connect-timeout 1 -fsm 3 '" .. url .. "'" - - async.request(cmd, function(f) - local text = f:read("*a") - f:close() - - -- In case of no connection or invalid city ID - -- widgets won't display - if text == "" or text:match("City not found") - then - yawn.icon:set_image(icon_path .. "na.png") - if text == "" then - weather_data = "Service not available at the moment." - yawn.widget:set_text(" N/A ") - else - weather_data = "City not found!\n" .. - "Are you sure " .. city_id .. - " is your Yahoo city ID?" - yawn.widget:set_text(" ? ") - end - return - end - - -- Processing raw data - weather_data = text:gsub("<.->", "") - weather_data = weather_data:match("Current Conditions:.-Full") or "" - - -- may still happens in case of bad connectivity - if weather_data == "" then - yawn.icon:set_image(icon_path .. "na.png") - yawn.widget:set_text(" ? ") - return - end - - weather_data = weather_data:gsub("Current Conditions:.-\n", "Now: ") - weather_data = weather_data:gsub("Forecast:.-\n", "") - weather_data = weather_data:gsub("\nFull", "") - weather_data = weather_data:gsub("[\n]$", "") - weather_data = weather_data:gsub(" [-] " , ": ") - weather_data = weather_data:gsub("[.]", ",") - weather_data = weather_data:gsub("High: ", "") - weather_data = weather_data:gsub(" Low: ", " - ") - - -- Getting info for text widget - local now = weather_data:sub(weather_data:find("Now:")+5, - weather_data:find("\n")-1) - forecast = now:sub(1, now:find(",")-1) - units = now:sub(now:find(",")+2, -2) - - -- Day/Night icon change - local hour = tonumber(os.date("%H")) - sky = icon_path - - if string.find(forecast, "Clear") or - string.find(forecast, "Fair") or - string.find(forecast, "Partly Cloudy") or - string.find(forecast, "Mostly Cloudy") - then - if hour >= 6 and hour <= 18 - then - sky = sky .. "Day" - else - sky = sky .. "Night" - end - end - - sky = sky .. forecast:gsub(" ", ""):gsub("/", "") .. ".png" - - -- In case there's no defined icon for current forecast - if io.open(sky) == nil then - sky = icon_path .. "na.png" - end - - -- Localization - local f = io.open(localizations_path .. language, "r") - if language:find("en_") == nil and f ~= nil - then - f:close() - for line in io.lines(localizations_path .. language) - do - word = string.sub(line, 1, line:find("|")-1) - translation = string.sub(line, line:find("|")+1) - weather_data = string.gsub(weather_data, word, translation) - end - end - - -- Finally setting infos - yawn.icon:set_image(sky) - widget = yawn.widget - - _data = weather_data:match(": %S.-,") or weather_data - forecast = _data:gsub(": ", ""):gsub(",", "") - units = units:gsub(" ", "") - - settings() - end) -end - -function yawn.hide() - if notification ~= nil then - naughty.destroy(notification) - notification = nil - end -end - -function yawn.show(t_out) - if yawn.widget._layout.text:match("?") - then - yawn.fetch_weather() - end - - yawn.hide() - - notification = naughty.notify({ - preset = yawn_notification_preset, - text = weather_data, - icon = sky, - timeout = t_out, - }) -end - -function yawn.register(id, args) - local args = args or {} - local timeout = args.timeout or 600 - settings = args.settings or function() end - - if args.u == "f" then units_set = '?u=f&w=' end - - city_id = id - - newtimer("yawn", timeout, yawn.fetch_weather) - - yawn.icon:connect_signal("mouse::enter", function() - yawn.show(0) - end) - yawn.icon:connect_signal("mouse::leave", function() - yawn.hide() - end) - - return yawn -end - -function yawn.attach(widget, id, args) - yawn.register(id, args) - - widget:connect_signal("mouse::enter", function() - yawn.show(0) - end) - - widget:connect_signal("mouse::leave", function() - yawn.hide() - end) -end - -return setmetatable(yawn, { __call = function(_, ...) return yawn.register(...) end }) diff --git a/widgets/yawn/localizations/de_DE b/widgets/yawn/localizations/de_DE deleted file mode 100644 index 82cef79..0000000 --- a/widgets/yawn/localizations/de_DE +++ /dev/null @@ -1,61 +0,0 @@ -Now:|Jetzt: -Sun:|So: -Mon:|Mo: -Tue:|Di: -Wed:|Mi: -Thu:|Do: -Fri:|Fr: -Sat:|Sa: -Mostly Sunny|Größtenteils Sonnig -Sunny|Sonnig -Sun|Sonne -Rain/Thunder|Regen/Donner -Isolated Thunderstorms|Vereinzelte Gewitter -Scattered Thunderstorms|Aufgelockertes Gewitter -Thundershowers|Gewitterschauer -Thunderstorms|Gewitter -Thunder in the Vicinity|Donner in der Umgebung -Thunder|Donner -AM|Vormittags -PM|Nachmittags -Early|Früh -Late|Spät -Few|einige -Severe|starker -Clear|Klar -Fair|Heiter -Partly|teilweise -Mostly|größtenteils -Cloudy|Wolkig -Clouds|Wolken -Scattered Showers|Vereinzelte Schauer -Light Snow Showers|Leichter Schneeregen -Snow Showers|Schneeregen -Heavy Snow|Starker Schneefall -Scattered Snow Showers|Vereinzelter Schneefall -Mixed Rain And Snow|Gemischter Regen und Schnee -Mixed Rain And Sleet|Gemischter Regen und Graupel -Mixed Snow And Sleet|Gemischter Schnee und Graupel -Mixed Rain And Hail|Gemischter Regen und Hagel -Snow Flurries|Schneegestöber -Blowing Snow|Schneetreiben -Blowing Rain|Treibender Regen -Heavy Rain|Starke Regenfälle -Freezing Rain|Eisregen -Showers|Schauer -Light Rain|Leichter Regen -Heavy|Starker -Rain|Regen -Windy|Windig -Wind|Wind -Snow|Schnee -Sleet|Graupel -Freezing Drizzle|Gefrierender Sprühregen -Light Drizzle|Leichter Sprühregen -Drizzle|Sprühregen -Hail|Hagel -Fog|Nebel -Foggy|Nebelig -Haze|Dunst -Light|leichter -With|mit \ No newline at end of file diff --git a/widgets/yawn/localizations/fr_FR b/widgets/yawn/localizations/fr_FR deleted file mode 100644 index 18a35bb..0000000 --- a/widgets/yawn/localizations/fr_FR +++ /dev/null @@ -1,61 +0,0 @@ -Now:|Auj: -Sun:|Dim: -Mon:|Lun: -Tue:|Mar: -Wed:|Mer: -Thu:|Jeu: -Fri:|Ven: -Sat:|Sam: -Mostly Sunny|Partiellement ensoleillé -Sunny|Ensoleillé -Sun|Soleil -Rain/Thunder|Pluie/Orage -Isolated Thunderstorms|Orages localisés -Scattered Thunderstorms|Orages épars -Thundershowers|Tempête -Thunderstorms|Orages -Thunder in the Vicinity|Orage aux alentours -Thunder|Orages -AM|Matinée -PM|Après-midi -Early|Tôt -Late|Tard -Few|Quelques -Severe|Sévère -Clear|Clair -Fair|Clair -Partly|Partiellement -Mostly|Très -Cloudy|Nuageux -Clouds|Nuages -Scattered Showers|Nuages épars -Light Snow Showers|Légères averses de neige -Snow Showers|Averses de neige -Heavy Snow|Neige -Scattered Snow Showers|Averses de neige localisées -Mixed Rain And Snow|Alternance de neige et de pluie -Mixed Rain And Sleet|Alternance de pluie et de neige fondue -Mixed Snow And Sleet|Alternance de neige et de neige fondue -Mixed Rain And Hail|Alternance de pluie et de grêle -Snow Flurries|Averses de neige -Blowing Snow|Neige -Blowing Rain|Pluie -Heavy Rain|Pluie forte -Freezing Rain|Pluie verglaçante -Showers|Averses -Light Rain|Pluie légère -Heavy|Forte -Rain|Pluie -Windy|Venteux -Wind|Vent -Snow|Neige -Sleet|Neige fondue -Freezing Drizzle|Bruine verglaçante -Light Drizzle|Légère bruine -Drizzle|Bruine -Hail|Grêle -Fog|Brouillard -Foggy|Brumeux -Haze|Brume -Light|Clair -With|Avec diff --git a/widgets/yawn/localizations/it_IT b/widgets/yawn/localizations/it_IT deleted file mode 100644 index 44d010e..0000000 --- a/widgets/yawn/localizations/it_IT +++ /dev/null @@ -1,61 +0,0 @@ -Now:|Ora: -Sun:|Dom: -Mon:|Lun: -Tue:|Mar: -Wed:|Mer: -Thu:|Gio: -Fri:|Ven: -Sat:|Sab: -Mostly Sunny|Abbastanza Soleggiato -Sunny|Soleggiato -Sun|Soleggiato -Rain/Thunder|Temporali -Isolated Thunderstorms|Temporali Isolati -Scattered Thunderstorms|Temporali Sparsi -Thundershowers|Rovesci Temporaleschi -Thunderstorms|Temporali -Thunder in the Vicinity|Tuoni in prossimità -Thunder|Temporale -AM|In Mattinata -PM|Nel Pomeriggio -Early|In Mattinata -Late|In Serata -Few|Sporadiche -Severe|Forti -Clear|Sereno -Fair|Sereno -Partly|Parzialmente -Mostly|Molto -Cloudy|Nuvoloso -Clouds|Nuvoloso -Scattered Showers|Temporali Sparsi -Light Snow Showers|Nevicate Leggere -Snow Showers|Nevicate -aeavy Snow|Forti Nevicate -Scattered Snow Showers|Nevicate Sparse -Mixed Rain And Snow|Pioggia E Neve -Mixed Rain And Sleet|Pioggia E Nevischio -Mixed Snow And Sleet|Neve E Nevischio -Mixed Rain And Hail|Pioggia E Grandine -Snow Flurries|Folate Di Neve -Blowing Snow|Neve Battente -Blowing Rain|Pioggia Battente -Heavy Rain|Forti Piogge -Freezing Rain|Pioggia Congelantesi -Showers|Piogge -Light Rain|Pioggia Leggera -Heavy|Forti -Rain|Piovoso -Windy|Ventoso -Wind|Ventoso -Snow|Neve -Sleet|Nevischio -Light Drizzle|Pioggia Leggera -Drizzle|Pioggia Leggera -Freezing Drizzle|Pioggerella Congelantesi -Hail|Grandine -Fog|Nebbia -Foggy|Nebbioso -Haze|Nebbia -Light|Leggere -With|Con diff --git a/widgets/yawn/localizations/localization_template b/widgets/yawn/localizations/localization_template deleted file mode 100644 index 2fbf066..0000000 --- a/widgets/yawn/localizations/localization_template +++ /dev/null @@ -1,61 +0,0 @@ -Now:| -Sun:| -Mon:| -Tue:| -Wed:| -Thu:| -Fri:| -Sat:| -Mostly Sunny| -Sunny| -Sun| -Rain/Thunder| -Isolated Thunderstorms| -Scattered Thunderstorms| -Thundershowers| -Thunderstorms| -Thunder in the Vicinity| -Thunder| -AM| -PM| -Early| -Late| -Few| -Severe| -Clear| -Fair| -Partly| -Mostly| -Cloudy| -Clouds| -Scattered Showers| -Light Snow Showers| -Snow Showers| -Heavy Snow| -Scattered Snow Showers| -Mixed Rain And Snow| -Mixed Rain And Sleet| -Mixed Snow And Sleet| -Mixed Rain And Hail| -Snow Flurries| -Blowing Snow| -Blowing Rain| -Heavy Rain| -Freezing Rain| -Showers| -Light Rain| -Heavy| -Rain| -Windy| -Wind| -Snow| -Sleet| -Freezing Drizzle| -Light Drizzle| -Drizzle| -Hail| -Fog| -Foggy| -Haze| -Light| -With| diff --git a/widgets/yawn/localizations/ru_RU b/widgets/yawn/localizations/ru_RU deleted file mode 100644 index 0b2ae23..0000000 --- a/widgets/yawn/localizations/ru_RU +++ /dev/null @@ -1,61 +0,0 @@ -Now:|Cейчас: -Sun:|Воскресенье: -Mon:|Понедельник: -Tue:|Вторник: -Wed:|Среда: -Thu:|Четверг: -Fri:|Пятница: -Sat:|Суббота: -Mostly Sunny|Преимущественно солнечно -Sunny|Солнечно -Sun|Солнце -Rain/Thunder|Дождь/Гром -Isolated Thunderstorms|Изолированные грозы -Scattered Thunderstorms|Рассеянные грозы -Thundershowers|Ливни -Thunderstorms|Грозы -Thunder in the Vicinity|Гром в окрестностях -Thunder|Гром -AM|Утро -PM|Вечер -Early|Рано -Late|Поздно -Few|Мало -Severe|Тяжелый -Clear|Ясно -Fair|Светлый -Partly|Частично -Mostly|По большей части -Cloudy|Облачно -Clouds|Облака -Scattered Showers|Рассеянные ливни -Light Snow Showers|Небольшой снег -Snow Showers|Ливневый Снег -Heavy Snow|Сильный снегопад -Scattered Snow Showers|Рассеянный ливневый снег -Mixed Rain And Snow|Снег с дождём -Mixed Rain And Sleet|Дождь и мокрый снег -Mixed Snow And Sleet|Снег и мокрый снег -Mixed Rain And Hail|Дождь с градом -Snow Flurries|Снежные порывы -Blowing Snow|Снег и ветер -Blowing Rain|Дождь и ветер -Heavy Rain|Сильный дождь -Freezing Rain|Ледяной дождь -Showers|Ливни -Light Rain|Небольшой дождь -Heavy|Сильный -Rain|Дождь -Windy|Ветреный -Wind|Ветер -Snow|Снег -Sleet|Мокрый снег -Freezing Drizzle|Изморозь -Light Drizzle|Лёгкая изморось -Drizzle|Моросящий дождь -Hail|Град -Fog|Туман -Foggy|Туманно -Haze|Дымка -Light|Лёгкий -With|С diff --git a/widgets/yawn/localizations/zh_CN b/widgets/yawn/localizations/zh_CN deleted file mode 100644 index 61e98a4..0000000 --- a/widgets/yawn/localizations/zh_CN +++ /dev/null @@ -1,61 +0,0 @@ -Now:|当前: -Sun:|周日: -Mon:|周一: -Tue:|周二: -Wed:|周三: -Thu:|周四: -Fri:|周五: -Sat:|周六: -Mostly Sunny|晴时多云 -Sunny|晴朗 -Sun|太阳 -Rain/Thunder|雨/雷 -Isolated Thunderstorms|局部雷雨 -Scattered Thunderstorms|零星雷雨 -Thundershowers|雷阵雨 -Thunderstorms|雷雨 -Thunder in the Vicinity|周围有雷雨 -Thunder|雷鸣 -AM|上午 -PM|下午 -Early|早 -Late|晚 -Few|短暂 -Severe|恶劣 -Clear|晴朗 -Fair|晴 -Partly|局部 -Mostly|大部 -Cloudy|多云 -Clouds|有云 -Scattered Showers|零星阵雨 -Light Snow Showers|小阵雪 -Snow Showers|阵雪 -Heavy Snow|大雪 -Scattered Snow Showers|零星阵雪 -Mixed Rain And Snow|雨夹雪 -Mixed Rain And Sleet|雨转雨夹雪 -Mixed Snow And Sleet|雪转雨夹雪 -Mixed Rain And Hail|雨夹冰雹 -Snow Flurries|阵雪 -Blowing Snow|风吹雪 -Blowing Rain|风吹雨 -Heavy Rain|大雨 -Freezing Rain|冻雨 -Showers|阵雨 -Light Rain|小雨 -Heavy|大 -Rain|雨 -Windy|有风 -Wind|风 -Snow|雪 -Sleet|冻雨 -Freezing Drizzle|冻毛毛雨 -Light Drizzle|细雨 -Drizzle|毛毛雨 -Hail|冰雹 -Fog|雾 -Foggy|有雾 -Haze|霾 -Light|小 -With|與 diff --git a/widgets/yawn/localizations/zh_TW b/widgets/yawn/localizations/zh_TW deleted file mode 100644 index 03644c1..0000000 --- a/widgets/yawn/localizations/zh_TW +++ /dev/null @@ -1,61 +0,0 @@ -Now:|現在: -Sun:|週日: -Mon:|週一: -Tue:|週二: -Wed:|週三: -Thu:|週四: -Fri:|週五: -Sat:|週六: -Mostly Sunny|晴時多雲 -Sunny|大太陽 -Sun|太陽 -Rain/Thunder|雨時有雷 -Isolated Thunderstorms|局部雷雨 -Scattered Thunderstorms|零星雷雨 -Thundershowers|雷陣雨 -Thunderstorms|雷雨 -Thunder in the Vicinity|局部性雷雨 -Thunder|雷嗚 -AM|上午 -PM|下午 -Early|早 -Late|晚有 -Few|短暫 -Severe|惡劣 -Clear|晴朗 -Fair|晴 -Partly|局部 -Mostly|大部 -Cloudy|多雲 -Clouds|有雲 -Scattered Showers|零星陣雨 -Light Snow Showers|小陣雪 -Snow Showers|陣雪 -Heavy Snow|大雪 -Scattered Snow Showers|零星陣雪 -Mixed Rain And Snow|雨夾雪 -Mixed Rain And Sleet|雨時雨夾雪 -Mixed Snow And Sleet|雪時雨夾雪 -Mixed Rain And Hail|雨夾冰雹 -Snow Flurries|陣雪 -Blowing Snow|風吹雪 -Blowing Rain|風吹雨 -Heavy Rain|大雨 -Freezing Rain|凍雨 -Showers|陣雨 -Light Rain|小雨 -Heavy|大 -Rain|雨 -Windy|有風 -Wind|風 -Snow|雪 -Sleet|冰珠 -Freezing Drizzle|凍毛毛雨 -Light Drizzle|細雨 -Drizzle|毛毛雨 -Hail|冰雹 -Fog|霧 -Foggy|有霧 -Haze|霾 -Light|小 -With|與 diff --git a/wiki b/wiki index b011c03..75c796a 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit b011c0339e805ee1596d0b6778d6c497dab41109 +Subproject commit 75c796a9a7a0f0f468bd36f77c7b918a2ff9a4d5 From d2e1557e421a7dce17ae43253394a1908f7e57a1 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Thu, 2 Jul 2015 12:09:45 +0200 Subject: [PATCH 509/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 75c796a..6cf15f9 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 75c796a9a7a0f0f468bd36f77c7b918a2ff9a4d5 +Subproject commit 6cf15f990457d3bfa9ac61ee3d57099143d1200d From 33ee32b4d165fe1547c6d9846653e9d3f00cd2ad Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 3 Jul 2015 11:56:38 +0200 Subject: [PATCH 510/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 6cf15f9..b260e93 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 6cf15f990457d3bfa9ac61ee3d57099143d1200d +Subproject commit b260e938c83f1339b0b4b3b003f33f302f9a47b1 From 973b56ce0b9ce214b5dc17795893ece7def6ce78 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 3 Jul 2015 12:17:31 +0200 Subject: [PATCH 511/546] whitespaces cleaning --- helpers.lua | 6 +++--- layout/centerfair.lua | 2 +- layout/uselessfair.lua | 14 +++++++------- layout/uselesspiral.lua | 8 ++++---- layout/uselesstile.lua | 14 +++++++------- util/separators.lua | 4 ++-- widgets/abase.lua | 2 +- widgets/calendar.lua | 4 ++-- widgets/contrib/moc.lua | 8 ++++---- widgets/contrib/redshift.lua | 34 +++++++++++++++++----------------- widgets/contrib/task.lua | 4 ++-- 11 files changed, 50 insertions(+), 50 deletions(-) diff --git a/helpers.lua b/helpers.lua index 9c4a83f..dbee617 100644 --- a/helpers.lua +++ b/helpers.lua @@ -43,12 +43,12 @@ function helpers.file_exists(file) return f ~= nil end --- get all lines from a file, returns an empty +-- get all lines from a file, returns an empty -- list/table if the file does not exist function helpers.lines_from(file) if not helpers.file_exists(file) then return {} end lines = {} - for line in io.lines(file) do + for line in io.lines(file) do lines[#lines + 1] = line end return lines @@ -64,7 +64,7 @@ end -- returns nil otherwise function helpers.first_nonempty_line(file) for k,v in pairs(helpers.lines_from(file)) do - if #v then return v end + if #v then return v end end return nil end diff --git a/layout/centerfair.lua b/layout/centerfair.lua index 67462f7..1e8915d 100644 --- a/layout/centerfair.lua +++ b/layout/centerfair.lua @@ -90,7 +90,7 @@ function centerfair.arrange(p) -- Master client deserves a special treatement local g = {} - g.width = wa.width - (num_x - 1) * width - num_x * 2*useless_gap - 2 + g.width = wa.width - (num_x - 1) * width - num_x * 2*useless_gap - 2 g.height = wa.height - 2*useless_gap - 2 g.x = offset_x + useless_gap + global_border g.y = offset_y + global_border diff --git a/layout/uselessfair.lua b/layout/uselessfair.lua index ee3aa40..e1284e0 100644 --- a/layout/uselessfair.lua +++ b/layout/uselessfair.lua @@ -1,12 +1,12 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2014, projektile, worron - * (c) 2013, Luke Bonham - * (c) 2012, Josh Komoroske - * (c) 2010-2012, Peter Hofmann - + + Licensed under GNU General Public License v2 + * (c) 2014, projektile, worron + * (c) 2013, Luke Bonham + * (c) 2012, Josh Komoroske + * (c) 2010-2012, Peter Hofmann + --]] local beautiful = require("beautiful") diff --git a/layout/uselesspiral.lua b/layout/uselesspiral.lua index ba63bca..c388961 100644 --- a/layout/uselesspiral.lua +++ b/layout/uselesspiral.lua @@ -2,10 +2,10 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2014 projektile - * (c) 2013 Luke Bonham - * (c) 2009 Uli Schlachter - * (c) 2008 Julien Danjolu + * (c) 2014, projektile + * (c) 2013, Luke Bonham + * (c) 2009, Uli Schlachter + * (c) 2008, Julien Danjolu --]] diff --git a/layout/uselesstile.lua b/layout/uselesstile.lua index 877fad1..e48c85d 100644 --- a/layout/uselesstile.lua +++ b/layout/uselesstile.lua @@ -1,12 +1,12 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2014 projektile, worron - * (c) 2013 Luke Bonham - * (c) 2009 Donald Ephraim Curtis - * (c) 2008 Julien Danjolu - + + Licensed under GNU General Public License v2 + * (c) 2014, projektile, worron + * (c) 2013, Luke Bonham + * (c) 2009, Donald Ephraim Curtis + * (c) 2008, Julien Danjolu + --]] local tag = require("awful.tag") diff --git a/util/separators.lua b/util/separators.lua index d2a3891..6e5ef96 100644 --- a/util/separators.lua +++ b/util/separators.lua @@ -2,8 +2,8 @@ --[[ Licensed under GNU General Public License v2 - * (c) 2015, Luke Bonham - * (c) 2015, plotnikovanton + * (c) 2015, Luke Bonham + * (c) 2015, plotnikovanton --]] diff --git a/widgets/abase.lua b/widgets/abase.lua index 075d615..8ffdf0e 100644 --- a/widgets/abase.lua +++ b/widgets/abase.lua @@ -12,7 +12,7 @@ local wibox = require("wibox") local setmetatable = setmetatable --- Basic template for custom widgets +-- Basic template for custom widgets -- Asynchronous version -- lain.widgets.abase diff --git a/widgets/calendar.lua b/widgets/calendar.lua index cc0ebe7..3e65f38 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -37,7 +37,7 @@ function calendar:show(t_out, inc_offset, scr) local tims = t_out or 0 local f, c_text local today = tonumber(os.date('%d')) - local init_t = calendar.cal .. ' ' .. calendar.post_cal .. ' ' .. + local init_t = calendar.cal .. ' ' .. calendar.post_cal .. ' ' .. ' | sed -r -e "s/_\\x08//g" | sed -r -e "s/(^| )(' calendar.offset = calendar.offset + offs @@ -77,7 +77,7 @@ function calendar:show(t_out, inc_offset, scr) calendar.notify_icon = nil - f = io.popen(calendar.cal .. ' ' .. month .. ' ' .. year .. ' ' .. + f = io.popen(calendar.cal .. ' ' .. month .. ' ' .. year .. ' ' .. calendar.post_cal) end diff --git a/widgets/contrib/moc.lua b/widgets/contrib/moc.lua index 84c618b..cfdbec7 100644 --- a/widgets/contrib/moc.lua +++ b/widgets/contrib/moc.lua @@ -1,9 +1,9 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2014, anticlockwise - + + Licensed under GNU General Public License v2 + * (c) 2014, anticlockwise + --]] local helpers = require("lain.helpers") diff --git a/widgets/contrib/redshift.lua b/widgets/contrib/redshift.lua index 38f1d83..5ed9300 100644 --- a/widgets/contrib/redshift.lua +++ b/widgets/contrib/redshift.lua @@ -1,25 +1,25 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2014, blueluke - + + Licensed under GNU General Public License v2 + * (c) 2014, blueluke + --]] -local os = os -local awful = require("awful") -local spawn = awful.util.spawn_with_shell +local awful = require("awful") +local os = os +local spawn = awful.util.spawn_with_shell local setmetatable = setmetatable --- redshift +-- Redshift -- lain.widgets.contrib.redshift local redshift = {} -local attached = false -- true if attached to a widget -local active = false -- true if redshift is active -local running = false -- true if redshift was initialized -local update_fnct = function() end -- function that is run each time redshift is toggled. See redshift:attach(). +local attached = false -- true if attached to a widget +local active = false -- true if redshift is active +local running = false -- true if redshift was initialized +local update_fnct = function() end -- Function that is run each time redshift is toggled. See redshift:attach(). local function init() @@ -35,11 +35,11 @@ local function init() end function redshift:toggle() - if running then + if running then -- Sending -USR1 toggles redshift (See project website) os.execute("pkill -USR1 redshift") active = not active - else + else init() end update_fnct() @@ -63,9 +63,9 @@ end -- Attach to a widget -- Provides a button which toggles redshift on/off on click --- @ param widget: widget to attach to --- @ param fnct: function to be run each time redshift is toggled (optional). --- Use it to update widget text or icons on status change. +-- @param widget: Widget to attach to. +-- @param fnct: Function to be run each time redshift is toggled (optional). +-- Use it to update widget text or icons on status change. function redshift:attach(widget, fnct) update_fnct = fnct or function() end if not attached then diff --git a/widgets/contrib/task.lua b/widgets/contrib/task.lua index 2e30cdc..6425926 100644 --- a/widgets/contrib/task.lua +++ b/widgets/contrib/task.lua @@ -59,7 +59,7 @@ function task:prompt_add() mypromptbox[mouse.screen].widget, function (...) local f = io.popen("task add " .. ...) - c_text = "\n" .. f:read("*all") @@ -94,7 +94,7 @@ function task:prompt_search() c_text = "" - .. c_text + .. c_text .. "" end From f31134fd1c35835cfea15dcc4db04b1985b89e2b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 3 Jul 2015 18:05:22 +0200 Subject: [PATCH 512/546] weather.forecast_update: forgot to add check on err --- widgets/weather.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/weather.lua b/widgets/weather.lua index d8dfd3f..c69d02b 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -75,7 +75,7 @@ local function worker(args) f:close() weather_now, pos, err = json.decode(j, 1, nil) - if tonumber(weather_now["cod"]) == 200 then + if not err and tonumber(weather_now["cod"]) == 200 then weather.notification_text = '' for i = 1, weather_now["cnt"] do local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"]))) From fa0d05aa95f8f37efb54cbdd4f01516988ed9c6a Mon Sep 17 00:00:00 2001 From: luke bonham Date: Fri, 3 Jul 2015 18:10:03 +0200 Subject: [PATCH 513/546] weather.forecast_update: forgot to add check on err --- widgets/weather.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/weather.lua b/widgets/weather.lua index c69d02b..7223c29 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -75,7 +75,7 @@ local function worker(args) f:close() weather_now, pos, err = json.decode(j, 1, nil) - if not err and tonumber(weather_now["cod"]) == 200 then + if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then weather.notification_text = '' for i = 1, weather_now["cnt"] do local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"]))) From 94fe36d0c74a4c620e02c3e861b41eff39e6eed4 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 5 Jul 2015 11:12:41 +0200 Subject: [PATCH 514/546] weather: add back default hover notification; #113 --- widgets/weather.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/widgets/weather.lua b/widgets/weather.lua index 7223c29..7673284 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -116,6 +116,8 @@ local function worker(args) end) end + weather.attach(weather.widget) + newtimer("weather", timeout, weather.update) newtimer("weather_forecast", timeout, weather.forecast_update) From d1e810f2fc4620f8b3c278d57506c47360a77b0c Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 5 Jul 2015 11:30:24 +0200 Subject: [PATCH 515/546] weather: added failsafe check; #105 --- widgets/weather.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/widgets/weather.lua b/widgets/weather.lua index 7673284..d1624fa 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -30,7 +30,7 @@ local function worker(args) local timeout_forecast = args.timeout or 86400 -- 24 hrs local current_call = "curl -s 'http://api.openweathermap.org/data/2.5/weather?id=%s&units=%s&lang=%s'" local forecast_call = "curl -s 'http://api.openweathermap.org/data/2.5/forecast/daily?id=%s&units=%s&lang=%s&cnt=%s'" - local city_id = args.city_id + local city_id = args.city_id or 0 -- placeholder local units = args.units or "metric" local lang = args.lang or "en" local cnt = args.cnt or 7 @@ -93,6 +93,9 @@ local function worker(args) weather.notification_text = weather.notification_text .. "\n" end end + else + weather.icon_path = icons_path .. "na.png" + weather.notification_text = "API/connection error or bad/not set city ID" end end) end @@ -104,14 +107,14 @@ local function worker(args) f:close() weather_now, pos, err = json.decode(j, 1, nil) - if err then - weather.widget.set_text("N/A") - weather.icon:set_image(icons_path .. "na.png") - elseif tonumber(weather_now["cod"]) == 200 then + if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then weather.icon_path = icons_path .. weather_now["weather"][1]["icon"] .. ".png" weather.icon:set_image(weather.icon_path) widget = weather.widget settings() + else + weather.widget._layout.text = " N/A " -- tries to avoid textbox bugs + weather.icon:set_image(icons_path .. "na.png") end end) end From b92942b0e07f4491cf5d96fecee94b1e82675e52 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 9 Jul 2015 12:52:18 +0200 Subject: [PATCH 516/546] enhancement: unique timers for widgets; #114 --- widgets/alsa.lua | 4 +++- widgets/alsabar.lua | 6 ++++-- widgets/bat.lua | 2 +- widgets/contrib/tpbat/init.lua | 2 +- widgets/fs.lua | 12 ++++++------ widgets/weather.lua | 4 ++-- wiki | 2 +- 7 files changed, 18 insertions(+), 14 deletions(-) diff --git a/widgets/alsa.lua b/widgets/alsa.lua index a356892..979d9fd 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -60,7 +60,9 @@ local function worker(args) settings() end - newtimer("alsa", timeout, alsa.update) + timer_id = string.format("alsa-%s-%s", alsa.cmd, alsa.channel) + + newtimer(timer_id, timeout, alsa.update) return setmetatable(alsa, { __index = alsa.widget }) end diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 1421975..2639aa4 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -148,8 +148,6 @@ local function worker(args) settings() end - newtimer("alsabar", timeout, alsabar.update) - alsabar.bar:buttons (awful.util.table.join ( awful.button ({}, 1, function() awful.util.spawn(alsabar.mixer) @@ -168,6 +166,10 @@ local function worker(args) end) )) + timer_id = string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel) + + newtimer(timer_id, timeout, alsa.update) + return alsabar end diff --git a/widgets/bat.lua b/widgets/bat.lua index 572d099..626239b 100644 --- a/widgets/bat.lua +++ b/widgets/bat.lua @@ -141,7 +141,7 @@ local function worker(args) end end - newtimer("bat", timeout, update) + newtimer(battery, timeout, update) return bat.widget end diff --git a/widgets/contrib/tpbat/init.lua b/widgets/contrib/tpbat/init.lua index 782bf35..0a22526 100644 --- a/widgets/contrib/tpbat/init.lua +++ b/widgets/contrib/tpbat/init.lua @@ -159,7 +159,7 @@ function tpbat.register(args) settings() end - newtimer("tpbat", timeout, update) + newtimer("tpbat-" .. bat.name, timeout, update) widget:connect_signal('mouse::enter', function () tpbat:show() end) widget:connect_signal('mouse::leave', function () tpbat:hide() end) diff --git a/widgets/fs.lua b/widgets/fs.lua index 8b51178..fab61bd 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -61,7 +61,7 @@ local function worker(args) fs.widget = wibox.widget.textbox('') - helpers.set_map("fs", false) + helpers.set_map(partition, false) function update() fs_info = {} @@ -91,7 +91,7 @@ local function worker(args) widget = fs.widget settings() - if fs_now.used >= 99 and not helpers.get_map("fs") + if fs_now.used >= 99 and not helpers.get_map(partition) then naughty.notify({ title = "warning", @@ -100,17 +100,17 @@ local function worker(args) fg = "#000000", bg = "#FFFFFF", }) - helpers.set_map("fs", true) + helpers.set_map(partition, true) else - helpers.set_map("fs", false) + helpers.set_map(partition, false) end end - helpers.newtimer(partition, timeout, update) - widget:connect_signal('mouse::enter', function () fs:show(0) end) widget:connect_signal('mouse::leave', function () fs:hide() end) + helpers.newtimer(partition, timeout, update) + return setmetatable(fs, { __index = fs.widget }) end diff --git a/widgets/weather.lua b/widgets/weather.lua index d1624fa..77d9b9b 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -121,8 +121,8 @@ local function worker(args) weather.attach(weather.widget) - newtimer("weather", timeout, weather.update) - newtimer("weather_forecast", timeout, weather.forecast_update) + newtimer("weather-" .. city_id, timeout, weather.update) + newtimer("weather_forecast" .. city_id, timeout, weather.forecast_update) return setmetatable(weather, { __index = weather.widget }) end diff --git a/wiki b/wiki index b260e93..54b3a71 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit b260e938c83f1339b0b4b3b003f33f302f9a47b1 +Subproject commit 54b3a717b2f7069264ce5a20018ae4abf153e7b2 From fb358dcd043d9639cb2ec19f4e369b8aa31675dc Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Thu, 9 Jul 2015 12:53:08 +0200 Subject: [PATCH 517/546] enhancement: unique timers for widgets; #114 --- widgets/alsabar.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 2639aa4..8ec5a00 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -168,7 +168,7 @@ local function worker(args) timer_id = string.format("alsabar-%s-%s", alsabar.cmd, alsabar.channel) - newtimer(timer_id, timeout, alsa.update) + newtimer(timer_id, timeout, alsabar.update) return alsabar end From 72556c9cd181c7cc269fdd164c09d8059684f431 Mon Sep 17 00:00:00 2001 From: aajjbb Date: Sat, 11 Jul 2015 14:19:12 -0300 Subject: [PATCH 518/546] fixing small typo in fs widget which lead to nil reference --- widgets/fs.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/fs.lua b/widgets/fs.lua index fab61bd..951f0cc 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -106,8 +106,8 @@ local function worker(args) end end - widget:connect_signal('mouse::enter', function () fs:show(0) end) - widget:connect_signal('mouse::leave', function () fs:hide() end) + fs.widget:connect_signal('mouse::enter', function () fs:show(0) end) + fs.widget:connect_signal('mouse::leave', function () fs:hide() end) helpers.newtimer(partition, timeout, update) From 2119b79449f73828eae44ecaa762c2daf52de394 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 12 Jul 2015 11:22:10 +0200 Subject: [PATCH 519/546] uniform timers for single-instance widgets; #114 --- widgets/alsabar.lua | 4 ++-- widgets/cpu.lua | 2 +- widgets/mem.lua | 2 +- widgets/sysload.lua | 2 +- widgets/temp.lua | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 8ec5a00..c957dbb 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -56,7 +56,7 @@ function alsabar.notify() local preset = { title = "", text = "", - timeout = 4, + timeout = 5, screen = alsabar.notifications.screen, font = alsabar.notifications.font .. " " .. alsabar.notifications.font_size, @@ -90,7 +90,7 @@ end local function worker(args) local args = args or {} - local timeout = args.timeout or 4 + local timeout = args.timeout or 5 local settings = args.settings or function() end local width = args.width or 63 local height = args.heigth or 1 diff --git a/widgets/cpu.lua b/widgets/cpu.lua index 7c1ecb0..ec84101 100644 --- a/widgets/cpu.lua +++ b/widgets/cpu.lua @@ -28,7 +28,7 @@ local cpu = { local function worker(args) local args = args or {} - local timeout = args.timeout or 5 + local timeout = args.timeout or 2 local settings = args.settings or function() end cpu.widget = wibox.widget.textbox('') diff --git a/widgets/mem.lua b/widgets/mem.lua index 46bb5f9..f6213b2 100644 --- a/widgets/mem.lua +++ b/widgets/mem.lua @@ -23,7 +23,7 @@ local mem = {} local function worker(args) local args = args or {} - local timeout = args.timeout or 3 + local timeout = args.timeout or 2 local settings = args.settings or function() end mem.widget = wibox.widget.textbox('') diff --git a/widgets/sysload.lua b/widgets/sysload.lua index 144ad0c..b10c5e2 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -22,7 +22,7 @@ local sysload = {} local function worker(args) local args = args or {} - local timeout = args.timeout or 5 + local timeout = args.timeout or 2 local settings = args.settings or function() end sysload.widget = wibox.widget.textbox('') diff --git a/widgets/temp.lua b/widgets/temp.lua index 5994f59..1e93848 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -21,7 +21,7 @@ local temp = {} local function worker(args) local args = args or {} - local timeout = args.timeout or 5 + local timeout = args.timeout or 2 local tempfile = args.tempfile or "/sys/class/thermal/thermal_zone0/temp" local settings = args.settings or function() end From 2565a0f0b0dc6adf1f155587373a9e247e6e6b39 Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 12 Jul 2015 11:51:58 +0200 Subject: [PATCH 520/546] mpd: added http streams check; #115 --- widgets/mpd.lua | 12 +++++++++--- wiki | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index c10eb78..6b66f81 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -89,12 +89,18 @@ local function worker(args) then helpers.set_map("current mpd track", mpd_now.title) - os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir, - mpd_now.file, cover_size, default_art)) + if string.match(mpd_now.file, "http://") == nil + then -- local file + os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir, + mpd_now.file, cover_size, default_art)) + current_icon = "/tmp/mpdcover.png" + else -- http stream + current_icon = default_art + end mpd.id = naughty.notify({ preset = mpd_notification_preset, - icon = "/tmp/mpdcover.png", + icon = current_icon, replaces_id = mpd.id, }).id end diff --git a/wiki b/wiki index 54b3a71..4021f24 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 54b3a717b2f7069264ce5a20018ae4abf153e7b2 +Subproject commit 4021f24b33be60d2e6b4050098bd8da131648a7e From 3afe2d54690edf4474a80fa212d9b3819dc716ce Mon Sep 17 00:00:00 2001 From: Luke Bonham Date: Sun, 12 Jul 2015 17:17:22 +0200 Subject: [PATCH 521/546] alsabar: button signals updated --- widgets/alsabar.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index c957dbb..2cf1c29 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -25,7 +25,6 @@ local setmetatable = setmetatable -- ALSA volume bar -- lain.widgets.alsabar local alsabar = { - card = "0", channel = "Master", step = "2%", @@ -153,15 +152,15 @@ local function worker(args) awful.util.spawn(alsabar.mixer) end), awful.button ({}, 3, function() - awful.util.spawn(string.format("amixer -c %s set %s toggle", alsabar.card, alsabar.channel)) + awful.util.spawn(string.format("%s set %s toggle", alsabar.cmd, alsabar.channel)) alsabar.update() end), awful.button ({}, 4, function() - awful.util.spawn(string.format("amixer -c %s set %s %s+", alsabar.card, alsabar.channel, alsabar.step)) + awful.util.spawn(string.format("%s set %s %s+", alsabar.cmd, alsabar.channel, alsabar.step)) alsabar.update() end), awful.button ({}, 5, function() - awful.util.spawn(string.format("amixer -c %s set %s %s-", alsabar.card, alsabar.channel, alsabar.step)) + awful.util.spawn(string.format("%s set %s %s-", alsabar.cmd, alsabar.channel, alsabar.step)) alsabar.update() end) )) From c6fadc6871a4810aa29395a02d125d1380de7b49 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 26 Jul 2015 00:49:49 +0200 Subject: [PATCH 522/546] #121: fixed typo --- widgets/weather.lua | 2 +- wiki | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/weather.lua b/widgets/weather.lua index 77d9b9b..559d4d2 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -79,7 +79,7 @@ local function worker(args) weather.notification_text = '' for i = 1, weather_now["cnt"] do local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"]))) - day = string.gsub(f:read("a"), "\n", "") + day = string.gsub(f:read("*a"), "\n", "") f:close() tmin = math.floor(weather_now["list"][i]["temp"]["min"]) diff --git a/wiki b/wiki index 4021f24..b260e93 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 4021f24b33be60d2e6b4050098bd8da131648a7e +Subproject commit b260e938c83f1339b0b4b3b003f33f302f9a47b1 From 293091d2674bb5b37d461b7989a39b7048800794 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 26 Jul 2015 00:59:23 +0200 Subject: [PATCH 523/546] #121: io.read abbreviations removed --- widgets/abase.lua | 2 +- widgets/alsa.lua | 2 +- widgets/alsabar.lua | 2 +- widgets/base.lua | 2 +- widgets/calendar.lua | 2 +- widgets/fs.lua | 2 +- widgets/imap.lua | 4 ++-- widgets/maildir.lua | 2 +- widgets/net.lua | 2 +- widgets/sysload.lua | 2 +- widgets/temp.lua | 2 +- widgets/weather.lua | 6 +++--- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/widgets/abase.lua b/widgets/abase.lua index 8ffdf0e..1c132cd 100644 --- a/widgets/abase.lua +++ b/widgets/abase.lua @@ -27,7 +27,7 @@ local function worker(args) function abase.update() async.request(cmd, function(f) - output = f:read("*a") + output = f:read("*all") f:close() widget = abase.widget settings() diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 979d9fd..91bf488 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -33,7 +33,7 @@ local function worker(args) function alsa.update() local f = assert(io.popen(string.format("%s get %s", alsa.cmd, alsa.channel))) - local mixer = f:read("*a") + local mixer = f:read("*all") f:close() volume_now = {} diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 2cf1c29..5fe74c4 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -117,7 +117,7 @@ local function worker(args) function alsabar.update() -- Get mixer control contents local f = assert(io.popen(string.format("%s get %s", alsabar.cmd, alsabar.channel))) - local mixer = f:read("*a") + local mixer = f:read("*all") f:close() -- Capture mixer control state: [5%] ... ... [on] diff --git a/widgets/base.lua b/widgets/base.lua index 39b0863..2a7bf10 100644 --- a/widgets/base.lua +++ b/widgets/base.lua @@ -26,7 +26,7 @@ local function worker(args) function base.update() local f = assert(io.popen(cmd)) - output = f:read("*a") + output = f:read("*all") f:close() widget = base.widget settings() diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 3e65f38..2df2f05 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -85,7 +85,7 @@ function calendar:show(t_out, inc_offset, scr) .. calendar.font_size .. "'>" .. f:read() .. "\n\n" .. f:read() .. "\n" - .. f:read("*a"):gsub("\n*$", "") + .. f:read("*all"):gsub("\n*$", "") .. "" f:close() diff --git a/widgets/fs.lua b/widgets/fs.lua index 951f0cc..07490fa 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -40,7 +40,7 @@ function fs:show(t_out) fs:hide() local f = io.popen(helpers.scripts_dir .. "dfs") - ws = f:read("*a"):gsub("\n*$", "") + ws = f:read("*all"):gsub("\n*$", "") f:close() notification = naughty.notify({ diff --git a/widgets/imap.lua b/widgets/imap.lua index 1ebbb76..ea62cc7 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -42,7 +42,7 @@ local function worker(args) if not is_plain then local f = io.popen(password) - password = f:read("*a"):gsub("\n", "") + password = f:read("*all"):gsub("\n", "") f:close() end @@ -58,7 +58,7 @@ local function worker(args) head_command, server, port, mail, password, request) async.request(curl, function(f) - ws = f:read("*a") + ws = f:read("*all") f:close() _, mailcount = string.gsub(ws, "%d+", "") diff --git a/widgets/maildir.lua b/widgets/maildir.lua index 246341f..315ae34 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -53,7 +53,7 @@ local function worker(args) local np = io.popen("find " .. line .. "/new -mindepth 1 -type f " .. "-not -name '.*' -printf a") - local mailstring = np:read("*a") + local mailstring = np:read("*all") -- Strip off leading mailpath. local box = string.match(line, mailpath .. "/*([^/]+)") diff --git a/widgets/net.lua b/widgets/net.lua index 2585ad4..d859d91 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -29,7 +29,7 @@ local net = { function net.get_device() f = io.popen("ip link show | cut -d' ' -f2,9") - ws = f:read("*a") + ws = f:read("*all") f:close() ws = ws:match("%w+: UP") or ws:match("ppp%w+: UNKNOWN") if ws ~= nil then diff --git a/widgets/sysload.lua b/widgets/sysload.lua index b10c5e2..d8e4713 100644 --- a/widgets/sysload.lua +++ b/widgets/sysload.lua @@ -29,7 +29,7 @@ local function worker(args) function update() local f = io.open("/proc/loadavg") - local ret = f:read("*a") + local ret = f:read("*all") f:close() load_1, load_5, load_15 = string.match(ret, "([^%s]+) ([^%s]+) ([^%s]+)") diff --git a/widgets/temp.lua b/widgets/temp.lua index 1e93848..67c9456 100644 --- a/widgets/temp.lua +++ b/widgets/temp.lua @@ -31,7 +31,7 @@ local function worker(args) local f = io.open(tempfile) if f ~= nil then - coretemp_now = tonumber(f:read("*a")) / 1000 + coretemp_now = tonumber(f:read("*all")) / 1000 f:close() else coretemp_now = "N/A" diff --git a/widgets/weather.lua b/widgets/weather.lua index 559d4d2..53ae838 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -71,7 +71,7 @@ local function worker(args) function weather.forecast_update() local cmd = string.format(forecast_call, city_id, units, lang, cnt) async.request(cmd, function(f) - j = f:read("*a") + j = f:read("*all") f:close() weather_now, pos, err = json.decode(j, 1, nil) @@ -79,7 +79,7 @@ local function worker(args) weather.notification_text = '' for i = 1, weather_now["cnt"] do local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"]))) - day = string.gsub(f:read("*a"), "\n", "") + day = string.gsub(f:read("*all"), "\n", "") f:close() tmin = math.floor(weather_now["list"][i]["temp"]["min"]) @@ -103,7 +103,7 @@ local function worker(args) function weather.update() local cmd = string.format(current_call, city_id, units, lang) async.request(cmd, function(f) - j = f:read("*a") + j = f:read("*all") f:close() weather_now, pos, err = json.decode(j, 1, nil) From 89bad3b56b7a76318113f3831b74c156044aa34b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Sun, 26 Jul 2015 01:08:12 +0200 Subject: [PATCH 524/546] #112 fix --- widgets/mpd.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 6b66f81..d910fd1 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -40,7 +40,7 @@ local function worker(args) local mpdcover = helpers.scripts_dir .. "mpdcover" local mpdh = "telnet://" .. host .. ":" .. port - local echo = "echo 'password " .. password .. "\nstatus\ncurrentsong\nclose'" + local echo = "echo -e 'password " .. password .. "\nstatus\ncurrentsong\nclose'" mpd.widget = wibox.widget.textbox('') From 95fe93a75106d4a57fcac6cb51540ba93a821836 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Mon, 27 Jul 2015 13:05:56 +0200 Subject: [PATCH 525/546] #115: also catching http.*// --- widgets/mpd.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index d910fd1..cea4a78 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -89,7 +89,7 @@ local function worker(args) then helpers.set_map("current mpd track", mpd_now.title) - if string.match(mpd_now.file, "http://") == nil + if string.match(mpd_now.file, "http.*://") == nil then -- local file os.execute(string.format("%s %q %q %d %q", mpdcover, music_dir, mpd_now.file, cover_size, default_art)) From 2e8fd41bc3ca120ae71658aeda98bcb91a0fd9d9 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 28 Jul 2015 20:43:47 +0200 Subject: [PATCH 526/546] allow to define in supported widgets which don't allow it already --- widgets/contrib/task.lua | 7 +++++-- widgets/fs.lua | 9 +++++---- widgets/imap.lua | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/widgets/contrib/task.lua b/widgets/contrib/task.lua index 6425926..3b8039f 100644 --- a/widgets/contrib/task.lua +++ b/widgets/contrib/task.lua @@ -31,7 +31,7 @@ function task:hide() end end -function task:show() +function task:show(scr_pos) task:hide() local f, c_text @@ -51,6 +51,7 @@ function task:show() fg = task.fg, bg = task.bg, timeout = task.timeout, + screen = scr_pos or 1 }) end @@ -106,6 +107,7 @@ function task:prompt_search() fg = task.fg, bg = task.bg, timeout = task.timeout, + screen = mouse.screen }) end, nil, @@ -122,11 +124,12 @@ function task:attach(widget, args) task.bg = args.bg or beautiful.bg_normal or "#FFFFFF" task.position = args.position or "top_right" task.timeout = args.timeout or 7 + task.scr_pos = args.scr_pos or 1 task.notify_icon = icons_dir .. "/taskwarrior/task.png" task.notify_icon_small = icons_dir .. "/taskwarrior/tasksmall.png" - widget:connect_signal("mouse::enter", function () task:show() end) + widget:connect_signal("mouse::enter", function () task:show(scr_pos) end) widget:connect_signal("mouse::leave", function () task:hide() end) end diff --git a/widgets/fs.lua b/widgets/fs.lua index 07490fa..dbd45bf 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -36,7 +36,7 @@ function fs:hide() end end -function fs:show(t_out) +function fs:show(t_out, scr) fs:hide() local f = io.popen(helpers.scripts_dir .. "dfs") @@ -44,9 +44,10 @@ function fs:show(t_out) f:close() notification = naughty.notify({ - preset = fs_notification_preset, - text = ws, + preset = fs_notification_preset, + text = ws, timeout = t_out, + screen = scr or 1 }) end @@ -106,7 +107,7 @@ local function worker(args) end end - fs.widget:connect_signal('mouse::enter', function () fs:show(0) end) + fs.widget:connect_signal('mouse::enter', function () fs:show(0, mouse.screen) end) fs.widget:connect_signal('mouse::leave', function () fs:hide() end) helpers.newtimer(partition, timeout, update) diff --git a/widgets/imap.lua b/widgets/imap.lua index ea62cc7..a17b02f 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -76,7 +76,7 @@ local function worker(args) end naughty.notify({ preset = mail_notification_preset, - text = nt, + text = nt }) end From d3cf8f992b0a987122155e72f15ee286ad8f7965 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Tue, 28 Jul 2015 20:52:52 +0200 Subject: [PATCH 527/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index b260e93..1544177 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit b260e938c83f1339b0b4b3b003f33f302f9a47b1 +Subproject commit 1544177cc083a62e40d93dfc29e545dcafae40be From e43585e94796926ceec3639bc71c0ed9bc62ae43 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 29 Jul 2015 11:54:51 +0200 Subject: [PATCH 528/546] #112: using /bin/echo -e --- widgets/mpd.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index cea4a78..a0b7192 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -40,7 +40,7 @@ local function worker(args) local mpdcover = helpers.scripts_dir .. "mpdcover" local mpdh = "telnet://" .. host .. ":" .. port - local echo = "echo -e 'password " .. password .. "\nstatus\ncurrentsong\nclose'" + local echo = "/bin/echo -e 'password " .. password .. "\nstatus\ncurrentsong\nclose'" mpd.widget = wibox.widget.textbox('') From f291bd62b75e4d18b6e96fff845c3597640d92a7 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 29 Jul 2015 12:16:13 +0200 Subject: [PATCH 529/546] reverted bb3a0c1 and fixed scr_pos pointers in calendar widget --- widgets/calendar.lua | 12 ++++++------ widgets/fs.lua | 17 +++++++++-------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 2df2f05..a03503e 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -111,21 +111,21 @@ function calendar:attach(widget, args) calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF" calendar.position = args.position or "top_right" - calendar.scr_pos = args.scr_pos or 1 + calendar.scr_pos = args.scr_pos or mouse.screen calendar.offset = 0 calendar.notify_icon = nil - widget:connect_signal("mouse::enter", function () calendar:show(0, 0, scr_pos) end) + widget:connect_signal("mouse::enter", function () calendar:show(0, 0, calendar.scr_pos) end) widget:connect_signal("mouse::leave", function () calendar:hide() end) widget:buttons(awful.util.table.join( awful.button({ }, 1, function () - calendar:show(0, -1, scr_pos) end), + calendar:show(0, -1, calendar.scr_pos) end), awful.button({ }, 3, function () - calendar:show(0, 1, scr_pos) end), + calendar:show(0, 1, calendar.scr_pos) end), awful.button({ }, 4, function () - calendar:show(0, -1, scr_pos) end), + calendar:show(0, -1, calendar.scr_pos) end), awful.button({ }, 5, function () - calendar:show(0, 1, scr_pos) end))) + calendar:show(0, 1, calendar.scr_pos) end))) end return setmetatable(calendar, { __call = function(_, ...) return create(...) end }) diff --git a/widgets/fs.lua b/widgets/fs.lua index dbd45bf..a2d8990 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -26,19 +26,21 @@ local setmetatable = setmetatable -- lain.widgets.fs local fs = {} -local notification = nil +local fs_notification = nil fs_notification_preset = { fg = beautiful.fg_normal } function fs:hide() - if notification ~= nil then - naughty.destroy(notification) - notification = nil + if fs_notification ~= nil then + naughty.destroy(fs_notification) + fs_notification = nil end end -function fs:show(t_out, scr) +function fs:show(t_out) fs:hide() + naughty.notify({text=fs_notification_preset.screen}) + local f = io.popen(helpers.scripts_dir .. "dfs") ws = f:read("*all"):gsub("\n*$", "") f:close() @@ -46,8 +48,7 @@ function fs:show(t_out, scr) notification = naughty.notify({ preset = fs_notification_preset, text = ws, - timeout = t_out, - screen = scr or 1 + timeout = t_out }) end @@ -107,7 +108,7 @@ local function worker(args) end end - fs.widget:connect_signal('mouse::enter', function () fs:show(0, mouse.screen) end) + fs.widget:connect_signal('mouse::enter', function () fs:show(0) end) fs.widget:connect_signal('mouse::leave', function () fs:hide() end) helpers.newtimer(partition, timeout, update) From 52deb6911957f840a0191f73c8a9626bd9ff5086 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 29 Jul 2015 13:21:59 +0200 Subject: [PATCH 530/546] #126 extended to every supported widget --- widgets/alsabar.lua | 6 +++++ widgets/calendar.lua | 49 ++++++++++++++++++++++++---------------- widgets/contrib/moc.lua | 5 ++++ widgets/contrib/task.lua | 30 +++++++++++++++--------- widgets/fs.lua | 22 ++++++++++-------- widgets/imap.lua | 24 ++++++++++++-------- widgets/mpd.lua | 6 +++++ widgets/weather.lua | 37 ++++++++++++++++++------------ wiki | 2 +- 9 files changed, 116 insertions(+), 65 deletions(-) diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index 5fe74c4..f504cc0 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -15,6 +15,7 @@ local naughty = require("naughty") local io = { popen = io.popen } local math = { modf = math.modf } +local mouse = mouse local string = { format = string.format, match = string.match, rep = string.rep } @@ -75,6 +76,10 @@ function alsabar.notify() .. string.rep(" ", alsabar.notifications.bar_size - int) .. "]" + if alsabar.followmouse then + preset.screen = mouse.screen + end + if alsabar._notify ~= nil then alsabar._notify = naughty.notify ({ replaces_id = alsabar._notify.id, @@ -102,6 +107,7 @@ local function worker(args) alsabar.step = args.step or alsabar.step alsabar.colors = args.colors or alsabar.colors alsabar.notifications = args.notifications or alsabar.notifications + alsabar.followmouse = args.followmouse or false alsabar.bar = awful.widget.progressbar() diff --git a/widgets/calendar.lua b/widgets/calendar.lua index a03503e..2ed26a0 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -14,6 +14,7 @@ local naughty = require("naughty") local io = { popen = io.popen } local os = { date = os.date } +local mouse = mouse local tonumber = tonumber local setmetatable = setmetatable @@ -89,6 +90,12 @@ function calendar:show(t_out, inc_offset, scr) .. "" f:close() + if calendar.followmouse then + local scrp = mouse.screen + else + local scrp = scr or calendar.scr_pos + end + cal_notification = naughty.notify({ text = c_text, icon = calendar.notify_icon, @@ -96,36 +103,38 @@ function calendar:show(t_out, inc_offset, scr) fg = calendar.fg, bg = calendar.bg, timeout = tims, - screen = scr or 1 + screen = scrp }) end function calendar:attach(widget, args) local args = args or {} - calendar.cal = args.cal or "/usr/bin/cal" - calendar.post_cal = args.post_cal or "" - calendar.icons = args.icons or icons_dir .. "cal/white/" - calendar.font = args.font or beautiful.font:sub(beautiful.font:find(""), - beautiful.font:find(" ")) - calendar.font_size = tonumber(args.font_size) or 11 - calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" - calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF" - calendar.position = args.position or "top_right" - calendar.scr_pos = args.scr_pos or mouse.screen - calendar.offset = 0 + calendar.cal = args.cal or "/usr/bin/cal" + calendar.post_cal = args.post_cal or "" + calendar.icons = args.icons or icons_dir .. "cal/white/" + calendar.font = args.font or beautiful.font:sub(beautiful.font:find(""), + beautiful.font:find(" ")) + calendar.font_size = tonumber(args.font_size) or 11 + calendar.fg = args.fg or beautiful.fg_normal or "#FFFFFF" + calendar.bg = args.bg or beautiful.bg_normal or "#FFFFFF" + calendar.position = args.position or "top_right" + calendar.scr_pos = args.scr_pos or 1 + calendar.followmouse = args.followmouse or false + + calendar.offset = 0 calendar.notify_icon = nil widget:connect_signal("mouse::enter", function () calendar:show(0, 0, calendar.scr_pos) end) widget:connect_signal("mouse::leave", function () calendar:hide() end) - widget:buttons(awful.util.table.join( awful.button({ }, 1, function () - calendar:show(0, -1, calendar.scr_pos) end), - awful.button({ }, 3, function () - calendar:show(0, 1, calendar.scr_pos) end), - awful.button({ }, 4, function () - calendar:show(0, -1, calendar.scr_pos) end), - awful.button({ }, 5, function () - calendar:show(0, 1, calendar.scr_pos) end))) + widget:buttons(awful.util.table.join(awful.button({ }, 1, function () + calendar:show(0, -1, calendar.scr_pos) end), + awful.button({ }, 3, function () + calendar:show(0, 1, calendar.scr_pos) end), + awful.button({ }, 4, function () + calendar:show(0, -1, calendar.scr_pos) end), + awful.button({ }, 5, function () + calendar:show(0, 1, calendar.scr_pos) end))) end return setmetatable(calendar, { __call = function(_, ...) return create(...) end }) diff --git a/widgets/contrib/moc.lua b/widgets/contrib/moc.lua index cfdbec7..bd25ffb 100644 --- a/widgets/contrib/moc.lua +++ b/widgets/contrib/moc.lua @@ -29,6 +29,7 @@ local function worker(args) local music_dir = args.music_dir or os.getenv("HOME") .. "/Music" local cover_size = args.cover_size or 100 local default_art = args.default_art or "" + local followmouse = args.followmouse or false local settings = args.settings or function() end local mpdcover = helpers.scripts_dir .. "mpdcover" @@ -82,6 +83,10 @@ local function worker(args) os.execute(string.format("%s %q %q %d %q", mpdcover, "", moc_now.file, cover_size, default_art)) + if followmouse then + moc_notification_preset.screen = mouse.screen + end + moc.id = naughty.notify({ preset = moc_notification_preset, icon = "/tmp/mpdcover.png", diff --git a/widgets/contrib/task.lua b/widgets/contrib/task.lua index 3b8039f..6f131e2 100644 --- a/widgets/contrib/task.lua +++ b/widgets/contrib/task.lua @@ -12,6 +12,7 @@ local awful = require("awful") local beautiful = require("beautiful") local naughty = require("naughty") +local mouse = mouse local io = io local string = { len = string.len } local tonumber = tonumber @@ -36,6 +37,12 @@ function task:show(scr_pos) local f, c_text + if task.followmouse then + local scrp = mouse.screen + else + local scrp = scr_pos or task.scr_pos + end + f = io.popen('task') c_text = " Date: Wed, 29 Jul 2015 16:32:09 +0200 Subject: [PATCH 531/546] #126 fs notification: fixed typo --- widgets/fs.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/fs.lua b/widgets/fs.lua index 0597845..c3a9e18 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -46,7 +46,7 @@ function fs:show(t_out) fs.notification_preset.screen = mouse.screen end - notification = naughty.notify({ + fs_notification = naughty.notify({ preset = fs.notification_preset, text = ws, timeout = t_out From 0594fb0ebdfa65f1a15b820b9690d5802e82ad1b Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 29 Jul 2015 17:15:45 +0200 Subject: [PATCH 532/546] #112: custom echo cmd added --- widgets/mpd.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/widgets/mpd.lua b/widgets/mpd.lua index 642a556..d5f07a8 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -38,11 +38,12 @@ local function worker(args) local cover_size = args.cover_size or 100 local default_art = args.default_art or "" local followmouse = args.followmouse or false + local echo_cmd = args.echo_cmd or "echo" local settings = args.settings or function() end local mpdcover = helpers.scripts_dir .. "mpdcover" local mpdh = "telnet://" .. host .. ":" .. port - local echo = "/bin/echo -e 'password " .. password .. "\nstatus\ncurrentsong\nclose'" + local echo = echo_cmd .. " 'password " .. password .. "\nstatus\ncurrentsong\nclose'" mpd.widget = wibox.widget.textbox('') From e418d9fb86e95043a678c207f0ca212c98341469 Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 29 Jul 2015 17:16:04 +0200 Subject: [PATCH 533/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 1b310ca..cec2ebd 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 1b310ca2f9277d66d285b9ef89e38eb5106535fb +Subproject commit cec2ebd96e91ef3c2a61e6ea9d41f5c44931ee58 From e6f3e74e0c087d10d5b20448b3554cdb8b1f9fce Mon Sep 17 00:00:00 2001 From: luke bonham Date: Wed, 29 Jul 2015 17:35:35 +0200 Subject: [PATCH 534/546] #126 calendar: local scrp fix --- widgets/calendar.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widgets/calendar.lua b/widgets/calendar.lua index 2ed26a0..7e52308 100644 --- a/widgets/calendar.lua +++ b/widgets/calendar.lua @@ -91,9 +91,9 @@ function calendar:show(t_out, inc_offset, scr) f:close() if calendar.followmouse then - local scrp = mouse.screen + scrp = mouse.screen else - local scrp = scr or calendar.scr_pos + scrp = scr or calendar.scr_pos end cal_notification = naughty.notify({ From b0209bd820dd5d8c6a2de893444953490f531de0 Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Wed, 5 Aug 2015 12:28:54 +0200 Subject: [PATCH 535/546] #122 merged --- asyncshell.lua | 105 +++++++++++++++++++--------------------- widgets/abase.lua | 3 +- widgets/contrib/moc.lua | 2 +- widgets/imap.lua | 5 +- widgets/mpd.lua | 2 +- widgets/weather.lua | 8 +-- 6 files changed, 55 insertions(+), 70 deletions(-) diff --git a/asyncshell.lua b/asyncshell.lua index 0aafa17..827cf4b 100644 --- a/asyncshell.lua +++ b/asyncshell.lua @@ -2,78 +2,71 @@ --[[ Licensed under GNU General Public License v2 + * (c) 2015, worron * (c) 2013, Alexander Yakushev --]] -- Asynchronous io.popen for Awesome WM. --- How to use... --- ...asynchronously: --- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end) --- ...synchronously: --- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error") +-- How to use: +-- asyncshell.request('wscript -Kiev', function(output) wwidget.text = output end) -local spawn = require('awful.util').spawn +-- Grab environment +local awful = require('awful') -asyncshell = {} -asyncshell.request_table = {} -asyncshell.id_counter = 0 -asyncshell.folder = "/tmp/asyncshell" -asyncshell.file_template = asyncshell.folder .. '/req' +-- Initialize tables for module +asyncshell = { request_table = {}, id_counter = 0 } --- Create a directory for asynchell response files -os.execute("mkdir -p " .. asyncshell.folder) - --- Returns next tag - unique identifier of the request +-- Request counter local function next_id() - asyncshell.id_counter = (asyncshell.id_counter + 1) % 100000 - return asyncshell.id_counter + asyncshell.id_counter = (asyncshell.id_counter + 1) % 10000 + return asyncshell.id_counter end --- Sends an asynchronous request for an output of the shell command. +-- Remove given request +function asyncshell.clear(id) + if asyncshell.request_table[id] then + if asyncshell.request_table[id].timer then + asyncshell.request_table[id].timer:stop() + asyncshell.request_table[id].timer = nil + end + asyncshell.request_table[id] = nil + end +end + +-- Sends an asynchronous request for an output of the shell command -- @param command Command to be executed and taken output from -- @param callback Function to be called when the command finishes --- @return Request ID -function asyncshell.request(command, callback) - local id = next_id() - local tmpfname = asyncshell.file_template .. id - asyncshell.request_table[id] = { callback = callback } - local req = - string.format("sh -c '%s > %s; " .. - 'echo "asyncshell.deliver(%s)" | ' .. - "awesome-client' 2> /dev/null", - string.gsub(command, "'", "'\\''"), tmpfname, id) - spawn(req, false) - return id +-- @param timeout Maximum amount of time to wait for the result (optional) +function asyncshell.request(command, callback, timeout) + local id = next_id() + asyncshell.request_table[id] = { callback = callback } + + local formatted_command = string.gsub(command, '"','\"') + + local req = string.format( + "echo \"asyncshell.deliver(%s, [[\\\"$(%s)\\\"]])\" | awesome-client &", + id, formatted_command + ) + + awful.util.spawn_with_shell(req) + + if timeout then + asyncshell.request_table[id].timer = timer({ timeout = timeout }) + asyncshell.request_table[id].timer:connect_signal("timeout", function() asyncshell.clear(id) end) + asyncshell.request_table[id].timer:start() + end end --- Calls the remembered callback function on the output of the shell --- command. +-- Calls the remembered callback function on the output of the shell command -- @param id Request ID --- @param output The output file of the shell command to be delievered -function asyncshell.deliver(id) - if asyncshell.request_table[id] and - asyncshell.request_table[id].callback then - local output = io.open(asyncshell.file_template .. id, 'r') - asyncshell.request_table[id].callback(output) - end -end - --- Sends a synchronous request for an output of the command. Waits for --- the output, but if the given timeout expires returns nil. --- @param command Command to be executed and taken output from --- @param timeout Maximum amount of time to wait for the result --- @return File handler on success, nil otherwise -function asyncshell.demand(command, timeout) - local id = next_id() - local tmpfname = asyncshell.file_template .. id - local f = io.popen(string.format("(%s > %s; echo asyncshell_done) & " .. - "(sleep %s; echo asynchell_timeout)", - command, tmpfname, timeout)) - local result = f:read("*line") - if result == "asyncshell_done" then - return io.open(tmpfname) - end +-- @param output Shell command output to be delievered +function asyncshell.deliver(id, output) + local output = string.sub(output, 2, -2) + if asyncshell.request_table[id] then + asyncshell.request_table[id].callback(output) + asyncshell.clear(id) + end end return asyncshell diff --git a/widgets/abase.lua b/widgets/abase.lua index 1c132cd..98f7818 100644 --- a/widgets/abase.lua +++ b/widgets/abase.lua @@ -27,8 +27,7 @@ local function worker(args) function abase.update() async.request(cmd, function(f) - output = f:read("*all") - f:close() + output = f widget = abase.widget settings() end) diff --git a/widgets/contrib/moc.lua b/widgets/contrib/moc.lua index bd25ffb..b818bb6 100644 --- a/widgets/contrib/moc.lua +++ b/widgets/contrib/moc.lua @@ -59,7 +59,7 @@ local function worker(args) total = "N/A" } - for line in f:lines() do + for line in string.gmatch(f, "[^\n]+") do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do if k == "State" then moc_now.state = v elseif k == "File" then moc_now.file = v diff --git a/widgets/imap.lua b/widgets/imap.lua index ec7bd1f..62b33d7 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -64,10 +64,7 @@ local function worker(args) head_command, server, port, mail, password, request) async.request(curl, function(f) - ws = f:read("*all") - f:close() - - _, mailcount = string.gsub(ws, "%d+", "") + _, mailcount = string.gsub(f, "%d+", "") _ = nil widget = imap.widget diff --git a/widgets/mpd.lua b/widgets/mpd.lua index d5f07a8..5af898b 100644 --- a/widgets/mpd.lua +++ b/widgets/mpd.lua @@ -67,7 +67,7 @@ local function worker(args) elapsed = "N/A" } - for line in f:lines() do + for line in string.gmatch(f, "[^\n]+") do for k, v in string.gmatch(line, "([%w]+):[%s](.*)$") do if k == "state" then mpd_now.state = v elseif k == "file" then mpd_now.file = v diff --git a/widgets/weather.lua b/widgets/weather.lua index 741c9dc..fb37a52 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -78,9 +78,7 @@ local function worker(args) function weather.forecast_update() local cmd = string.format(forecast_call, city_id, units, lang, cnt) async.request(cmd, function(f) - j = f:read("*all") - f:close() - weather_now, pos, err = json.decode(j, 1, nil) + weather_now, pos, err = json.decode(f, 1, nil) if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then weather.notification_text = '' @@ -110,9 +108,7 @@ local function worker(args) function weather.update() local cmd = string.format(current_call, city_id, units, lang) async.request(cmd, function(f) - j = f:read("*all") - f:close() - weather_now, pos, err = json.decode(j, 1, nil) + weather_now, pos, err = json.decode(f, 1, nil) if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then weather.icon_path = icons_path .. weather_now["weather"][1]["icon"] .. ".png" From 04e310cb3d28037afa4a1a44324faafcb2b54b28 Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Sat, 8 Aug 2015 19:34:51 +0200 Subject: [PATCH 536/546] readme updated --- LICENSE | 352 ----------------------------------------------------- README.rst | 4 +- 2 files changed, 2 insertions(+), 354 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 716f177..0000000 --- a/LICENSE +++ /dev/null @@ -1,352 +0,0 @@ -<<<<<<< HEAD - GNU GENERAL PUBLIC LICENSE -======= -GNU GENERAL PUBLIC LICENSE ->>>>>>> 32a5f32... Initial commit - 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. - -<<<<<<< HEAD - - Copyright (C) -======= - Next generation Vain - Copyright (C) 2013 Luke Bonham ->>>>>>> 32a5f32... Initial commit - - 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. - -<<<<<<< HEAD - , 1 April 1989 -======= - {signature of Ty Coon}, 1 April 1989 ->>>>>>> 32a5f32... Initial commit - 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/README.rst b/README.rst index a06b64e..be3e377 100644 --- a/README.rst +++ b/README.rst @@ -7,7 +7,7 @@ Layouts, widgets and utilities for Awesome WM 3.5+ :Author: Luke Bonham :Version: git -:License: GNU-GPLv2_ +:License: GNU-GPL2_ :Source: https://github.com/copycat-killer/lain Description @@ -41,7 +41,7 @@ Screenshots .. image:: http://i.imgur.com/9Iv3OR3.png .. image:: http://i.imgur.com/STCPcaJ.png -.. _GNU-GPLv2: http://www.gnu.org/licenses/gpl-2.0.html +.. _GNU-GPL2: http://www.gnu.org/licenses/gpl-2.0.html .. _awesome-vain: https://github.com/vain/awesome-vain .. _Awesome: http://awesome.naquadah.org/ .. _wiki: https://github.com/copycat-killer/lain/wiki From 945f220e022e69c1aeda0ee86558be26f19bdd40 Mon Sep 17 00:00:00 2001 From: Dario Gjorgjevski Date: Thu, 13 Aug 2015 01:07:32 +0200 Subject: [PATCH 537/546] add new widget (kbdlayout.lua) --- widgets/contrib/kbdlayout.lua | 58 +++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 widgets/contrib/kbdlayout.lua diff --git a/widgets/contrib/kbdlayout.lua b/widgets/contrib/kbdlayout.lua new file mode 100644 index 0000000..c5242c1 --- /dev/null +++ b/widgets/contrib/kbdlayout.lua @@ -0,0 +1,58 @@ + +local newtimer = require("lain.helpers").newtimer +local wibox = require("wibox") + +local string = { match = string.match } +local io = { popen = io.popen } + +local setmetatable = setmetatable + +local function worker (args) + local kbdlayout = {} + kbdlayout.widget = wibox.widget.textbox('') + + local settings = args.settings or function () end + local layouts = args.layouts + local idx = 1 + + local function run_settings (layout, variant) + widget = kbdlayout.widget + kbdlayout_now = { layout=layout, variant=variant } + settings() + end + + function kbdlayout.update () + local file = assert(io.popen('setxkbmap -query')) + local status = file:read('*all') + file:close() + + run_settings(string.match(status, "layout:%s*([^\n]*)%s*"), + string.match(status, "variant:%s*([^\n]*)%s*")) + end + + function kbdlayout.set (i) + idx = ((i - 1) % #layouts) + 1 -- Make sure to wrap around as needed. + local to_execute = 'setxkbmap ' .. layouts[idx].layout + + if layouts[idx].variant then + to_execute = to_execute .. ' ' .. layouts[idx].variant + end + + if os.execute(to_execute) then + run_settings(layouts[idx].layout, layouts[idx].variant) + end + end + + function kbdlayout.next () + kbdlayout.set(idx + 1) + end + + function kbdlayout.prev () + kbdlayout.set(idx - 1) + end + + newtimer("kbdlayout", args.timeout or 10, kbdlayout.update) + return setmetatable(kbdlayout, { __index = kbdlayout.widget }) +end + +return setmetatable({}, { __call = function (_, ...) return worker(...) end }) From 6603c641c6ce675b010ca1977423747ca55d8795 Mon Sep 17 00:00:00 2001 From: Dario Gjorgjevski Date: Thu, 13 Aug 2015 01:56:37 +0200 Subject: [PATCH 538/546] abstract out reading full output of pipes --- helpers.lua | 15 ++++++++++++++- widgets/alsa.lua | 6 ++---- widgets/alsabar.lua | 6 ++---- widgets/base.lua | 7 +++---- widgets/contrib/kbdlayout.lua | 32 ++++++++++++++++++++++---------- widgets/fs.lua | 4 +--- widgets/imap.lua | 4 +--- widgets/maildir.lua | 8 ++++---- widgets/net.lua | 5 +---- widgets/weather.lua | 7 ++++--- 10 files changed, 54 insertions(+), 40 deletions(-) diff --git a/helpers.lua b/helpers.lua index dbee617..4e90e16 100644 --- a/helpers.lua +++ b/helpers.lua @@ -10,7 +10,8 @@ local debug = require("debug") local capi = { timer = timer } local io = { open = io.open, - lines = io.lines } + lines = io.lines, + popen = io.popen } local rawget = rawget -- Lain helper functions for internal use @@ -86,6 +87,18 @@ end -- }}} +-- {{{ Pipe operations + +-- read the full output of a pipe (command) +function helpers.read_pipe(cmd) + local f = assert(io.popen(cmd)) + local output = f:read("*all") + f:close() + return output +end + +-- }}} + -- {{{ A map utility helpers.map_table = {} diff --git a/widgets/alsa.lua b/widgets/alsa.lua index 91bf488..85d5311 100644 --- a/widgets/alsa.lua +++ b/widgets/alsa.lua @@ -8,10 +8,10 @@ --]] local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe local wibox = require("wibox") -local io = { popen = io.popen } local string = { match = string.match, format = string.format } @@ -32,9 +32,7 @@ local function worker(args) alsa.widget = wibox.widget.textbox('') function alsa.update() - local f = assert(io.popen(string.format("%s get %s", alsa.cmd, alsa.channel))) - local mixer = f:read("*all") - f:close() + local mixer = read_pipe(string.format("%s get %s", alsa.cmd, alsa.channel)) volume_now = {} diff --git a/widgets/alsabar.lua b/widgets/alsabar.lua index f504cc0..c7498d2 100644 --- a/widgets/alsabar.lua +++ b/widgets/alsabar.lua @@ -8,12 +8,12 @@ --]] local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe local awful = require("awful") local beautiful = require("beautiful") local naughty = require("naughty") -local io = { popen = io.popen } local math = { modf = math.modf } local mouse = mouse local string = { format = string.format, @@ -122,9 +122,7 @@ local function worker(args) function alsabar.update() -- Get mixer control contents - local f = assert(io.popen(string.format("%s get %s", alsabar.cmd, alsabar.channel))) - local mixer = f:read("*all") - f:close() + local mixer = read_pipe(string.format("%s get %s", alsabar.cmd, alsabar.channel)) -- Capture mixer control state: [5%] ... ... [on] local volu, mute = string.match(mixer, "([%d]+)%%.*%[([%l]*)") diff --git a/widgets/base.lua b/widgets/base.lua index 2a7bf10..2f377f7 100644 --- a/widgets/base.lua +++ b/widgets/base.lua @@ -7,9 +7,10 @@ --]] local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe + local wibox = require("wibox") -local io = { popen = io.popen } local setmetatable = setmetatable -- Basic template for custom widgets @@ -25,9 +26,7 @@ local function worker(args) base.widget = wibox.widget.textbox('') function base.update() - local f = assert(io.popen(cmd)) - output = f:read("*all") - f:close() + output = read_pipe(cmd) widget = base.widget settings() end diff --git a/widgets/contrib/kbdlayout.lua b/widgets/contrib/kbdlayout.lua index c5242c1..8d13a74 100644 --- a/widgets/contrib/kbdlayout.lua +++ b/widgets/contrib/kbdlayout.lua @@ -1,9 +1,17 @@ +--[[ + + Licensed under GNU General Public License v2 + * (c) 2015, Dario Gjorgjevski + +--]] + local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe + local wibox = require("wibox") local string = { match = string.match } -local io = { popen = io.popen } local setmetatable = setmetatable @@ -11,29 +19,33 @@ local function worker (args) local kbdlayout = {} kbdlayout.widget = wibox.widget.textbox('') - local settings = args.settings or function () end - local layouts = args.layouts - local idx = 1 + local layouts = args.layouts + local settings = args.settings or function () end + local add_us_secondary = args.add_us_secondary or true + local idx = 1 local function run_settings (layout, variant) widget = kbdlayout.widget - kbdlayout_now = { layout=layout, variant=variant } + kbdlayout_now = { layout=string.match(layout, "[^,]+"), -- Make sure to match the primary layout only. + variant=variant } settings() end function kbdlayout.update () - local file = assert(io.popen('setxkbmap -query')) - local status = file:read('*all') - file:close() + local status = read_pipe('setxkbmap -query') - run_settings(string.match(status, "layout:%s*([^\n]*)%s*"), - string.match(status, "variant:%s*([^\n]*)%s*")) + run_settings(string.match(status, "layout:%s*([^\n]*)"), + string.match(status, "variant:%s*([^\n]*)")) end function kbdlayout.set (i) idx = ((i - 1) % #layouts) + 1 -- Make sure to wrap around as needed. local to_execute = 'setxkbmap ' .. layouts[idx].layout + if add_us_secondary then + to_execute = to_execute .. ",us" + end + if layouts[idx].variant then to_execute = to_execute .. ' ' .. layouts[idx].variant end diff --git a/widgets/fs.lua b/widgets/fs.lua index c3a9e18..a01d3cf 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -38,9 +38,7 @@ end function fs:show(t_out) fs:hide() - local f = io.popen(helpers.scripts_dir .. "dfs") - ws = f:read("*all"):gsub("\n*$", "") - f:close() + ws = helpers.read_pipe(helpers.scripts_dir .. "dfs"):gsub("\n*$", "") if fs.followmouse then fs.notification_preset.screen = mouse.screen diff --git a/widgets/imap.lua b/widgets/imap.lua index 62b33d7..ea763df 100644 --- a/widgets/imap.lua +++ b/widgets/imap.lua @@ -43,9 +43,7 @@ local function worker(args) if not is_plain then - local f = io.popen(password) - password = f:read("*all"):gsub("\n", "") - f:close() + password = helpers.read_pipe(password):gsub("\n", "") end imap.widget = wibox.widget.textbox('') diff --git a/widgets/maildir.lua b/widgets/maildir.lua index 315ae34..cb96a30 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -8,12 +8,12 @@ --]] local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe local wibox = require("wibox") local util = require("lain.util") -local io = { popen = io.popen } local os = { getenv = os.getenv } local pairs = pairs local string = { len = string.len, @@ -50,10 +50,9 @@ local function worker(args) -- match files that begin with a dot. -- Afterwards the length of this string is the number of -- new mails in that box. - local np = io.popen("find " .. line .. + local mailstring = read_pipe("find " .. line .. "/new -mindepth 1 -type f " .. "-not -name '.*' -printf a") - local mailstring = np:read("*all") -- Strip off leading mailpath. local box = string.match(line, mailpath .. "/*([^/]+)") @@ -65,10 +64,11 @@ local function worker(args) end until line == nil + p:close() table.sort(boxes) newmail = "no mail" - --Count the total number of mails irrespective of where it was found + -- Count the total number of mails irrespective of where it was found total = 0 for box, number in pairs(boxes) diff --git a/widgets/net.lua b/widgets/net.lua index d859d91..a578ae4 100644 --- a/widgets/net.lua +++ b/widgets/net.lua @@ -13,7 +13,6 @@ local notify_fg = require("beautiful").fg_focus local naughty = require("naughty") local wibox = require("wibox") -local io = { popen = io.popen } local string = { format = string.format, gsub = string.gsub, match = string.match } @@ -28,9 +27,7 @@ local net = { } function net.get_device() - f = io.popen("ip link show | cut -d' ' -f2,9") - ws = f:read("*all") - f:close() + local ws = helpers.read_pipe("ip link show | cut -d' ' -f2,9") ws = ws:match("%w+: UP") or ws:match("ppp%w+: UNKNOWN") if ws ~= nil then return ws:match("(%w+):") diff --git a/widgets/weather.lua b/widgets/weather.lua index fb37a52..8a0d751 100644 --- a/widgets/weather.lua +++ b/widgets/weather.lua @@ -7,9 +7,12 @@ --]] local newtimer = require("lain.helpers").newtimer +local read_pipe = require("lain.helpers").read_pipe + local async = require("lain.asyncshell") local json = require("lain.util").dkjson local lain_icons = require("lain.helpers").icons_dir + local naughty = require("naughty") local wibox = require("wibox") @@ -83,9 +86,7 @@ local function worker(args) if not err and weather_now ~= nil and tonumber(weather_now["cod"]) == 200 then weather.notification_text = '' for i = 1, weather_now["cnt"] do - local f = assert(io.popen(string.format(date_cmd, weather_now["list"][i]["dt"]))) - day = string.gsub(f:read("*all"), "\n", "") - f:close() + day = string.gsub(read_pipe(string.format(date_cmd, weather_now["list"][i]["dt"])), "\n", "") tmin = math.floor(weather_now["list"][i]["temp"]["min"]) tmax = math.floor(weather_now["list"][i]["temp"]["max"]) From 9223ddfb10e77e932d3e462f6c734528e665290a Mon Sep 17 00:00:00 2001 From: Dario Gjorgjevski Date: Thu, 13 Aug 2015 02:05:49 +0200 Subject: [PATCH 539/546] add mouse bindings to kbdlayout --- widgets/contrib/kbdlayout.lua | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/widgets/contrib/kbdlayout.lua b/widgets/contrib/kbdlayout.lua index 8d13a74..1c24647 100644 --- a/widgets/contrib/kbdlayout.lua +++ b/widgets/contrib/kbdlayout.lua @@ -10,6 +10,7 @@ local newtimer = require("lain.helpers").newtimer local read_pipe = require("lain.helpers").read_pipe local wibox = require("wibox") +local awful = require("awful") local string = { match = string.match } @@ -22,7 +23,14 @@ local function worker (args) local layouts = args.layouts local settings = args.settings or function () end local add_us_secondary = args.add_us_secondary or true + local timeout = args.timeout or 5 + local idx = 1 + + -- Mouse bindings + kbdlayout.widget:buttons(awful.util.table.join( + awful.button({ }, 1, function () kbdlayout.next() end), + awful.button({ }, 3, function () kbdlayout.prev() end))) local function run_settings (layout, variant) widget = kbdlayout.widget @@ -63,7 +71,7 @@ local function worker (args) kbdlayout.set(idx - 1) end - newtimer("kbdlayout", args.timeout or 10, kbdlayout.update) + newtimer("kbdlayout", timeout, kbdlayout.update) return setmetatable(kbdlayout, { __index = kbdlayout.widget }) end From edac7419fa0f8c849b055a08cc1a58e61c8980d3 Mon Sep 17 00:00:00 2001 From: Dario Gjorgjevski Date: Thu, 13 Aug 2015 02:11:24 +0200 Subject: [PATCH 540/546] add 'local' modifier as appropriate --- widgets/fs.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/fs.lua b/widgets/fs.lua index a01d3cf..a1d5d95 100644 --- a/widgets/fs.lua +++ b/widgets/fs.lua @@ -38,7 +38,7 @@ end function fs:show(t_out) fs:hide() - ws = helpers.read_pipe(helpers.scripts_dir .. "dfs"):gsub("\n*$", "") + local ws = helpers.read_pipe(helpers.scripts_dir .. "dfs"):gsub("\n*$", "") if fs.followmouse then fs.notification_preset.screen = mouse.screen From 9358f8ac54a20f2351e4e4b7c45735f2388c3c42 Mon Sep 17 00:00:00 2001 From: Dario Gjorgjevski Date: Thu, 13 Aug 2015 02:16:34 +0200 Subject: [PATCH 541/546] bring back mistaken deletion --- widgets/maildir.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/widgets/maildir.lua b/widgets/maildir.lua index cb96a30..eed6138 100644 --- a/widgets/maildir.lua +++ b/widgets/maildir.lua @@ -14,6 +14,7 @@ local wibox = require("wibox") local util = require("lain.util") +local io = { popen = io.popen } local os = { getenv = os.getenv } local pairs = pairs local string = { len = string.len, From 390203892a05a2bd9e08cb37621637263e4ac8c1 Mon Sep 17 00:00:00 2001 From: Dario Gjorgjevski Date: Fri, 14 Aug 2015 00:31:05 +0200 Subject: [PATCH 542/546] update wiki --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index cec2ebd..268a2cd 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit cec2ebd96e91ef3c2a61e6ea9d41f5c44931ee58 +Subproject commit 268a2cd3867d890616d6326472372e7168276927 From 75c3b81654b5159dbad6123e51838d8c3a34e3bd Mon Sep 17 00:00:00 2001 From: Dario Gjorgjevski Date: Sun, 16 Aug 2015 05:36:09 +0200 Subject: [PATCH 543/546] fix trailing whitespace and mixed indent --- widgets/contrib/kbdlayout.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/widgets/contrib/kbdlayout.lua b/widgets/contrib/kbdlayout.lua index 1c24647..8b15475 100644 --- a/widgets/contrib/kbdlayout.lua +++ b/widgets/contrib/kbdlayout.lua @@ -1,7 +1,7 @@ --[[ - Licensed under GNU General Public License v2 + Licensed under GNU General Public License v2 * (c) 2015, Dario Gjorgjevski --]] @@ -24,26 +24,26 @@ local function worker (args) local settings = args.settings or function () end local add_us_secondary = args.add_us_secondary or true local timeout = args.timeout or 5 - + local idx = 1 -- Mouse bindings kbdlayout.widget:buttons(awful.util.table.join( - awful.button({ }, 1, function () kbdlayout.next() end), - awful.button({ }, 3, function () kbdlayout.prev() end))) - + awful.button({ }, 1, function () kbdlayout.next() end), + awful.button({ }, 3, function () kbdlayout.prev() end))) + local function run_settings (layout, variant) widget = kbdlayout.widget kbdlayout_now = { layout=string.match(layout, "[^,]+"), -- Make sure to match the primary layout only. variant=variant } settings() end - + function kbdlayout.update () local status = read_pipe('setxkbmap -query') run_settings(string.match(status, "layout:%s*([^\n]*)"), - string.match(status, "variant:%s*([^\n]*)")) + string.match(status, "variant:%s*([^\n]*)")) end function kbdlayout.set (i) @@ -51,15 +51,15 @@ local function worker (args) local to_execute = 'setxkbmap ' .. layouts[idx].layout if add_us_secondary then - to_execute = to_execute .. ",us" + to_execute = to_execute .. ",us" end if layouts[idx].variant then - to_execute = to_execute .. ' ' .. layouts[idx].variant + to_execute = to_execute .. ' ' .. layouts[idx].variant end if os.execute(to_execute) then - run_settings(layouts[idx].layout, layouts[idx].variant) + run_settings(layouts[idx].layout, layouts[idx].variant) end end From 5f643320f36d201df94ee56303b0504afd695697 Mon Sep 17 00:00:00 2001 From: Dario Gjorgjevski Date: Sun, 16 Aug 2015 05:42:18 +0200 Subject: [PATCH 544/546] do not add `us' as secondary if already present --- widgets/contrib/kbdlayout.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widgets/contrib/kbdlayout.lua b/widgets/contrib/kbdlayout.lua index 8b15475..f9342a0 100644 --- a/widgets/contrib/kbdlayout.lua +++ b/widgets/contrib/kbdlayout.lua @@ -50,7 +50,7 @@ local function worker (args) idx = ((i - 1) % #layouts) + 1 -- Make sure to wrap around as needed. local to_execute = 'setxkbmap ' .. layouts[idx].layout - if add_us_secondary then + if add_us_secondary and not string.match(layouts[idx].layout, ",?us,?") then to_execute = to_execute .. ",us" end From 6db29e08b3c34ef78f9b674c2ca36b6785193759 Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Sun, 16 Aug 2015 13:54:04 +0200 Subject: [PATCH 545/546] wiki updated --- widgets/contrib/init.lua | 2 +- widgets/contrib/kbdlayout.lua | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/widgets/contrib/init.lua b/widgets/contrib/init.lua index ccaed82..eb5d610 100644 --- a/widgets/contrib/init.lua +++ b/widgets/contrib/init.lua @@ -7,7 +7,7 @@ Users contributed widgets section Licensed under GNU General Public License v2 - * (c) 2013, Luke Bonham + * (c) 2013, Luke Bonham --]] diff --git a/widgets/contrib/kbdlayout.lua b/widgets/contrib/kbdlayout.lua index f9342a0..f8164ce 100644 --- a/widgets/contrib/kbdlayout.lua +++ b/widgets/contrib/kbdlayout.lua @@ -1,9 +1,9 @@ --[[ - - Licensed under GNU General Public License v2 - * (c) 2015, Dario Gjorgjevski - + + Licensed under GNU General Public License v2 + * (c) 2015, Dario Gjorgjevski + --]] local newtimer = require("lain.helpers").newtimer From 592ae95bd2393a707648d10dba67eaa772cb8328 Mon Sep 17 00:00:00 2001 From: copycat-killer Date: Sun, 16 Aug 2015 13:58:52 +0200 Subject: [PATCH 546/546] wiki updated --- wiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiki b/wiki index 268a2cd..e21f7dd 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 268a2cd3867d890616d6326472372e7168276927 +Subproject commit e21f7ddbdd05019501136a7cca1ac6c897eae2ce