kdocker-4.6/000755 000765 000024 00000000000 11570604624 013113 5ustar00johnstaff000000 000000 kdocker-4.6/AUTHORS000644 000765 000024 00000000232 11570604611 014154 0ustar00johnstaff000000 000000 John Schember (john@nachtimwald.com) - Active developer and maintainer Girish Ramakrishnan - Original creator. He is not an active member of the project. kdocker-4.6/BUGS000644 000765 000024 00000000217 11570604611 013572 0ustar00johnstaff000000 000000 Bugs and wishes to https://bugs.launchpad.net/kdocker Known issues: --- * Robust error reporting from 1.x have not been implemented in 4.x. kdocker-4.6/ChangeLog000644 000765 000024 00000013173 11570604611 014666 0ustar00johnstaff000000 000000 for version 4.6 - Fix bug with windows not showing after being restored when KWin is the WM. - Fix bug with restored windows not gaining focus when KWin is the WM. for version 4.5 - Change -n option behavior: - -n now acts as -n -y. - Name matching now matches any running application. Previously it would only match when launching an application. - Remove -y option. - Change a number of casts from C style to C++ style. for version 4.4 - Remove window manager decoration close button can optionally iconify. It ended up causing many issues. Fixes: - Drag and drop. - Moving borderless windows (chrome). - Windows moving slightly when undocking. - Focus bug (#600045). - Remove -c option. - Add help text for -i option. - Update INSTALL. - Default install path is now /usr instead of /usr/local. for version 4.3 - Use QtSingleApplication. - Window manager decoration close button can optionally iconify. - Changed command line option -c: Disables WM close button iconify. - Restructure large parts of the appplication. for version 4.2.2 - Fix installing translation files. for version 4.2.1 - Fix type in .pro file that prevents all files from installing. for version 4.2 - Fix disabling balloon title changes menu option. - Ignore docked windows and continue looking when matching command by name and when matching by specified pid. - Bash completion - Italian Translation thanks to Alessio Cassibba - Change behavior of tray activation. Raise window when not active, and iconify when active. - Change to the desktop the window was last on when restoring. Only works with WMs that support _NET_CURRENT_DESKTOP. - Iconify when focus lost. for version 4.1 - Fix bug 431297: Fall back to window title and class name when launching if pid becomes invalid. Allows commands that detach and get a new pid (rox) to dock correctly. - New command line option -n: Specify the string to use for fall back when launching a command and a pid match cannot be determined. - New command line option -y: Force matching command by title and class name. - New command line option -x: Specify PID of application to dock. - Fix a bug that prevented the time out for trying to dock and launched command from increasing. - Menu item for setting the tray icon. - Fix bug: Do not quit when closing docked application from tray menu. for version 4.0 - 4.0 rewrite complete. for version 4.0-preview-1 - Preview release of Qt 4 port. for version 1.3 - Fix bug when reading back balloon timeout on session restoration - AutoLaunch enhancement (Request user to provide program name when autodetection failed) - Indonesian translations from Eko Prasetiyo - Italian translations from Alessio Cassibba - Updated Brazilian Portuguese and polish translations for version 1.2 - Polish translations from KonMan - Check WM_NAME to support programs like LimeWire (for lavacube) - Store entire application path as part of session - Move around command line handling code - Configure balloon timeout using "-p" (for roopesh) for version 1.1 - German translations from Thomas Runge - Dialog detection bug. I replaced all LOG with TRACE (Thanks to Novoselic who raised a question which helped me notice it) - -v Displays the version - -b Suppress the warning when docking non-normal dialogs (For John Pettigrew) - Fix issue when passing large command line to previous instance (Reported by Arseniy Akopyan) for version 1.0 CR1 - Russian translations by Aleksey Kirpichnikov - Brazilian Portugese translations by Paulo Ruthes for version 1.0 - Spanish translations are back in (Thanks Edulix) - Yet another fix for xmms for version 1.0 rc2 - "make install" support (with QMake) - Multiple desktop awareness (for Sharon) - Icons from Marcel Dierkes - Use XDND type mechanism to pass arguments to previous instance - Spanish translations are out. - Czech translations by Jiri Hofman - Drag and drop support for Antonio C. Censi - Xmms+PlayList fix (for KDE) for version 1.0 rc1 - Session Management support (XSMP) for KDE and GNOME - AutoLaunch application support that do not support Session Management - Wait until system tray comes up on session restoration (Requested by Normen) - Fix GNOME docked icon resize issue - Track tray label appearance and disappearance handling - Major code refactoring. QTrayLabel is now a very reusable class for version 0.9 - Support to dock the active window (useful with keyboard shortcuts) -f Was requested by Daniel - Small security fix - ToolTip positioning issue (reported by Alex) - CLI Support to disabling ballooning of title changes. -q (requested by Marcel Dierkes) - French Translations (Thanks to Al) for version 0.8 - Custom Icons. Accessible through menu or CLI - Fixes for KDE (ObscureEvent, BringToFront, SkippingTaskbar) - Code refactoring - Changes to have only a single instance of KDocker running all the time! for version 0.7 - Use WM_COMMAND to identify windows - Warn when attemping to dock non-normal windows - Issue with tool tips fixed for version 0.6 - Start up applications - CLI support - Spanish Translation and i18n support for version 0.5 - Support to remember the position - Support to close application - Support to remove application from the task bar for version 0.4 - Add dock on obscure - Add dock on minimise kdocker-4.6/COPYING000644 000765 000024 00000043110 11570604611 014141 0ustar00johnstaff000000 000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General Public License instead of this License. kdocker-4.6/CREDITS000644 000765 000024 00000001645 11570604611 014135 0ustar00johnstaff000000 000000 Code ---- Maintained by John Schember (john@nachtimwald.com) Originally created by Girish Ramakrishnan. He is not an active member of the project. Artwork ------- KDocker Icon by Marcel Dierkes (marcel dot dierkes at gmx dot de) 4.x Translations ------------ Italian - Alessio Cassibba (x-drum@zerodev.it) 1.3 Translations ------------ Spanish translations by Edulix (edulix at tumundoweb dot com) French translations by Al (altrash at altern &dot& org) Czech translations by Jiri Hofman (jiri dot hofman # a.t # tut*fi) Russian translations by Aleksey Kirpichnikov (coder *at* paco dot net) Brazilian Portugese by Paulo Ruthes (paulo.ruthes $at$ $uol$ com dot br) German translations by Thomas Runge (thomas dot r3 at gmx dot de) Polish translation by KonMan (dedalus !at o2 dot pl) Indonesian translation by Eko Prasetiyo (e hiphen prast at spymac dot com) Italian translations by Alessio Cassibba (swapon at gmail dot com) kdocker-4.6/helpers/000755 000765 000024 00000000000 11570604611 014551 5ustar00johnstaff000000 000000 kdocker-4.6/i18n/000755 000765 000024 00000000000 11570604611 013666 5ustar00johnstaff000000 000000 kdocker-4.6/INSTALL000644 000765 000024 00000001010 11570604611 014130 0ustar00johnstaff000000 000000 Prerequisites 1. Make sure you have Qt 4 installed and working. If you dont know what Qt is, go to http://qt.nokia.com/products/. You will need qmake to compile. Building 1. edit kdocker.pro if necessary. It should be ready to go with no change. 2. qmake 3. make 4. run "make install" (optional) 5. While making shortcuts, use the icons in /usr/share/kdocker/icons. Please see README for tips and general information IMPORTANT: Kill all previous instances of KDocker that are running before trying out this version kdocker-4.6/kdocker.pro000644 000765 000024 00000003361 11570604611 015256 0ustar00johnstaff000000 000000 TEMPLATE = app CONFIG += qt TARGET = kdocker include(solutions/qtsingleapplication/qtsingleapplication.pri) DEPENDPATH += src INCLUDEPATH += . src /usr/include/X11 QMAKE_LIBDIR += /usr/X11/lib LIBS = -lX11 -lXpm -lXmu INSTALL_PATH = /usr/share/kdocker TRANSLATIONS += i18n/kdocker_it_IT.ts isEmpty(QMAKE_LRELEASE) { QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease !exists($$QMAKE_LRELEASE) { QMAKE_LRELEASE = lrelease-qt4 } } updateqm.input = TRANSLATIONS updateqm.output = build/i18n/${QMAKE_FILE_BASE}.qm updateqm.commands = $$QMAKE_LRELEASE -silent ${QMAKE_FILE_IN} -qm build/i18n/${QMAKE_FILE_BASE}.qm updateqm.CONFIG += no_link target_predeps QMAKE_EXTRA_COMPILERS += updateqm TRANSLATIONS_PATH = $$INSTALL_PATH DEFINES += TRANSLATIONS_PATH=\\\"$${TRANSLATIONS_PATH}/i18n\\\" translations.path = $$TRANSLATIONS_PATH translations.files = build/i18n ICONS_PATH = $$INSTALL_PATH/icons icons.path = $$ICONS_PATH icons.files = resources/images/kdocker.png desktop.path = /usr/share/applications desktop.files = helpers/kdocker.desktop completion.path = /etc/bash_completion.d completion.files = helpers/kdocker target.path = /usr/bin INSTALLS += target icons desktop completion translations # Input HEADERS += src/application.h \ src/constants.h \ src/kdocker.h \ src/scanner.h \ src/trayitem.h \ src/trayitemmanager.h \ src/xlibutil.h SOURCES += src/application.cpp \ src/constants.cpp \ src/kdocker.cpp \ src/main.cpp \ src/scanner.cpp \ src/trayitem.cpp \ src/trayitemmanager.cpp \ src/xlibutil.cpp RESOURCES += resources/resources.qrc # Output MOC_DIR = build OBJECTS_DIR = build RCC_DIR = build DESTDIR = . kdocker-4.6/README000644 000765 000024 00000003251 11570604611 013770 0ustar00johnstaff000000 000000 KDocker ------- KDocker will help you dock any application in the system tray. This means you can dock openoffice, xmms, firefox, thunderbolt, eclipse, anything! Just point and click. Works for both KDE and GNOME (In fact it should work for most modern window managers that support NET WM Specification. I believe it works for XFCE, for instance) All you need to do is start KDocker and select an application using the mouse and lo! the application gets docked into the system tray. The application can also be made to dissappear from the task bar. System Tray Support ------------------- KDocker supports the System Tray Protocol from freedesktop.org Tips to use KDocker ------------------- 1. On KDE, right click on K menu and use the menu editor to create a link of KDocker and create a shortcut (Windows key + Z). You could use the kdocker.xpm in the src folder as the icon (its an anchor). Rationale: ^Z on the shell puts processes in the background. On the same lines, Windows+Z will help you put windows app to the background ;) (thanks to Thomas McGuire for this suggestion) 2. With KDocker 0.9, there is an option to dock the current active window (-f). As soon as you press WinKey+Z, the window which has the focus will be automatically docked. Thanks to Daniel for this neat feature request. Reporting Bugs -------------- Bugs and wishes to https://bugs.launchpad.net/kdocker Send Girish a postcard! ------------------- If you love KDocker and would like to thank Girish for starting this wonderful project, send him a postcard or some stamps to Girish Ramakrishnan G7, Block No.12, R.K.Apartments, Hoysala Nagar, Bangalore, Karnataka, India https://launchpad.net/kdocker for updates kdocker-4.6/resources/000755 000765 000024 00000000000 11570604611 015121 5ustar00johnstaff000000 000000 kdocker-4.6/solutions/000755 000765 000024 00000000000 11570604611 015146 5ustar00johnstaff000000 000000 kdocker-4.6/src/000755 000765 000024 00000000000 11570604611 013676 5ustar00johnstaff000000 000000 kdocker-4.6/TODO000644 000765 000024 00000000111 11570604611 013570 0ustar00johnstaff000000 000000 Bugs and wishes to https://bugs.launchpad.net/kdocker 1. Translations. kdocker-4.6/VERSION000644 000765 000024 00000000005 11570604611 014152 0ustar00johnstaff000000 000000 4.6 kdocker-4.6/src/application.cpp000644 000765 000024 00000002376 11570604611 016715 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include "application.h" Application::Application(const QString &appId, int &argc, char **argv) : QtSingleApplication(appId, argc, argv) { m_kdocker = 0; } void Application::setKDockerInstance(KDocker *kdocker) { m_kdocker = kdocker; } bool Application::x11EventFilter(XEvent *event) { if (m_kdocker) { return m_kdocker->x11EventFilter(event); } return false; } void Application::close() { if (m_kdocker) { m_kdocker->undockAll(); } quit(); } kdocker-4.6/src/application.h000644 000765 000024 00000002246 11570604611 016356 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #ifndef _APPLICATION_H #define _APPLICATION_H #include #include "kdocker.h" class Application : public QtSingleApplication { Q_OBJECT public: Application(const QString &appId, int &argc, char **argv); void setKDockerInstance(KDocker *kdocker); bool x11EventFilter(XEvent *event); void close(); private: KDocker *m_kdocker; }; #endif /* _APPLICATION_H */ kdocker-4.6/src/constants.cpp000644 000765 000024 00000002735 11570604611 016425 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include "constants.h" const QString Constants::ORG_NAME = "net.launchpad.kdocker"; const QString Constants::DOM_NAME = "launchpad.net/kdocker"; const QString Constants::APP_NAME = "KDocker"; const QString Constants::APP_VERSION = "4.6"; const char *Constants::OPTIONSTRING = "+abd:fhi:lmn:op:qrstvuw:x:"; const QString Constants::ABOUT_MESSAGE = tr("KDocker will help you dock any application into the system tray. This means you can dock openoffice, xmms, firefox, thunderbird, anything! Just point and click. Works for all NET WM compliant window managers - that includes KDE, GNOME, Xfce, Fluxbox and many more.\n\nCreated by %1. Updated and maintained by %2.").arg("Girish Ramakrishnan").arg("John Schember"); kdocker-4.6/src/constants.h000644 000765 000024 00000002217 11570604611 016065 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #ifndef _CONSTANTS_H #define _CONSTANTS_H #include #include class Constants : QObject { Q_OBJECT public: static const QString ORG_NAME; static const QString DOM_NAME; static const QString APP_NAME; static const QString APP_VERSION; static const char *OPTIONSTRING; static const QString ABOUT_MESSAGE; }; #endif /* _CONSTANTS_H */ kdocker-4.6/src/kdocker.cpp000644 000765 000024 00000012732 11570604611 016031 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include #include #include "constants.h" #include "kdocker.h" #include "trayitemmanager.h" #include #include KDocker::KDocker() { m_trayItemManager = new TrayItemManager(); } KDocker::~KDocker() { if (m_trayItemManager) { delete m_trayItemManager; m_trayItemManager = 0; } } void KDocker::undockAll() { if (m_trayItemManager) { m_trayItemManager->undockAll(); } } bool KDocker::x11EventFilter(XEvent *ev) { if (m_trayItemManager) { return m_trayItemManager->x11EventFilter(ev); } return false; } void KDocker::run() { if (m_trayItemManager) { m_trayItemManager->processCommand(QCoreApplication::arguments()); } } void KDocker::handleMessage(const QString &args) { if (m_trayItemManager) { m_trayItemManager->processCommand(args.split("\n")); } } /* * handle arguments that output information to the user. We want to handle * them here so they are printed on the tty that the application is run from. * If we left it up to TrayItemManager with the rest of the arguments these * would be printed on the tty the instace was started on not the instance the * user is calling from. */ void KDocker::preProcessCommand(int argc, char **argv) { int option; optind = 0; // initialise the getopt static while ((option = getopt(argc, argv, Constants::OPTIONSTRING)) != -1) { switch (option) { case '?': printUsage(); ::exit(1); break; case 'a': printAbout(); ::exit(0); break; case 'h': printHelp(); ::exit(0); break; case 'u': printUsage(); ::exit(0); break; case 'v': printVersion(); ::exit(0); break; } } } void KDocker::printAbout() { QTextStream out(stdout); out << Constants::ABOUT_MESSAGE << endl; } void KDocker::printHelp() { QTextStream out(stdout); out << tr("Usage: %1 [options] [command] -- [command options]").arg(qApp->applicationName().toLower()) << endl; out << tr("Docks any application into the system tray") << endl; out << endl; out << tr("Command") << endl; out << tr("Run command and dock window") << endl; out << tr("Use -- after command to specify options for command") << endl; out << endl; out << tr("Options") << endl; out << "-a \t" << tr("Show author information") << endl; out << "-b \t" << tr("Don't warn about non-normal windows (blind mode)") << endl; out << "-d secs\t" << tr("Maximum time in seconds to allow for command to start and open a window (defaults to 5 sec)") << endl; out << "-f \t" << tr("Dock window that has focus (active window)") << endl; out << "-h \t" << tr("Display this help") << endl; out << "-i file\t" << tr("Set the tray icon to file") << endl; out << "-l \t" << tr("Iconify when focus lost") << endl; out << "-m \t" << tr("Keep application window showing (dont hide on dock)") << endl; out << "-n name\t" << tr("Match window based on window title") << endl; out << "-o \t" << tr("Iconify when obscured") << endl; out << "-p secs\t" << tr("Set ballooning timeout (popup time)") << endl; out << "-q \t" << tr("Disable ballooning title changes (quiet)") << endl; out << "-r \t" << tr("Remove this application from the pager") << endl; out << "-s \t" << tr("Make the window sticky (appears on all desktops)") << endl; out << "-t \t" << tr("Remove this application from the taskbar") << endl; out << "-v \t" << tr("Display version") << endl; out << "-w wid \t" << tr("Window id of the application to dock. Assumes hex number of the form 0x###...") << endl; out << "-x pid \t" << tr("Process id of the application to dock. Assumes decimal number of the form ###...") << endl; out << endl; out << tr("Bugs and wishes to https://bugs.launchpad.net/kdocker") << endl; out << tr("Project information at https://launchpad.net/kdocker") << endl; } void KDocker::printUsage() { QTextStream out(stdout); out << tr("Usage: %1 [options] command").arg(qApp->applicationName().toLower()) << endl; out << tr("Try `%1 -h' for more information").arg(qApp->applicationName().toLower()) << endl; } void KDocker::printVersion() { QTextStream out(stdout); out << tr("%1 version: %2").arg(qApp->applicationName()).arg(qApp->applicationVersion()) << endl; out << tr("Using Qt version: %1").arg(qVersion()) << endl; } kdocker-4.6/src/kdocker.h000644 000765 000024 00000002615 11570604611 015475 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #ifndef _KDOCKER_H #define _KDOCKER_H #include #include #include "trayitemmanager.h" class KDocker : public QObject { Q_OBJECT public: KDocker(); ~KDocker(); void undockAll(); void preProcessCommand(int argc, char **argv); bool x11EventFilter(XEvent *ev); public slots: void run(); private slots: void handleMessage(const QString &args); private: void printAbout(); void printHelp(); void printUsage(); void printVersion(); TrayItemManager *m_trayItemManager; }; #endif /* _KDOCKER_H */ kdocker-4.6/src/main.cpp000644 000765 000024 00000005602 11570604611 015331 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include #include #include #include #include #include "application.h" #include "constants.h" #include "kdocker.h" static void sighandler(int sig) { Q_UNUSED(sig); dynamic_cast (qApp)->close(); } int main(int argc, char *argv[]) { Application app("KDocker", argc, argv); // setup signal handlers that undock and quit signal(SIGHUP, sighandler); signal(SIGSEGV, sighandler); signal(SIGTERM, sighandler); signal(SIGINT, sighandler); signal(SIGUSR1, sighandler); // Setup the translator QTranslator translator; QString locale = QString("kdocker_%1").arg(QLocale::system().name()); if (!translator.load(locale, TRANSLATIONS_PATH)) { if (!translator.load(locale, "./build/i18n/")) { translator.load(locale, "./i18n/"); } } app.installTranslator(&translator); app.setOrganizationName(Constants::ORG_NAME); app.setOrganizationDomain(Constants::DOM_NAME); app.setApplicationName(Constants::APP_NAME); app.setApplicationVersion(Constants::APP_VERSION); // Quiting will be handled by the TrayItemManager in the KDocker instance. // It will determine when there is nothing left running. app.setQuitOnLastWindowClosed(false); KDocker kdocker; // This can exit the application. We want the output of any help text output // on the tty the instance has started from so we call this here. kdocker.preProcessCommand(argc, argv); // Send the arguments in a message to another instance if there is one. if (app.sendMessage(QCoreApplication::arguments().join("\n"))) { return 0; } // Handle messages from other instance so this can be a single instance app. QObject::connect(&app, SIGNAL(messageReceived(const QString&)), &kdocker, SLOT(handleMessage(const QString&))); // Wait for the Qt event loop to be started before running. QMetaObject::invokeMethod(&kdocker, "run", Qt::QueuedConnection); app.setKDockerInstance(&kdocker); return app.exec(); } kdocker-4.6/src/scanner.cpp000644 000765 000024 00000007264 11570604611 016044 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include #include #include #include #include #include #include "scanner.h" #include "xlibutil.h" #include Scanner::Scanner(TrayItemManager *manager) { m_manager = manager; m_timer = new QTimer(); // Check every second if a window has been created. m_timer->setInterval(1000); connect(m_timer, SIGNAL(timeout()), this, SLOT(check())); } Scanner::~Scanner() { delete m_timer; } void Scanner::enqueue(const QString &command, const QStringList &arguments, TrayItemSettings settings, int maxTime, bool checkNormality, const QString &windowName) { qint64 pid = 0; bool started = true; if (maxTime <= 0) { maxTime = 1; } ProcessId processId = {command, 0, settings, 0, maxTime, checkNormality, windowName}; if (!command.isEmpty()) { // Launched the requested application. started = QProcess::startDetached(command, arguments, "", &pid); } if (started) { // Either the application started properly or we are matching by name. processId.pid = static_cast(pid); m_processes.append(processId); m_timer->start(); } else { QMessageBox::information(0, qApp->applicationName(), tr("%1 did not start properly.").arg(command)); } } bool Scanner::isRunning() { return !m_processes.isEmpty(); } void Scanner::check() { QMutableListIterator pi(m_processes); while (pi.hasNext()) { ProcessId id = pi.next(); id.count++; pi.setValue(id); Window w = None; if (id.windowName.isEmpty()) { if (kill(id.pid, 0) == -1) { // PID does not exist; fall back to name matching. id.windowName = id.command.split("/").last(); pi.setValue(id); } else { // Check based on PID. w = XLibUtil::pidToWid(QX11Info::display(), QX11Info::appRootWindow(), id.checkNormality, id.pid); } } // Use an if instead of else because the windowName could be set previously if the PID does not exist. if (!id.windowName.isEmpty()) { // Check based on window name if the user specified a window name to match with. w = XLibUtil::findWindow(QX11Info::display(), QX11Info::appRootWindow(), id.checkNormality, id.windowName, m_manager->dockedWindows()); } if (w != None) { emit(windowFound(w, id.settings)); pi.remove(); } else { if (id.count >= id.maxCount) { QMessageBox::information(0, tr("KDocker"), tr("Could not find a matching window for %1 in the specified time: %2 seconds.").arg(id.command).arg(QString::number(id.maxCount))); pi.remove(); } } } if (m_processes.isEmpty()) { m_timer->stop(); emit(stopping()); } } kdocker-4.6/src/scanner.h000644 000765 000024 00000003421 11570604611 015500 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #ifndef _SCANNER_H #define _SCANNER_H #include #include #include #include #include "trayitem.h" #include "trayitemmanager.h" #include #include class TrayItemManager; struct ProcessId { QString command; pid_t pid; TrayItemSettings settings; int count; int maxCount; bool checkNormality; QString windowName; }; // Launches commands and looks for the window ids they create. class Scanner : public QObject { Q_OBJECT public: Scanner(TrayItemManager *manager); ~Scanner(); void enqueue(const QString &command, const QStringList &arguments, TrayItemSettings settings, int maxTime = 30, bool checkNormality = true, const QString &windowName = QString()); bool isRunning(); private slots: void check(); signals: void windowFound(Window, TrayItemSettings); void stopping(); private: TrayItemManager *m_manager; QTimer *m_timer; QList m_processes; }; #endif /* _SCANNER_H */ kdocker-4.6/src/trayitem.cpp000644 000765 000024 00000044620 11570604611 016246 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include #include #include #include #include #include #include #include #include "trayitem.h" #include "xlibutil.h" #include #include TrayItem::TrayItem(Window window) { m_iconified = false; m_customIcon = false; m_skipTaskbar = false; m_skipPager = false; m_sticky = false; m_iconifyMinimized = true; m_iconifyObscure = false; m_iconifyFocusLost = false; m_balloonTimeout = 4000; m_dockedAppName = ""; m_window = window; m_is_restoring = false; Display *display = QX11Info::display(); // Allows events from m_window to be forwarded to the x11EventFilter. XLibUtil::subscribe(display, m_window, StructureNotifyMask | PropertyChangeMask | VisibilityChangeMask | FocusChangeMask, true); // Store the desktop on which the window is being shown. XLibUtil::getCardinalProperty(display, m_window, XInternAtom(display, "_NET_WM_DESKTOP", True), &m_desktop); readDockedAppName(); updateTitle(); updateIcon(); createContextMenu(); updateToggleAction(); connect(this, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason))); } TrayItem::~TrayItem() { // Only the main menu needs to be deleted. The rest of the menus and actions // are children of this menu and Qt will delete all children. delete m_contextMenu; } Window TrayItem::dockedWindow() { return m_window; } bool TrayItem::x11EventFilter(XEvent *ev) { if (isBadWindow()) { return false; } XAnyEvent *event = reinterpret_cast (ev); if (event->window == m_window) { if (event->type == DestroyNotify) { destroyEvent(); return true; } else if (event->type == PropertyNotify) { return propertyChangeEvent(reinterpret_cast (event)->atom); } else if (event->type == VisibilityNotify) { if (reinterpret_cast (event)->state == VisibilityFullyObscured) { obscureEvent(); return true; } } else if (event->type == FocusOut) { focusLostEvent(); return true; } else if (event->type == MapNotify) { m_iconified = false; updateToggleAction(); return true; } else if (event->type == UnmapNotify) { m_iconified = true; updateToggleAction(); return true; } } return false; } void TrayItem::restoreWindow() { if (isBadWindow()) { return; } m_is_restoring = true; Display *display = QX11Info::display(); Window root = QX11Info::appRootWindow(); if (m_iconified) { m_iconified = false; /* * A simple XMapWindow would not do. Some applications like xmms wont * redisplay its other windows (like the playlist, equalizer) since the * Withdrawn->Normal state change code does not map them. So we make the * window go through Withdrawn->Map->Iconify->Normal state. */ XMapWindow(display, m_window); XIconifyWindow(display, m_window, DefaultScreen(display)); XSync(display, False); long l_state[1] = {NormalState}; XLibUtil::sendMessage(display, root, m_window, "WM_CHANGE_STATE", 32, SubstructureNotifyMask | SubstructureRedirectMask, l_state, sizeof (l_state)); m_sizeHint.flags = USPosition; XSetWMNormalHints(display, m_window, &m_sizeHint); updateToggleAction(); } XMapRaised(display, m_window); // Change to the desktop that the window was last on. long l_currDesk[2] = {m_desktop, CurrentTime}; XLibUtil::sendMessage(display, root, root, "_NET_CURRENT_DESKTOP", 32, SubstructureNotifyMask | SubstructureRedirectMask, l_currDesk, sizeof (l_currDesk)); // Set the desktop the window wants to be on. long l_wmDesk[2] = {m_desktop, 1}; // 1 == request sent from application. 2 == from pager XLibUtil::sendMessage(display, root, m_window, "_NET_WM_DESKTOP", 32, SubstructureNotifyMask | SubstructureRedirectMask, l_wmDesk, sizeof (l_wmDesk)); // Make it the active window // 1 == request sent from application. 2 == from pager. // We use 2 because KWin doesn't always give the window focus with 1. long l_active[2] = {2, CurrentTime}; XLibUtil::sendMessage(display, root, m_window, "_NET_ACTIVE_WINDOW", 32, SubstructureNotifyMask | SubstructureRedirectMask, l_active, sizeof (l_active)); XSetInputFocus(display, m_window, RevertToParent, CurrentTime); updateToggleAction(); doSkipTaskbar(); /* * Wait half a second to ensure the window is fully restored. * This and m_is_restoring are a work around for KWin. * KWin is the only WM that will send a PropertyNotify * event with the Iconic state set because of the above * XIconifyWindow call. */ QTime t; t.start(); while (t.elapsed() < 500) { qApp->processEvents(); } m_is_restoring = false; } void TrayItem::iconifyWindow() { if (isBadWindow() || m_is_restoring) { return; } m_iconified = true; Display *display = QX11Info::display(); int screen = DefaultScreen(display); long dummy; XGetWMNormalHints(display, m_window, &m_sizeHint, &dummy); /* * A simple call to XWithdrawWindow wont do. Here is what we do: * 1. Iconify. This will make the application hide all its other windows. For * example, xmms would take off the playlist and equalizer window. * 2. Withdrawn the window so we will be removed from the taskbar. */ XIconifyWindow(display, m_window, screen); // good for effects too XSync(display, False); XWithdrawWindow(display, m_window, screen); updateToggleAction(); } void TrayItem::closeWindow() { if (isBadWindow()) { return; } Display *display = QX11Info::display(); long l[5] = {0, 0, 0, 0, 0}; restoreWindow(); XLibUtil::sendMessage(display, QX11Info::appRootWindow(), m_window, "_NET_CLOSE_WINDOW", 32, SubstructureNotifyMask | SubstructureRedirectMask, l, sizeof (l)); } void TrayItem::doSkipTaskbar() { set_NET_WM_STATE("_NET_WM_STATE_SKIP_TASKBAR", m_skipTaskbar); } void TrayItem::doSkipPager() { set_NET_WM_STATE("_NET_WM_STATE_SKIP_PAGER", m_skipPager); } void TrayItem::doSticky() { set_NET_WM_STATE("_NET_WM_STATE_STICKY", m_sticky); } void TrayItem::setCustomIcon(QString path) { m_customIcon = true; QPixmap customIcon; if (!customIcon.load(path)) { customIcon.load(":/images/question.png"); } setIcon(QIcon(customIcon)); } void TrayItem::selectCustomIcon(bool value) { Q_UNUSED(value); QStringList types; QString supportedTypes; QString path; Q_FOREACH(QByteArray type, QImageReader::supportedImageFormats()) { types << QString(type); } if (types.isEmpty()) { supportedTypes = "All Files (*.*)"; } else { supportedTypes = QString("Images (*.%1);;All Files (*.*)").arg(types.join(" *.")); } path = QFileDialog::getOpenFileName(0, tr("Select Icon"), QDir::homePath(), supportedTypes); if (!path.isEmpty()) { setCustomIcon(path); } } void TrayItem::setSkipTaskbar(bool value) { m_skipTaskbar = value; m_actionSkipTaskbar->setChecked(value); doSkipTaskbar(); } void TrayItem::setSkipPager(bool value) { m_skipPager = value; m_actionSkipPager->setChecked(value); doSkipPager(); } void TrayItem::setSticky(bool value) { m_sticky = value; m_actionSticky->setChecked(value); doSticky(); } void TrayItem::setIconifyMinimized(bool value) { m_iconifyMinimized = value; m_actionIconifyMinimized->setChecked(value); } void TrayItem::setIconifyObscure(bool value) { m_iconifyObscure = value; m_actionIconifyObscure->setChecked(value); } void TrayItem::setIconifyFocusLost(bool value) { m_iconifyFocusLost = value; m_actionIconifyFocusLost->setChecked(value); focusLostEvent(); } void TrayItem::setBalloonTimeout(int value) { if (value < 0) { value = 0; } m_balloonTimeout = value; m_actionBalloonTitleChanges->setChecked(value ? true : false); } void TrayItem::setBalloonTimeout(bool value) { if (!value) { setBalloonTimeout(-1); } else { setBalloonTimeout(4000); } } void TrayItem::toggleWindow() { if (m_iconified || m_window != XLibUtil::activeWindow(QX11Info::display())) { restoreWindow(); } else { iconifyWindow(); } } void TrayItem::trayActivated(QSystemTrayIcon::ActivationReason reason) { if (reason == QSystemTrayIcon::Trigger) { if (m_iconified || m_window != XLibUtil::activeWindow(QX11Info::display())) { restoreWindow(); } else { iconifyWindow(); } } } void TrayItem::doAbout() { emit(about()); } void TrayItem::doSelectAnother() { emit(selectAnother()); } void TrayItem::doUndock() { emit(undock(this)); } void TrayItem::doUndockAll() { emit(undockAll()); } void TrayItem::minimizeEvent() { if (m_iconifyMinimized) { iconifyWindow(); } } void TrayItem::destroyEvent() { m_window = 0; emit(dead(this)); } bool TrayItem::propertyChangeEvent(Atom property) { if (isBadWindow()) { return false; } Display *display = QX11Info::display(); static Atom WM_NAME = XInternAtom(display, "WM_NAME", True); static Atom WM_ICON = XInternAtom(display, "WM_ICON", True); static Atom WM_STATE = XInternAtom(display, "WM_STATE", True); static Atom _NET_WM_DESKTOP = XInternAtom(display, "_NET_WM_DESKTOP", True); if (property == WM_NAME) { updateTitle(); return true; } else if (property == WM_ICON) { updateIcon(); return true; } else if (property == _NET_WM_DESKTOP) { XLibUtil::getCardinalProperty(display, m_window, _NET_WM_DESKTOP, &m_desktop); return true; } else if (property == WM_STATE) { Atom type = None; int format; unsigned long nitems, after; unsigned char *data = 0; int r = XGetWindowProperty(display, m_window, WM_STATE, 0, 1, False, AnyPropertyType, &type, &format, &nitems, &after, &data); if ((r == Success) && data && (*reinterpret_cast (data) == IconicState)) { minimizeEvent(); XFree(data); return true; } } return false; } void TrayItem::obscureEvent() { if (m_iconifyObscure) { iconifyWindow(); } } void TrayItem::focusLostEvent() { // Wait half a second before checking to ensure the window is properly // focused when being restored. QTime t; t.start(); while (t.elapsed() < 500) { qApp->processEvents(); } if (m_iconifyFocusLost && m_window != XLibUtil::activeWindow(QX11Info::display())) { iconifyWindow(); } } void TrayItem::set_NET_WM_STATE(const char *type, bool set) { if (isBadWindow()) { return; } // set, true = add the state to the window. False, remove the state from // the window. Display *display = QX11Info::display(); Atom atom = XInternAtom(display, type, False); long l[2] = {set ? 1 : 0, atom}; XLibUtil::sendMessage(display, QX11Info::appRootWindow(), m_window, "_NET_WM_STATE", 32, SubstructureNotifyMask, l, sizeof (l)); } void TrayItem::readDockedAppName() { if (isBadWindow()) { return; } Display *display = QX11Info::display(); XClassHint ch; if (XGetClassHint(display, m_window, &ch)) { if (ch.res_class) { m_dockedAppName = QString(ch.res_class); } else if (ch.res_name) { m_dockedAppName = QString(ch.res_name); } if (ch.res_class) { XFree(ch.res_class); } if (ch.res_name) { XFree(ch.res_name); } } } /* * Update the title in the tooltip. */ void TrayItem::updateTitle() { if (isBadWindow()) { return; } Display *display = QX11Info::display(); char *windowName = 0; QString title; XFetchName(display, m_window, &windowName); title = windowName; if (windowName) { XFree(windowName); } setToolTip(QString("%1 [%2]").arg(title).arg(m_dockedAppName)); if (m_balloonTimeout > 0) { showMessage(m_dockedAppName, title, QSystemTrayIcon::Information, m_balloonTimeout); } } void TrayItem::updateIcon() { if (isBadWindow() || m_customIcon) { return; } setIcon(createIcon(m_window)); } void TrayItem::updateToggleAction() { QString text; QIcon icon; if (m_iconified) { text = tr("Show %1").arg(m_dockedAppName); icon = QIcon(":/images/restore.png"); } else { text = tr("Hide %1").arg(m_dockedAppName); icon = QIcon(":/images/iconify.png"); } m_actionToggle->setIcon(icon); m_actionToggle->setText(text); } void TrayItem::createContextMenu() { m_contextMenu = new QMenu(); m_contextMenu->addAction(QIcon(":/images/about.png"), tr("About %1").arg(qApp->applicationName()), this, SLOT(doAbout())); m_contextMenu->addSeparator(); // Options menu m_optionsMenu = new QMenu(tr("Options"), m_contextMenu); m_actionSetIcon = new QAction(tr("Set icon..."), m_optionsMenu); connect(m_actionSetIcon, SIGNAL(triggered(bool)), this, SLOT(selectCustomIcon(bool))); m_optionsMenu->addAction(m_actionSetIcon); m_actionSkipTaskbar = new QAction(tr("Skip taskbar"), m_optionsMenu); m_actionSkipTaskbar->setCheckable(true); m_actionSkipTaskbar->setChecked(m_skipTaskbar); connect(m_actionSkipTaskbar, SIGNAL(triggered(bool)), this, SLOT(setSkipTaskbar(bool))); m_optionsMenu->addAction(m_actionSkipTaskbar); m_actionSkipPager = new QAction(tr("Skip pager"), m_optionsMenu); m_actionSkipPager->setCheckable(true); m_actionSkipPager->setChecked(m_skipPager); connect(m_actionSkipPager, SIGNAL(triggered(bool)), this, SLOT(setSkipPager(bool))); m_optionsMenu->addAction(m_actionSkipPager); m_actionSticky = new QAction(tr("Sticky"), m_optionsMenu); m_actionSticky->setCheckable(true); m_actionSticky->setChecked(m_sticky); connect(m_actionSticky, SIGNAL(triggered(bool)), this, SLOT(setSticky(bool))); m_optionsMenu->addAction(m_actionSticky); m_actionIconifyMinimized = new QAction(tr("Iconify when minimized"), m_optionsMenu); m_actionIconifyMinimized->setCheckable(true); m_actionIconifyMinimized->setChecked(m_iconifyMinimized); connect(m_actionIconifyMinimized, SIGNAL(triggered(bool)), this, SLOT(setIconifyMinimized(bool))); m_optionsMenu->addAction(m_actionIconifyMinimized); m_actionIconifyObscure = new QAction(tr("Iconify when obscured"), m_optionsMenu); m_actionIconifyObscure->setCheckable(true); m_actionIconifyObscure->setChecked(m_iconifyObscure); connect(m_actionIconifyObscure, SIGNAL(triggered(bool)), this, SLOT(setIconifyObscure(bool))); m_optionsMenu->addAction(m_actionIconifyObscure); m_actionIconifyFocusLost = new QAction(tr("Iconify when focus lost"), m_optionsMenu); m_actionIconifyFocusLost->setCheckable(true); m_actionIconifyFocusLost->setChecked(m_iconifyFocusLost); connect(m_actionIconifyFocusLost, SIGNAL(toggled(bool)), this, SLOT(setIconifyFocusLost(bool))); m_optionsMenu->addAction(m_actionIconifyFocusLost); m_actionBalloonTitleChanges = new QAction(tr("Balloon title changes"), m_optionsMenu); m_actionBalloonTitleChanges->setCheckable(true); m_actionBalloonTitleChanges->setChecked(m_balloonTimeout ? true : false); connect(m_actionBalloonTitleChanges, SIGNAL(triggered(bool)), this, SLOT(setBalloonTimeout(bool))); m_optionsMenu->addAction(m_actionBalloonTitleChanges); m_contextMenu->addMenu(m_optionsMenu); m_contextMenu->addAction(QIcon(":/images/another.png"), tr("Dock Another"), this, SLOT(doSelectAnother())); m_contextMenu->addAction(tr("Undock All"), this, SLOT(doUndockAll())); m_contextMenu->addSeparator(); m_actionToggle = new QAction(tr("Toggle"), m_contextMenu); connect(m_actionToggle, SIGNAL(triggered()), this, SLOT(toggleWindow())); m_contextMenu->addAction(m_actionToggle); m_contextMenu->addAction(tr("Undock"), this, SLOT(doUndock())); m_contextMenu->addAction(QIcon(":/images/close.png"), tr("Close"), this, SLOT(closeWindow())); setContextMenu(m_contextMenu); } QIcon TrayItem::createIcon(Window window) { char **window_icon = 0; if (!window) { return QIcon(); } QPixmap appIcon; Display *display = QX11Info::display(); XWMHints *wm_hints = XGetWMHints(display, window); if (wm_hints != 0) { if (!(wm_hints->flags & IconMaskHint)) wm_hints->icon_mask = None; /* * We act paranoid here. Progams like KSnake has a bug where * IconPixmapHint is set but no pixmap (Actually this happens with * quite a few KDE 3.x programs) X-( */ if ((wm_hints->flags & IconPixmapHint) && (wm_hints->icon_pixmap)) { XpmCreateDataFromPixmap(display, &window_icon, wm_hints->icon_pixmap, wm_hints->icon_mask, 0); } XFree(wm_hints); } if (!window_icon) { appIcon.load(":/images/question.png"); } else { appIcon = QPixmap(const_cast (window_icon)); } if (window_icon) { XpmFree(window_icon); } return QIcon(appIcon); } bool TrayItem::isBadWindow() { Display *display = QX11Info::display(); if (!XLibUtil::isValidWindowId(display, m_window)) { destroyEvent(); return true; } return false; } kdocker-4.6/src/trayitem.h000644 000765 000024 00000007115 11570604611 015711 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #ifndef _TRAYITEM_H #define _TRAYITEM_H #include #include #include #include #include #include #include #include struct TrayItemSettings { QString customIcon; int balloonTimeout; bool iconify; bool skipTaskbar; bool skipPager; bool sticky; bool iconifyObscure; bool iconifyFocusLost; }; class TrayItem : public QSystemTrayIcon { Q_OBJECT public: TrayItem(Window window); ~TrayItem(); Window dockedWindow(); // Pass on all events through this interface bool x11EventFilter(XEvent * event); public slots: void restoreWindow(); void iconifyWindow(); // Close the window void closeWindow(); void doSkipTaskbar(); void doSkipPager(); void doSticky(); void setCustomIcon(QString path); void selectCustomIcon(bool value); void setSkipTaskbar(bool value); void setSkipPager(bool value); void setSticky(bool value); void setIconifyMinimized(bool value); void setIconifyObscure(bool value); void setIconifyFocusLost(bool value); void setBalloonTimeout(int value); void setBalloonTimeout(bool value); private slots: void toggleWindow(); void trayActivated(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Trigger); void doAbout(); void doSelectAnother(); void doUndock(); void doUndockAll(); signals: void selectAnother(); void dead(TrayItem*); void undockAll(); void undock(TrayItem*); void about(); private: void minimizeEvent(); void destroyEvent(); bool propertyChangeEvent(Atom property); void obscureEvent(); void focusLostEvent(); void set_NET_WM_STATE(const char *type, bool set); void readDockedAppName(); void updateTitle(); void updateIcon(); void updateToggleAction(); void createContextMenu(); QIcon createIcon(Window window); bool isBadWindow(); bool m_iconified; bool m_customIcon; bool m_skipTaskbar; bool m_skipPager; bool m_sticky; bool m_iconifyMinimized; bool m_iconifyObscure; bool m_iconifyFocusLost; int m_balloonTimeout; bool m_is_restoring; // SizeHint of m_window XSizeHints m_sizeHint; // The window that is associated with the tray icon. Window m_window; long m_desktop; QString m_dockedAppName; QMenu *m_contextMenu; QMenu *m_optionsMenu; QAction *m_actionSetIcon; QAction *m_actionSkipTaskbar; QAction *m_actionSkipPager; QAction *m_actionSticky; QAction *m_actionIconifyMinimized; QAction *m_actionIconifyObscure; QAction *m_actionIconifyFocusLost; QAction *m_actionBalloonTitleChanges; QAction *m_actionToggle; }; #endif /* _TRAYITEM_H */ kdocker-4.6/src/trayitemmanager.cpp000644 000765 000024 00000025533 11570604611 017603 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include #include #include #include #include #include "constants.h" #include "trayitemmanager.h" #include "xlibutil.h" #include #include #include #include int ignoreXErrors(Display *, XErrorEvent *) { return 0; } TrayItemManager::TrayItemManager() { m_scanner = new Scanner(this); connect(m_scanner, SIGNAL(windowFound(Window, TrayItemSettings)), this, SLOT(dockWindow(Window, TrayItemSettings))); connect(m_scanner, SIGNAL(stopping()), this, SLOT(checkCount())); // This will prevent x errors from being written to the console. // The isValidWindowId function in util.cpp will generate errors if the // window is not valid while it is checking. XSetErrorHandler(ignoreXErrors); } TrayItemManager::~TrayItemManager() { while (!m_trayItems.isEmpty()) { TrayItem *t = m_trayItems.takeFirst(); delete t; } delete m_scanner; } /* * The X11 Event Filter. Pass on events to the TrayItems that we created. */ bool TrayItemManager::x11EventFilter(XEvent *ev) { QListIterator ti(m_trayItems); // We pass on the event to the tray item with the associated window. TrayItem *t; while (ti.hasNext()) { t = ti.next(); if (ev->xclient.window == t->dockedWindow()) { return t->x11EventFilter(ev); } } return false; } void TrayItemManager::processCommand(const QStringList &args) { int option; pid_t pid = 0; Window window = 0; bool checkNormality = true; int maxTime = 5; QString windowName; TrayItemSettings settings; settings.balloonTimeout = 4000; settings.iconify = true; settings.skipTaskbar = false; settings.skipPager = false; settings.sticky = false; settings.iconifyObscure = false; settings.iconifyFocusLost = false; // Turn the QStringList of arguments into something getopt can use. QList bargs; Q_FOREACH(QString s, args) { bargs.append(s.toLocal8Bit()); } int argc = bargs.count(); // Use a const char * here and a const_cast later because it is faster. // Using char * will cause a deep copy. const char *argv[argc + 1]; for (int i = 0; i < argc; i++) { argv[i] = bargs[i].data(); } /* Options: a, h, u, v are all handled by the KDocker class because we * want them to print on the tty the instance was called from. */ optind = 0; // initialise the getopt static while ((option = getopt(argc, const_cast (argv), Constants::OPTIONSTRING)) != -1) { switch (option) { case '?': checkCount(); return; case 'b': checkNormality = false; break; case 'd': maxTime = atoi(optarg); break; case 'f': window = XLibUtil::activeWindow(QX11Info::display()); if (!window) { QMessageBox::critical(0, qApp->applicationName(), tr("Cannot dock the active window because no window has focus.")); checkCount(); return; } break; case 'i': settings.customIcon = QString::fromLocal8Bit(optarg); break; case 'l': settings.iconifyFocusLost = true; break; case 'm': settings.iconify = false; break; case 'n': windowName = QString::fromLocal8Bit(optarg); break; case 'o': settings.iconifyObscure = true; break; case 'p': settings.balloonTimeout = atoi(optarg) * 1000; // convert to ms break; case 'q': settings.balloonTimeout = 0; // same as '-p 0' break; case 'r': settings.skipPager = true; break; case 's': settings.sticky = true; break; case 't': settings.skipTaskbar = true; break; case 'w': if (((sizeof(optarg) / sizeof(*optarg)) > 2) && ((optarg[1] == 'x') || (optarg[1] == 'X'))) { sscanf(optarg, "%x", reinterpret_cast(&window)); } else { window = static_cast(atoi(optarg)); } if (!XLibUtil::isValidWindowId(QX11Info::display(), window)) { QMessageBox::critical(0, qApp->applicationName(), tr("Invalid window id.")); checkCount(); return; } break; case 'x': pid = atol(optarg); break; } // switch (option) } // while (getopt) if (optind < argc || !windowName.isEmpty()) { // We are either launching an application and or matching by name. QString command; QStringList arguments; // Store the command and it's arguments if the user specified them. if (optind < argc) { command = argv[optind]; for (int i = optind + 1; i < argc; i++) { arguments << QString::fromLocal8Bit(argv[i]); } } // Add the parameters the scanner should use to match. If a command was specified it will be started by the scanner. m_scanner->enqueue(command, arguments, settings, maxTime, checkNormality, windowName); checkCount(); } else { if (!window) { if (pid != 0) { window = XLibUtil::pidToWid(QX11Info::display(), QX11Info::appRootWindow(), checkNormality, pid, dockedWindows()); } else { window = userSelectWindow(checkNormality); } } if (window) { dockWindow(window, settings); } else { // No window was selected or set. checkCount(); } } } void TrayItemManager::dockWindow(Window window, TrayItemSettings settings) { if (isWindowDocked(window)) { QMessageBox::information(0, qApp->applicationName(), tr("This window is already docked.\nClick on system tray icon to toggle docking.")); checkCount(); return; } TrayItem *ti = new TrayItem(window); if (!settings.customIcon.isEmpty()) { ti->setCustomIcon(settings.customIcon); } ti->setBalloonTimeout(settings.balloonTimeout); ti->setSticky(settings.sticky); ti->setSkipPager(settings.skipPager); ti->setSkipTaskbar(settings.skipTaskbar); ti->setIconifyObscure(settings.iconifyObscure); ti->setIconifyFocusLost(settings.iconifyFocusLost); connect(ti, SIGNAL(selectAnother()), this, SLOT(selectAndIconify())); connect(ti, SIGNAL(dead(TrayItem*)), this, SLOT(remove(TrayItem*))); connect(ti, SIGNAL(undock(TrayItem*)), this, SLOT(undock(TrayItem*))); connect(ti, SIGNAL(undockAll()), this, SLOT(undockAll())); connect(ti, SIGNAL(about()), this, SLOT(about())); ti->show(); if (settings.iconify) { ti->iconifyWindow(); } else { if (settings.skipTaskbar) { ti->doSkipTaskbar(); } } m_trayItems.append(ti); } Window TrayItemManager::userSelectWindow(bool checkNormality) { QTextStream out(stdout); out << tr("Select the application/window to dock with the left mouse button.") << endl; out << tr("Click any other mouse button to abort.") << endl; QString error; Window window = XLibUtil::selectWindow(QX11Info::display(), error); if (!window) { if (error != QString()) { QMessageBox::critical(0, qApp->applicationName(), error); } checkCount(); return 0; } if (checkNormality) { if (!XLibUtil::isNormalWindow(QX11Info::display(), window)) { if (QMessageBox::warning(0, qApp->applicationName(), tr("The window you are attempting to dock does not seem to be a normal window."), QMessageBox::Abort | QMessageBox::Ignore) == QMessageBox::Abort) { checkCount(); return 0; } } } return window; } void TrayItemManager::remove(TrayItem *trayItem) { m_trayItems.removeAll(trayItem); trayItem->deleteLater(); checkCount(); } void TrayItemManager::undock(TrayItem *trayItem) { trayItem->restoreWindow(); trayItem->setSkipTaskbar(false); trayItem->doSkipTaskbar(); remove(trayItem); } void TrayItemManager::undockAll() { Q_FOREACH(TrayItem *ti, m_trayItems) { undock(ti); } } void TrayItemManager::about() { QMessageBox aboutBox; aboutBox.setIconPixmap(QPixmap(":/images/kdocker.png")); aboutBox.setWindowTitle(tr("About %1 - %2").arg(qApp->applicationName()).arg(qApp->applicationVersion())); aboutBox.setText(Constants::ABOUT_MESSAGE); aboutBox.setInformativeText(tr("See %1 for more information.").arg("https://launchpad.net/kdocker")); aboutBox.setStandardButtons(QMessageBox::Ok); aboutBox.exec(); } void TrayItemManager::selectAndIconify() { Window window = userSelectWindow(true); if (window) { TrayItemSettings settings; settings.balloonTimeout = 4000; settings.iconify = true; settings.skipTaskbar = false; settings.skipPager = false; settings.sticky = false; settings.iconifyObscure = false; settings.iconifyFocusLost = false; dockWindow(window, settings); } } void TrayItemManager::checkCount() { if (m_trayItems.isEmpty() && !m_scanner->isRunning()) { qApp->quit(); } } QList TrayItemManager::dockedWindows() { QList windows; QListIterator ti(m_trayItems); while (ti.hasNext()) { windows.append(ti.next()->dockedWindow()); } return windows; } bool TrayItemManager::isWindowDocked(Window window) { return dockedWindows().contains(window); } kdocker-4.6/src/trayitemmanager.h000644 000765 000024 00000003471 11570604611 017245 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #ifndef _TRAYITEMMANAGER_H #define _TRAYITEMMANAGER_H #include #include #include #include "scanner.h" #include "trayitem.h" #include #include class Scanner; class TrayItemManager : public QObject { Q_OBJECT // The Scanner needs to know which windows are docked. friend class Scanner; public: TrayItemManager(); ~TrayItemManager(); bool x11EventFilter(XEvent *ev); void processCommand(const QStringList &args); public slots: void dockWindow(Window window, TrayItemSettings settings); Window userSelectWindow(bool checkNormality = true); void remove(TrayItem *trayItem); void undock(TrayItem *trayItem); void undockAll(); void about(); private slots: void selectAndIconify(); void checkCount(); private: QList dockedWindows(); bool isWindowDocked(Window window); Scanner *m_scanner; QList m_trayItems; }; #endif /* _TRAYITEMMANAGER_H */ kdocker-4.6/src/xlibutil.cpp000644 000765 000024 00000025611 11570604611 016243 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include "xlibutil.h" #include #include #include #include #include #include /* * Assert validity of the window id. Get window attributes for the heck of it * and see if the request went through. */ bool XLibUtil::isValidWindowId(Display *display, Window w) { XWindowAttributes attrib; return (XGetWindowAttributes(display, w, &attrib) != 0); } /* * Checks if this window is a normal window (i.e) * - Has a WM_STATE * - Not modal window * - Not a purely transient window (with no window type set) * - Not a special window (desktop/menu/util) as indicated in the window type */ bool XLibUtil::isNormalWindow(Display *display, Window w) { Atom type; int format; unsigned long left; Atom *data = NULL; unsigned long nitems; Window transient_for = None; static Atom wmState = XInternAtom(display, "WM_STATE", false); static Atom windowState = XInternAtom(display, "_NET_WM_STATE", false); static Atom modalWindow = XInternAtom(display, "_NET_WM_STATE_MODAL", false); static Atom windowType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", false); static Atom normalWindow = XInternAtom(display, "_NET_WM_WINDOW_TYPE_NORMAL", false); static Atom dialogWindow = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", false); int ret = XGetWindowProperty(display, w, wmState, 0, 10, false, AnyPropertyType, &type, &format, &nitems, &left, (unsigned char **) & data); if (ret != Success || data == NULL) { return false; } if (data) { XFree(data); } ret = XGetWindowProperty(display, w, windowState, 0, 10, false, AnyPropertyType, &type, &format, &nitems, &left, (unsigned char **) & data); if (ret == Success) { unsigned int i; for (i = 0; i < nitems; i++) { if (data[i] == modalWindow) { break; } } XFree(data); if (i < nitems) { return false; } } XGetTransientForHint(display, w, &transient_for); ret = XGetWindowProperty(display, w, windowType, 0, 10, false, AnyPropertyType, &type, &format, &nitems, &left, (unsigned char **) & data); if ((ret == Success) && data) { unsigned int i; for (i = 0; i < nitems; i++) { if (data[i] != normalWindow && data[i] != dialogWindow) { break; } } XFree(data); return (i == nitems); } else { return (transient_for == None); } } /* * Returns the contents of the _NET_WM_PID (which is supposed to contain the * process id of the application that created the window) */ pid_t XLibUtil::pid(Display *display, Window w) { Atom actual_type; int actual_format; unsigned long nitems, leftover; unsigned char *pid; pid_t pid_return = -1; if (XGetWindowProperty(display, w, XInternAtom(display, "_NET_WM_PID", false), 0, 1, false, XA_CARDINAL, &actual_type, &actual_format, &nitems, &leftover, &pid) == Success) { if (pid) { pid_return = *(pid_t *) pid; } XFree(pid); } return pid_return; } Window XLibUtil::pidToWid(Display *display, Window window, bool checkNormality, pid_t epid, QList dockedWindows) { Window w = None; Window root; Window parent; Window *child; unsigned int num_child; if (XQueryTree(display, window, &root, &parent, &child, &num_child) != 0) { for (unsigned int i = 0; i < num_child; i++) { if (epid == pid(display, child[i])) { if (!dockedWindows.contains(child[i])) { if (checkNormality) { if (isNormalWindow(display, child[i])) { return child[i]; } } else { return child[i]; } } } w = pidToWid(display, child[i], checkNormality, epid); if (w != None) { break; } } } return w; } /* * The Grand Window Analyzer. Checks if window w has a expected pid of epid * or a expected name of ename. */ bool XLibUtil::analyzeWindow(Display *display, Window w, const QString &ename) { XClassHint ch; // no plans to analyze windows without a name char *window_name = NULL; if (!XFetchName(display, w, &window_name)) { return false; } if (window_name) { XFree(window_name); } else { return false; } bool this_is_our_man = false; // lets try the program name if (XGetClassHint(display, w, &ch)) { if (QString(ch.res_name).indexOf(ename, 0, Qt::CaseInsensitive) != -1) { this_is_our_man = true; } else if (QString(ch.res_class).indexOf(ename, 0, Qt::CaseInsensitive) != -1) { this_is_our_man = true; } else { // sheer desperation char *wm_name = NULL; XFetchName(display, w, &wm_name); if (wm_name && (QString(wm_name).indexOf(ename, 0, Qt::CaseInsensitive) != -1)) { this_is_our_man = true; } } if (ch.res_class) { XFree(ch.res_class); } if (ch.res_name) { XFree(ch.res_name); } } // its probably a good idea to check (obsolete) WM_COMMAND here return this_is_our_man; } /* * Given a starting window look though all children and try to find a window * that matches the ename. */ Window XLibUtil::findWindow(Display *display, Window window, bool checkNormality, const QString &ename, QList dockedWindows) { Window w = None; Window root; Window parent; Window *child; unsigned int num_child; if (XQueryTree(display, window, &root, &parent, &child, &num_child) != 0) { for (unsigned int i = 0; i < num_child; i++) { if (analyzeWindow(display, child[i], ename)) { if (!dockedWindows.contains(child[i])) { if (checkNormality) { if (isNormalWindow(display, child[i])) { return child[i]; } } else { return child[i]; } } } w = findWindow(display, child[i], checkNormality, ename); if (w != None) { break; } } } return w; } /* * Sends ClientMessage to a window. */ void XLibUtil::sendMessage(Display* display, Window to, Window w, const char *type, int format, long mask, void* data, int size) { XEvent ev; memset(&ev, 0, sizeof (ev)); ev.xclient.type = ClientMessage; ev.xclient.window = w; ev.xclient.message_type = XInternAtom(display, type, true); ev.xclient.format = format; memcpy((char *) & ev.xclient.data, (const char *) data, size); XSendEvent(display, to, false, mask, &ev); XSync(display, false); } /* * Returns the id of the currently active window. */ Window XLibUtil::activeWindow(Display * display) { Atom active_window_atom = XInternAtom(display, "_NET_ACTIVE_WINDOW", true); Atom type = None; int format; unsigned long nitems, after; unsigned char *data = NULL; int screen = DefaultScreen(display); Window root = RootWindow(display, screen); int r = XGetWindowProperty(display, root, active_window_atom, 0, 1, false, AnyPropertyType, &type, &format, &nitems, &after, &data); Window w = None; if ((r == Success) && data && (*reinterpret_cast (data) != None)) { w = *(Window *) data; } else { int revert; XGetInputFocus(display, &w, &revert); } return w; } /* * Requests user to select a window by grabbing the mouse. A left click will * select the application. Clicking any other button will abort the selection */ Window XLibUtil::selectWindow(Display *display, QString &error) { int screen = DefaultScreen(display); Window root = RootWindow(display, screen); Cursor cursor = XCreateFontCursor(display, XC_draped_box); if (cursor == None) { error = tr("Failed to create XC_draped_box"); return None; } if (XGrabPointer(display, root, false, ButtonPressMask | ButtonReleaseMask, GrabModeSync, GrabModeAsync, None, cursor, CurrentTime) != GrabSuccess) { error = tr("Failed to grab mouse"); return None; } XAllowEvents(display, SyncPointer, CurrentTime); XEvent event; XWindowEvent(display, root, ButtonPressMask, &event); Window selected_window = (event.xbutton.subwindow == None) ? RootWindow(display, screen) : event.xbutton.subwindow; XUngrabPointer(display, CurrentTime); XFreeCursor(display, cursor); if (event.xbutton.button != Button1) { return None; } return XmuClientWindow(display, selected_window); } /* * Have events associated with mask for the window set in the X11 Event loop * to the application. */ void XLibUtil::subscribe(Display *display, Window w, long mask, bool set) { Window root = RootWindow(display, DefaultScreen(display)); XWindowAttributes attr; XGetWindowAttributes(display, w == None ? root : w, &attr); // Already subscribed not need to do it again. if (set && ((attr.your_event_mask & mask) == mask)) { return; } // Not subscribed to the mask no need to remove it. if (!set && ((attr.your_event_mask | mask) == attr.your_event_mask)) { return; } XSelectInput(display, w == None ? root : w, set ? attr.your_event_mask | mask : attr.your_event_mask & mask); XSync(display, false); } /* * Sets data to the vaule of the requested window property. */ bool XLibUtil::getCardinalProperty(Display *display, Window w, Atom prop, long *data) { Atom type; int format; unsigned long nitems, bytes; unsigned char *d = NULL; if (XGetWindowProperty(display, w, prop, 0, 1, false, XA_CARDINAL, &type, &format, &nitems, &bytes, &d) == Success && d) { if (data) { *data = *reinterpret_cast (d); } XFree(d); return true; } return false; } kdocker-4.6/src/xlibutil.h000644 000765 000024 00000003760 11570604611 015711 0ustar00johnstaff000000 000000 /* * Copyright (C) 2009 John Schember * Copyright (C) 2004 Girish Ramakrishnan All Rights Reserved. * * This 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 software 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 software; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #ifndef _XLIBUTIL_H #define _XLIBUTIL_H #include #include #include #include #include class XLibUtil : public QObject { Q_OBJECT public: static bool isNormalWindow(Display *display, Window w); static bool isValidWindowId(Display *display, Window w); static pid_t pid(Display *display, Window w); static Window pidToWid(Display *display, Window window, bool checkNormality, pid_t epid, QList dockedWindows = QList()); static bool analyzeWindow(Display *display, Window w, const QString &ename); static Window findWindow(Display *display, Window w, bool checkNormality, const QString &ename, QList dockedWindows = QList()); static void sendMessage(Display *display, Window to, Window w, const char *type, int format, long mask, void *data, int size); static Window activeWindow(Display *display); static Window selectWindow(Display *display, QString &error); static void subscribe(Display *display, Window w, long mask, bool set); static bool getCardinalProperty(Display *display, Window w, Atom prop, long *data); }; #endif /* _XLIBUTIL_H */ kdocker-4.6/solutions/qtsingleapplication/000755 000765 000024 00000000000 11570604611 021220 5ustar00johnstaff000000 000000 kdocker-4.6/solutions/qtsingleapplication/qtlocalpeer.cpp000644 000765 000024 00000015206 11570604611 024243 0ustar00johnstaff000000 000000 /**************************************************************************** ** ** This file is part of a Qt Solutions component. ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #include "qtlocalpeer.h" #include #include #if defined(Q_OS_WIN) #include #include typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*); static PProcessIdToSessionId pProcessIdToSessionId = 0; #endif #if defined(Q_OS_UNIX) #include #endif namespace QtLP_Private { #include "qtlockedfile.cpp" #if defined(Q_OS_WIN) #include "qtlockedfile_win.cpp" #else #include "qtlockedfile_unix.cpp" #endif } const char* QtLocalPeer::ack = "ack"; QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) : QObject(parent), id(appId) { QString prefix = id; if (id.isEmpty()) { id = QCoreApplication::applicationFilePath(); #if defined(Q_OS_WIN) id = id.toLower(); #endif prefix = id.section(QLatin1Char('/'), -1); } prefix.remove(QRegExp("[^a-zA-Z]")); prefix.truncate(6); QByteArray idc = id.toUtf8(); quint16 idNum = qChecksum(idc.constData(), idc.size()); socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16); #if defined(Q_OS_WIN) if (!pProcessIdToSessionId) { QLibrary lib("kernel32"); pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId"); } if (pProcessIdToSessionId) { DWORD sessionId = 0; pProcessIdToSessionId(GetCurrentProcessId(), &sessionId); socketName += QLatin1Char('-') + QString::number(sessionId, 16); } #else socketName += QLatin1Char('-') + QString::number(::getuid(), 16); #endif server = new QLocalServer(this); QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile"); lockFile.setFileName(lockName); lockFile.open(QIODevice::ReadWrite); } bool QtLocalPeer::isClient() { if (lockFile.isLocked()) return false; if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false)) return true; bool res = server->listen(socketName); #if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0)) // ### Workaround if (!res && server->serverError() == QAbstractSocket::AddressInUseError) { QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName); res = server->listen(socketName); } #endif if (!res) qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString())); QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection())); return false; } bool QtLocalPeer::sendMessage(const QString &message, int timeout) { if (!isClient()) return false; QLocalSocket socket; bool connOk = false; for(int i = 0; i < 2; i++) { // Try twice, in case the other instance is just starting up socket.connectToServer(socketName); connOk = socket.waitForConnected(timeout/2); if (connOk || i) break; int ms = 250; #if defined(Q_OS_WIN) Sleep(DWORD(ms)); #else struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 }; nanosleep(&ts, NULL); #endif } if (!connOk) return false; QByteArray uMsg(message.toUtf8()); QDataStream ds(&socket); ds.writeBytes(uMsg.constData(), uMsg.size()); bool res = socket.waitForBytesWritten(timeout); res &= socket.waitForReadyRead(timeout); // wait for ack res &= (socket.read(qstrlen(ack)) == ack); return res; } void QtLocalPeer::receiveConnection() { QLocalSocket* socket = server->nextPendingConnection(); if (!socket) return; while (socket->bytesAvailable() < (int)sizeof(quint32)) socket->waitForReadyRead(); QDataStream ds(socket); QByteArray uMsg; quint32 remaining; ds >> remaining; uMsg.resize(remaining); int got = 0; char* uMsgBuf = uMsg.data(); do { got = ds.readRawData(uMsgBuf, remaining); remaining -= got; uMsgBuf += got; } while (remaining && got >= 0 && socket->waitForReadyRead(2000)); if (got < 0) { qWarning() << "QtLocalPeer: Message reception failed" << socket->errorString(); delete socket; return; } QString message(QString::fromUtf8(uMsg)); socket->write(ack, qstrlen(ack)); socket->waitForBytesWritten(1000); delete socket; emit messageReceived(message); //### (might take a long time to return) } kdocker-4.6/solutions/qtsingleapplication/qtlocalpeer.h000644 000765 000024 00000005565 11570604611 023717 0ustar00johnstaff000000 000000 /**************************************************************************** ** ** This file is part of a Qt Solutions component. ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #include #include #include namespace QtLP_Private { #include "qtlockedfile.h" } class QtLocalPeer : public QObject { Q_OBJECT public: QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); bool isClient(); bool sendMessage(const QString &message, int timeout); QString applicationId() const { return id; } Q_SIGNALS: void messageReceived(const QString &message); protected Q_SLOTS: void receiveConnection(); protected: QString id; QString socketName; QLocalServer* server; QtLP_Private::QtLockedFile lockFile; private: static const char* ack; }; kdocker-4.6/solutions/qtsingleapplication/QtLockedFile000644 000765 000024 00000000032 11570604611 023444 0ustar00johnstaff000000 000000 #include "qtlockedfile.h" kdocker-4.6/solutions/qtsingleapplication/qtlockedfile.cpp000644 000765 000024 00000014341 11570604611 024375 0ustar00johnstaff000000 000000 /**************************************************************************** ** ** This file is part of a Qt Solutions component. ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #include "qtlockedfile.h" /*! \class QtLockedFile \brief The QtLockedFile class extends QFile with advisory locking functions. A file may be locked in read or write mode. Multiple instances of \e QtLockedFile, created in multiple processes running on the same machine, may have a file locked in read mode. Exactly one instance may have it locked in write mode. A read and a write lock cannot exist simultaneously on the same file. The file locks are advisory. This means that nothing prevents another process from manipulating a locked file using QFile or file system functions offered by the OS. Serialization is only guaranteed if all processes that access the file use QLockedFile. Also, while holding a lock on a file, a process must not open the same file again (through any API), or locks can be unexpectedly lost. The lock provided by an instance of \e QtLockedFile is released whenever the program terminates. This is true even when the program crashes and no destructors are called. */ /*! \enum QtLockedFile::LockMode This enum describes the available lock modes. \value ReadLock A read lock. \value WriteLock A write lock. \value NoLock Neither a read lock nor a write lock. */ /*! Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way as \e QFile::QFile(). \sa QFile::QFile() */ QtLockedFile::QtLockedFile() : QFile() { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in the same way as \e QFile::QFile(const QString&). \sa QFile::QFile() */ QtLockedFile::QtLockedFile(const QString &name) : QFile(name) { #ifdef Q_OS_WIN wmutex = 0; rmutex = 0; #endif m_lock_mode = NoLock; } /*! Opens the file in OpenMode \a mode. This is identical to QFile::open(), with the one exception that the Truncate mode flag is disallowed. Truncation would conflict with the advisory file locking, since the file would be modified before the write lock is obtained. If truncation is required, use resize(0) after obtaining the write lock. Returns true if successful; otherwise false. \sa QFile::open(), QFile::resize() */ bool QtLockedFile::open(OpenMode mode) { if (mode & QIODevice::Truncate) { qWarning("QtLockedFile::open(): Truncate mode not allowed."); return false; } return QFile::open(mode); } /*! Returns \e true if this object has a in read or write lock; otherwise returns \e false. \sa lockMode() */ bool QtLockedFile::isLocked() const { return m_lock_mode != NoLock; } /*! Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock. \sa isLocked() */ QtLockedFile::LockMode QtLockedFile::lockMode() const { return m_lock_mode; } /*! \fn bool QtLockedFile::lock(LockMode mode, bool block = true) Obtains a lock of type \a mode. The file must be opened before it can be locked. If \a block is true, this function will block until the lock is aquired. If \a block is false, this function returns \e false immediately if the lock cannot be aquired. If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock is first released and then a new lock is obtained. This function returns \e true if, after it executes, the file is locked by this object, and \e false otherwise. \sa unlock(), isLocked(), lockMode() */ /*! \fn bool QtLockedFile::unlock() Releases a lock. If the object has no lock, this function returns immediately. This function returns \e true if, after it executes, the file is not locked by this object, and \e false otherwise. \sa lock(), isLocked(), lockMode() */ /*! \fn QtLockedFile::~QtLockedFile() Destroys the \e QtLockedFile object. If any locks were held, they are released. */ kdocker-4.6/solutions/qtsingleapplication/qtlockedfile.h000644 000765 000024 00000006671 11570604611 024051 0ustar00johnstaff000000 000000 /**************************************************************************** ** ** This file is part of a Qt Solutions component. ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #ifndef QTLOCKEDFILE_H #define QTLOCKEDFILE_H #include #ifdef Q_OS_WIN #include #endif #if defined(Q_WS_WIN) # if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) # define QT_QTLOCKEDFILE_EXPORT # elif defined(QT_QTLOCKEDFILE_IMPORT) # if defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # endif # define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) # elif defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) # endif #else # define QT_QTLOCKEDFILE_EXPORT #endif class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile { public: enum LockMode { NoLock = 0, ReadLock, WriteLock }; QtLockedFile(); QtLockedFile(const QString &name); ~QtLockedFile(); bool open(OpenMode mode); bool lock(LockMode mode, bool block = true); bool unlock(); bool isLocked() const; LockMode lockMode() const; private: #ifdef Q_OS_WIN Qt::HANDLE wmutex; Qt::HANDLE rmutex; QVector rmutexes; QString mutexname; Qt::HANDLE getMutexHandle(int idx, bool doCreate); bool waitMutex(Qt::HANDLE mutex, bool doBlock); #endif LockMode m_lock_mode; }; #endif kdocker-4.6/solutions/qtsingleapplication/qtlockedfile_unix.cpp000644 000765 000024 00000007213 11570604611 025440 0ustar00johnstaff000000 000000 /**************************************************************************** ** ** This file is part of a Qt Solutions component. ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #include #include #include #include #include "qtlockedfile.h" bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; int cmd = block ? F_SETLKW : F_SETLK; int ret = fcntl(handle(), cmd, &fl); if (ret == -1) { if (errno != EINTR && errno != EAGAIN) qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = F_UNLCK; int ret = fcntl(handle(), F_SETLKW, &fl); if (ret == -1) { qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); } kdocker-4.6/solutions/qtsingleapplication/qtlockedfile_win.cpp000644 000765 000024 00000015157 11570604611 025260 0ustar00johnstaff000000 000000 /**************************************************************************** ** ** This file is part of a Qt Solutions component. ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #include "qtlockedfile.h" #include #include #define MUTEX_PREFIX "QtLockedFile mutex " // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) { if (mutexname.isEmpty()) { QFileInfo fi(*this); mutexname = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); } QString mname(mutexname); if (idx >= 0) mname += QString::number(idx); Qt::HANDLE mutex; if (doCreate) { QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); return 0; } } else { QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { if (GetLastError() != ERROR_FILE_NOT_FOUND) qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); return 0; } } return mutex; } bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock) { Q_ASSERT(mutex); DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0); switch (res) { case WAIT_OBJECT_0: case WAIT_ABANDONED: return true; break; case WAIT_TIMEOUT: break; default: qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed"); } return false; } bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); if (!wmutex && !(wmutex = getMutexHandle(-1, true))) return false; if (!waitMutex(wmutex, block)) return false; if (mode == ReadLock) { int idx = 0; for (; idx < MAX_READERS; idx++) { rmutex = getMutexHandle(idx, false); if (!rmutex || waitMutex(rmutex, false)) break; CloseHandle(rmutex); } bool ok = true; if (idx >= MAX_READERS) { qWarning("QtLockedFile::lock(): too many readers"); rmutex = 0; ok = false; } else if (!rmutex) { rmutex = getMutexHandle(idx, true); if (!rmutex || !waitMutex(rmutex, false)) ok = false; } if (!ok && rmutex) { CloseHandle(rmutex); rmutex = 0; } ReleaseMutex(wmutex); if (!ok) return false; } else { Q_ASSERT(rmutexes.isEmpty()); for (int i = 0; i < MAX_READERS; i++) { Qt::HANDLE mutex = getMutexHandle(i, false); if (mutex) rmutexes.append(mutex); } if (rmutexes.size()) { DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), TRUE, block ? INFINITE : 0); if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) { if (res != WAIT_TIMEOUT) qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed"); m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky unlock(); return false; } } } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; if (m_lock_mode == ReadLock) { ReleaseMutex(rmutex); CloseHandle(rmutex); rmutex = 0; } else { foreach(Qt::HANDLE mutex, rmutexes) { ReleaseMutex(mutex); CloseHandle(mutex); } rmutexes.clear(); ReleaseMutex(wmutex); } m_lock_mode = QtLockedFile::NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); if (wmutex) CloseHandle(wmutex); } kdocker-4.6/solutions/qtsingleapplication/QtSingleApplication000644 000765 000024 00000000041 11570604611 025050 0ustar00johnstaff000000 000000 #include "qtsingleapplication.h" kdocker-4.6/solutions/qtsingleapplication/qtsingleapplication.cpp000644 000765 000024 00000026712 11570604611 026006 0ustar00johnstaff000000 000000 /**************************************************************************** ** ** This file is part of a Qt Solutions component. ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #include "qtsingleapplication.h" #include "qtlocalpeer.h" #include /*! \class QtSingleApplication qtsingleapplication.h \brief The QtSingleApplication class provides an API to detect and communicate with running instances of an application. This class allows you to create applications where only one instance should be running at a time. I.e., if the user tries to launch another instance, the already running instance will be activated instead. Another usecase is a client-server system, where the first started instance will assume the role of server, and the later instances will act as clients of that server. By default, the full path of the executable file is used to determine whether two processes are instances of the same application. You can also provide an explicit identifier string that will be compared instead. The application should create the QtSingleApplication object early in the startup phase, and call isRunning() or sendMessage() to find out if another instance of this application is already running. Startup parameters (e.g. the name of the file the user wanted this new instance to open) can be passed to the running instance in the sendMessage() function. If isRunning() or sendMessage() returns false, it means that no other instance is running, and this instance has assumed the role as the running instance. The application should continue with the initialization of the application user interface before entering the event loop with exec(), as normal. The messageReceived() signal will be emitted when the application receives messages from another instance of the same application. If isRunning() or sendMessage() returns true, another instance is already running, and the application should terminate or enter client mode. If a message is received it might be helpful to the user to raise the application so that it becomes visible. To facilitate this, QtSingleApplication provides the setActivationWindow() function and the activateWindow() slot. Here's an example that shows how to convert an existing application to use QtSingleApplication. It is very simple and does not make use of all QtSingleApplication's functionality (see the examples for that). \code // Original int main(int argc, char **argv) { QApplication app(argc, argv); MyMainWidget mmw; mmw.show(); return app.exec(); } // Single instance int main(int argc, char **argv) { QtSingleApplication app(argc, argv); if (app.isRunning()) return 0; MyMainWidget mmw; app.setActivationWindow(&mmw); mmw.show(); return app.exec(); } \endcode Once this QtSingleApplication instance is destroyed(for example, when the user quits), when the user next attempts to run the application this instance will not, of course, be encountered. The next instance to call isRunning() or sendMessage() will assume the role as the new running instance. For console (non-GUI) applications, QtSingleCoreApplication may be used instead of this class, to avoid the dependency on the QtGui library. \sa QtSingleCoreApplication */ void QtSingleApplication::sysInit(const QString &appId) { actWin = 0; peer = new QtLocalPeer(this, appId); connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); } /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a GUIenabled are passed on to the QAppliation constructor. If you are creating a console application (i.e. setting \a GUIenabled to false), you may consider using QtSingleCoreApplication instead. */ QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled) : QApplication(argc, argv, GUIenabled) { sysInit(); } /*! Creates a QtSingleApplication object with the application identifier \a appId. \a argc and \a argv are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv) : QApplication(argc, argv) { sysInit(appId); } /*! Creates a QtSingleApplication object. The application identifier will be QCoreApplication::applicationFilePath(). \a argc, \a argv, and \a type are passed on to the QAppliation constructor. */ QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type) : QApplication(argc, argv, type) { sysInit(); } #if defined(Q_WS_X11) /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(); } /*! Special constructor for X11, ref. the documentation of QApplication's corresponding constructor. The application identifier will be \a appId. \a dpy, \a argc, \a argv, \a visual, and \a cmap are passed on to the QApplication constructor. */ QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap) : QApplication(dpy, argc, argv, visual, cmap) { sysInit(appId); } #endif /*! Returns true if another instance of this application is running; otherwise false. This function does not find instances of this application that are being run by a different user (on Windows: that are running in another session). \sa sendMessage() */ bool QtSingleApplication::isRunning() { return peer->isClient(); } /*! Tries to send the text \a message to the currently running instance. The QtSingleApplication object in the running instance will emit the messageReceived() signal when it receives the message. This function returns true if the message has been sent to, and processed by, the current instance. If there is no instance currently running, or if the running instance fails to process the message within \a timeout milliseconds, this function return false. \sa isRunning(), messageReceived() */ bool QtSingleApplication::sendMessage(const QString &message, int timeout) { return peer->sendMessage(message, timeout); } /*! Returns the application identifier. Two processes with the same identifier will be regarded as instances of the same application. */ QString QtSingleApplication::id() const { return peer->applicationId(); } /*! Sets the activation window of this application to \a aw. The activation window is the widget that will be activated by activateWindow(). This is typically the application's main window. If \a activateOnMessage is true (the default), the window will be activated automatically every time a message is received, just prior to the messageReceived() signal being emitted. \sa activateWindow(), messageReceived() */ void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage) { actWin = aw; if (activateOnMessage) connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); else disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); } /*! Returns the applications activation window if one has been set by calling setActivationWindow(), otherwise returns 0. \sa setActivationWindow() */ QWidget* QtSingleApplication::activationWindow() const { return actWin; } /*! De-minimizes, raises, and activates this application's activation window. This function does nothing if no activation window has been set. This is a convenience function to show the user that this application instance has been activated when he has tried to start another instance. This function should typically be called in response to the messageReceived() signal. By default, that will happen automatically, if an activation window has been set. \sa setActivationWindow(), messageReceived(), initialize() */ void QtSingleApplication::activateWindow() { if (actWin) { actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized); actWin->raise(); actWin->activateWindow(); } } /*! \fn void QtSingleApplication::messageReceived(const QString& message) This signal is emitted when the current instance receives a \a message from another instance of this application. \sa sendMessage(), setActivationWindow(), activateWindow() */ /*! \fn void QtSingleApplication::initialize(bool dummy = true) \obsolete */ kdocker-4.6/solutions/qtsingleapplication/qtsingleapplication.h000644 000765 000024 00000007755 11570604611 025461 0ustar00johnstaff000000 000000 /**************************************************************************** ** ** This file is part of a Qt Solutions component. ** ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Solutions Commercial License Agreement provided ** with the Software or, alternatively, in accordance with the terms ** contained in a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** Please note Third Party Software included with Qt Solutions may impose ** additional restrictions and it is the user's responsibility to ensure ** that they have met the licensing requirements of the GPL, LGPL, or Qt ** Solutions Commercial license and the relevant license of the Third ** Party Software they are using. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** ****************************************************************************/ #include class QtLocalPeer; #if defined(Q_WS_WIN) # if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT) # define QT_QTSINGLEAPPLICATION_EXPORT # elif defined(QT_QTSINGLEAPPLICATION_IMPORT) # if defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # endif # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport) # elif defined(QT_QTSINGLEAPPLICATION_EXPORT) # undef QT_QTSINGLEAPPLICATION_EXPORT # define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport) # endif #else # define QT_QTSINGLEAPPLICATION_EXPORT #endif class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication { Q_OBJECT public: QtSingleApplication(int &argc, char **argv, bool GUIenabled = true); QtSingleApplication(const QString &id, int &argc, char **argv); QtSingleApplication(int &argc, char **argv, Type type); #if defined(Q_WS_X11) QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0); QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0); #endif bool isRunning(); QString id() const; void setActivationWindow(QWidget* aw, bool activateOnMessage = true); QWidget* activationWindow() const; // Obsolete: void initialize(bool dummy = true) { isRunning(); Q_UNUSED(dummy) } public Q_SLOTS: bool sendMessage(const QString &message, int timeout = 5000); void activateWindow(); Q_SIGNALS: void messageReceived(const QString &message); private: void sysInit(const QString &appId = QString()); QtLocalPeer *peer; QWidget *actWin; }; kdocker-4.6/solutions/qtsingleapplication/qtsingleapplication.pri000644 000765 000024 00000000263 11570604611 026007 0ustar00johnstaff000000 000000 INCLUDEPATH += $$PWD DEPENDPATH += $$PWD QT *= network SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h kdocker-4.6/resources/images/000755 000765 000024 00000000000 11570604611 016366 5ustar00johnstaff000000 000000 kdocker-4.6/resources/resources.qrc000644 000765 000024 00000000473 11570604611 017646 0ustar00johnstaff000000 000000 images/about.png images/another.png images/close.png images/iconify.png images/kdocker.png images/question.png images/restore.png kdocker-4.6/resources/images/about.png000644 000765 000024 00000016472 11570604611 020220 0ustar00johnstaff000000 000000 PNG  IHDR>asBIT|dIDATxy$U?']{onn Vy2=18Oob4(3L(3dT#A熂8 f<Ų l%~_3x8:`˘q-ZYȚl=3O5]dRF@UXyf4O8/M3[iԭD ͈M|8c+_ZZ7`n.Ϧ5]Fsl)B .it F-9C?Ŝ徲gK v0+nt mto+ 1J K<[Y8̥̓\d7=5T${f`Y 3,䕆m|-@OY[ShS?ٔi. ElaېKdӂ"^H'P#h8E;-p;kw%,\@ ;c}o Q||L͗x<&-et`'e9{r#y/s3j"je$K.dH |ưf2\mt`Q1%F?>O5>H7G_W)8<]T3Æ]gě=#s(sQ S|k5=^mi )^o~YU>4cS~$M6mp˹hVv*o4F~x|?c%pN/D-8u e婗fH>/DЂC"hHE;*K?9kgߣǞf,9~ )ͧי Flsߣ'(Y6+qLisEU<<}B;Rԁ>+PϿyj3û]/OCuc02M|xcq^ų-1ؓXaT(_}Gf;Ze Vݯ'7T.D^ӟckiK#%̓s?reǮ[66܅,羮=3Ƒ"ihQPrtdMN_ɋ L-8Ն™/eyK-yov /\Ud҆@ZsH~dDžkoV4ݕVvg-2,i|.2d#sZ8pg<ŧ+& D`^ز?ٶC"1$xn17t#K? Bpʪv6J1)Wp'Ĩxk1@n5]\e˖Cz!Cd9GJ.9#!W%2849Ol+xQ9E)ƕnY q#Wr )^u\y"|92h+XLϗƓ{VЇeK&~ *-%Wljm'Om<{|h 9v|!^_](Xƕ[@y@)9JM }{DƦ !鋎sWnem_X:uI)x.@꾫=[*xug~@O%lYםHTr\7əbZ2J^I.?\upRȵ?;/>5;~6oGXA4b i kX O|FJJ:ב4MٶBZq2)+N%Z&&w5+U܉u xS:ҊJRƖeЄݖƖ'}_ :=͛6ྜྷzfԜ;[|#Wu~=8pARiʙAK+W* US)37VlX u\xSwA&`L:s&gЃ%Fg-t46phȩz||"T vi}jY'/`;B"uв--g7ѥp<l 9^뻢q_ޕ椡sMڅ-naX6$\ *uӖ6rZ~Y[Q,(+ܙtLsyeMM%chgƐ@g{fyxJʬ76nGJ\ѧVgh@kVSVwVnBgG#*SIWGg݊w0:S=ֆX1%k- mF F_ }j՞19qMߏ7ܫz0 G^5x(<_xxRBD!-蹆gbs=o>}Fܾ5`kYqe#-j0U@}P ,kǖ{~ŞWec3,l&{zlQ?cTa(~`T[xA?x:p.mp^ ;B2#U&Ls{6qN=5+#wᷣd2)V-BCy 0I짻PI9 AGtՃ{8řd66nABh?BJƧ9<9 C%k~ڳjl3c&24ЭPTV1KQ$zb7DpՒ;~3սYN]^'0xٍ=/16>KTY"Φ 9Yޝ!m*xG^`baϾi-렻-K'eܗ=\\.1˹eX;zʽ!`jvDe֥2r^*LY?j0G@}[=ȔC"_N>ϵO\Z# /x_p Lk$Oe[:ó!wx y6)Vo ֙3=?b xZ?iDrB\{EeЙ37+R ~dG6A2V*M uRFᡑDxʸ֙1{ )Ma\x,eBJ/DE ҔWgXbjj˭ MӠLƱ01kvOy$B1֢7|hVf*aI ل$ry*N[6 )]D.;+/$Δ94cJy4MAyK̗%+3#Y+Mueo f7ŒEٻi֩u|4]_ٖp`b^9ItpETQ˜tg##J,[lBдVQ%؏;2}sP((OUXp!Zu]`%[oHO.Eo{1.3u?IJ雺/1 8Gx2=%yɼ\7g$ȡ UKI-viKz}w ڎ%VDq w|Vbd3>oX$a U|=dWb\ڤ;gT^nTmV[ʶbNJϲd*o//=v] ߱N|&?cKtf Rޗ.D6U֬.fx[p+Mٖ$yKe#x#R:+F]MTyM[{ƨoQAh Q߁*~?e%d,۽^/P )jFBfʒB"e)LJTnP+h.`%h*+"7h+ie l f" *S:0Ll"CF-|xOPDrfђ׳kH B)k)Y BHR49zh뀹Y }Xr TϏ{Է~mLJ}ױ:F `2a?pHJH6h'l)v|vL_ 7XZ; Q;ww_G9g}D]@("ϻBU_뻒 ^bT4^!$܃ p}d#1I ׏;8dC7LBLA4D@VES |FY);P1x+ )@J$STg%hZf%BJ[h,pi357^uˆ1?q ]OU_룪*;xv^GQ쇢/KE_b 'R<`\H`f(X M>$Mo_'gi յAVQ>fʇ ۿYj%Rힾ|<֘ Tt  hߞi&t5dx`nb+ظ8֖͈r2LJ*:*!|$@]*ڌ2Qi)M}B xQ3ICGkc-%j%,ܺi?5fR >Sf]Q_7*k N]wƭBy,|wڍP/ o2ܯ*iάCT ')|fhVBFzט{g&5d%),І)HS{Ƈ^Y<6fjkјE*6Q7}e%YAJtfJĴ Ajr*>0 LJ %wD"(!5C9ysT.Q+ ,<$/p7$ξg!?[* N E3ӗ(`fbDZF z k1>miȬ7$ư(&E09ԪqbcjDilgxp$I*Mk~MY@y# Nh pӪ2ˬ OkVPn|bw2뱖Y[Qv 6OSdʿB/$+\ <;>&a`!>d ח‘~dʑ/Zз*i_Ba cЮfč )aj V/G4;ѥ` &vBOX\: QGClXjVvt)X pnVQr_RA܂䌥> #K~}#C^jF8} .5+ )mN\ǁmKJCD/@8uq@?G{W: եN mDH2́E߷'RyԳ_sW'v\J덤қ1RIc)'OP?Naq~|:2H܋ZkIG:f+8 $tյm7O;T:WD:; HaS϶K)P.8sFzwH>%dUZе7;Ӽ؈Rj[:AiAJ Z;&d8UiaN~BU8*)AXZ#JPJ;L:3YG2( +S%u0}7ZQqizӫBUXa*0}1Qf47zeN< Z35"xө2qfVL tu(Uwu FҴ[VWQ‹#XP1]W\Ruܠ@[.q@^xY&UUaq P*EW^ k/fyзQ"IENDB`kdocker-4.6/resources/images/another.png000644 000765 000024 00000011507 11570604611 020540 0ustar00johnstaff000000 000000 PNG  IHDR>asBIT|dIDATx{\}?1sgf׻}cHcF@ME ӄHUKi( 44Q[yTDQ5jhJn(*<,&6^w31q{gvgήhǹ=pr=Vp:XjJhhA0 yɬv2OYW\ hi Ё0gjG)r|ቮ" _q+0a>1Ѷh_đQmE \ #o"Z: $B.I Ρ(gB0_܍2-@ EEۺsvlY:bMq }V9-zu2Ra~exbCCK %*s7I 3j ?W ^tıZAX .Nvm頻ڠ @]ut./nu{p7&/c> wP#=gp54$e\։aM7ݼ34 e=Zr NHK@t bNCZ=i&+xi膎hhA@aHϡ[:os)Y>7wsp`}l&~>N<JvV}˦O,XFwwtsۆ2ꜽFx8q0-/!oBo0Q`9^>.44pȧB  %|˰=3`Eit_ OT*^q񵹅ZVa[6^~#ᑸ,nJBK~w|> ]8\>̺{R[@.Y~ N>؞8C`4H؞ΆK_£S~z=z,$4|泿E͸}9`i\vh> `6 Пguq5à imcwl/=.c)Ӗ!UupИ`0 pnǹt vlbn`af!DQb8pSwRu3U %raۀx8Usp\Gi8U'pDY2a {?)! V-| Yp<V3 Oi jɤ%=#199)|c!1M@j)F'Dtqަ ]=TQj1l[4NPljY%G'v"N^/ v`/XXb$ǐO@-'.*o##f0Uuײqӆ/EOXUFUuhhm9Jl9/6椉Ym41\Ce%'tDX*\ ML@M 0==/mۜw޹lܸ˗p1W_ctt!JR9.3y|Rl^*P ^zB[v 4)Sp]=FD^=wGs➘{ؖp]_|0ڏ[lڴ'|^x.\n,y"ސ1Q*m֖<zz+y= 禿_1~~(ʣԨvd#kF1o>cWnHt!fwfTxD M:t7R(XT* 7n`xx?6/IƷE1l 8_B)-fH([dpi rIlJmƨV\r+W166F_l</ǁlA}.~Nndb h_la:h p}M0LOO!9g?dzzjXPv*#[vSf'rNR#>B5fjm۩չ?zXy*NV'mHZ۝yb-Om"a(LAGGGLMMP*-=3!տ)٪僪Zq C NUCa:݋7}X=*&mN"kFFiʕ9@T f=ѣ EӴEK}QZ2gza_ ތׯȑ8p`^٣b1:z˲X~>++Y>EvEk$ i+h&CCw>|B²UumR֭[1MsQT(a{QG8@Vt 94Rj{.P(pᅿΛoHm&v Mgpp 6`Ƣ>@wʘؐC(iCeFz*h_k@'_n4!UH|Bˢ6;Vl}٬_cǎ8r:HOOOmp `]쟈ydד^p/DS>Gկh6J2v̧$f^q× (D5z5}4zi.ђ%}D8zƭ K)4?g@/s+}CЬ@ ͇Q^k5|/͸"@ -~QLq5eO$H ni|v4'ս\:0 o630 on?{\XjJo[K'M ( l$PIC fܬUZjVJQۥ{GC!s%'V 36ڥ`"hߚE $U$@A6KJ ?"RlsKV 6IzNYh,Fù2y^uPnG<Z๭ϱY7rd\Yhr,x>~63LQf/ $II+{sVH5RS4 >Y C,u6(BQ//{lb2@s'O Bo$ >[)SH S3s齇W+&VBTOhPS:tI۞$^gYa~ i$EDg>̶eھt}}]]bC3YZjBCIxy"VJطe߼0H|& ÿי2QoOi$'_'J 8*H:{&# fqy7?73+4M_ J,~ۼn/ }E(&{~VLٴEȹt6;Ӷg'?>33V=V+p7 սW/n@9';wy|q+?ke80B1(\_΀199l·z?ę3Oj]PEC P82EC P82EC P82EC P82EC P82EC P82EC P82EC P82EC P82EC P82EC P82EC Hvw[*, 9ͫ6PAJaBͅ&pA>&FNg!^m w+> ʔcLEߡQbRk:/*¯.GqIENDB`kdocker-4.6/resources/images/close.png000644 000765 000024 00000025637 11570604611 020216 0ustar00johnstaff000000 000000 PNG  IHDR>asBIT|d IDATxyeU%YB"- ̕& 0zYrgi0訣NA/jŽ$"BX$t^R=u;}8|Suԩz}޷bhFI/`?`>öN? R0+IoMTٖk}V`.ź݇e,Nf0݂i>f$/}ȥa {-eN^ӿ@} tbml8#]8,aGB&Y!jMRˆ7xNL.ݵl},Rp ]/Bھ@|7m y->0DzV쉐 :ȃL~$i[\/ANIۄ> |́)ڏt@%ڄF*^'>u >rt&ˁ$@ gۑӔ]!NQ `7-Zrw~7mAFESBg⚺;E"r"-m[ᢐk(Bߖv>4te.~,&tO:N#HO0,={oF/طi+׽zT†:0'c"cA1}N?‴X '(oL<{.=ӍJ GLHw'~ n܈/-^Mؗ?W6ĸ/n nN눓4Θ/f4)Q bO_;*j!'=c.E&L}fkpN[K2O\_Oˊ]tNq}lPJ8 'F v1F!aK?Ь@N`mNka…Cޠ= ux߆ + $P$ v?L]:D4mCZ1B}YG4e G~LzV-Wpd3N X\D84|bcm0|ug([6>!f^}5DMVZ3070gz?*H/mEI[Fl#: $(w8e sngTMH osݻ+$ j?~_r%AS_ !ʽgSSOo$\SEZZ}lcK/ź% CCZ~ßax 3%/YXbDn?L[ g5"Eh}iv>@l8Y9B"(28@is |Ýn`ܩ4~z.:}cg6"EXTMhwec #QRamCƬ2LR n;q* ҶEܺJBZH' |? ,NJ5ĤΣ ԰r=屄T~F$ I ~? )6eЕP&}6tLx^9T$蘙6bg'^O4 Wh:n p &V)3ytVaUxx x'j@u ,\yaߨsX ::bQbs#`׳9F9t5{р˜ É5&o._}dܷ}/ V5lT/28d҂?8|gMekT@5l+_EǡX,H:{J\#oY:Z $u)l^19vZ*C%@47XN~~INJhXqpE[U9L+M8xϣ{ƒ'=F|q( 8nD9^K/8}:ͳg㩧'g DL+ĺRd^B] / T#>=hQ_#0q} h9t2ӦUTeQ"B!l\ ]'p3ӌ N< {Æ D 6l(%\^D@9"h1LBs]jꪪ:9yxŸRG@Ꙟ0ܫ{v "L 5t0$@Z/o7P~OX@Ǔ>hB!lBb&|iwʹ3L&|2B SnV6?ށJ.ǡP,t,s5zt7k-GŻׇ$l_+)Nf(|@m K)ym3~"T*RQ#*FԷ,~CjX%,W$ʋ#*Qw<ǘяK#`1ǰG]\)-'H0ys+D,㨀4q<( $04h\_+4f≟"@i3'ָVϗ8eq֗ 184p!~s%OV[㐏 ]kk/[<ÖƍBArDzmݻKHQ$88z#I9ڗ΄GmAC&(~5G=!\n`qPY~%dک?J`~hE|<"b|>1y_]7"[ffDz=Lv bH[VDn@qǎ%T2(/ 70@o.G.&~Âod7L|O~ðإA=X;;[=ASe:t~AkV҄q ^tMy< "Q "wl[ kۡA<12|8y`"W IƮ!^/=;yG9jF?~婧$Z Ku)F=oşlM 0{7?R6m"mYdlq4ͩ|{{{ b5To`p4f(3ԡ%1yX|́R ZGWU|q*f,o< ~='\|1uMM]iH2笳7x)F$P}so&ǫVѹiTͶ8Q+.;(l^ I"@/Q ?`R>pNT2݋JCKxR Ty vv#p%Ԍs>x';dwK.aK/,#'R4R{{Rx!]G^ 8|*!@O끆¼+xsWU|?Ǯ < , \gog'ׯ礕+Ԉ/&xq ygM .(mZ"oIh0Nݻz)rJ}Cy8e UA( 9 DB7 w>b1U"M$ nz:;yu:NYf$8jbb9z]59' ٱqchUTqN"Bgnl"(h'ߡ@p} HMS5WRrCux}}x}} ZZȈE no/_M=ĸɓGr_C![˗ӹq#uE&GX4k |*8#Txj. |xbil$0ɷvJ|g.]sTld7-?l]w>fbeE qpwٵ&+(?KWp+ S,K5c4CۋMj> > vtpϲeD$f . rdBX(޷wĮ$2qsp ~/ `{a-X$O}o/r9ZqAP" ҥ YҥAJLp]s9z{.Gݔ P1p^gRFfc0XqhG0qBzphDyi7l̃z O|16P ag58h_䫭fVb `ғ2VC9q *ޥNyIKQ׬'L'E a֎2$fJk+[;:J#'DIF;\ꢌƄ݉D0&0a:G">e#7F߿ƈ,_lmF*ld4E*`X% ]2@"A#a(PnvnϖbIЛVtt@tfxs$cCUcbV"$zƢf#jHִoH/fGG]@Y( WʉPOӲחX95(g~x;_#@H)J!x'J8P7Fh$"Umm,馚_M7qe[[!T,9"LؙDs<.~ӧ=@Ymm\fͨq5mm]?EΎJ)5R r(v0"WC8Gy6.E\f p[.!!R\ā"&|uOl.Lh nr*97&~2 @$.mk1_ K`Yx챒**c{J" h x(t6Wq_EQN $8h@d*:'i*WЗ ~IZ?Oh{e2qA ~ ܠ֢ aPiCR-aY B0@hkcA p붶RwUJ ťIƦ$"<7 |Dp-E,_ ,1,@&%ooߙIQMc ~?!}gejkC5ۭ|s /XeQH2yO9*P0G#*wGpltb5VcuRX,kkciV:;:vN첚y:E6T_"!l }W9c!@ju@+av@>BWVK8Ck+]vN@TJԢ<w}/|BX9DTPzRXБWߦ(ֶ6Zk Z[/5]]VୈP9b'g WdP9BXru@fL## Q*8d_F3EkHy 6xiXpDĵ= < d^*[p dE)r9%mm|])PNvN@S'PE 3lnJb"@ .HxݙုF`H햴S~g请UPcJ6 e_HK(79$ j9n\ji=?{ |9xtY%Ln7X ZZw (7%OY8gWl.j.)!H0$@22.>۰V*Hܕp^L,4),!e5,'\6+KU"uRcO0{,5Z`8-E!`)z5WzeP|~+eRP"=$f7E=B7|9$J{[[ըbx{^}+ƣ#PYQN4UDk& { FW\WRT_y%)lGn_YodJ,NY֭qʔ1<~z5׮ł &M+ +}-LJblp O;3NI;5?6]CW'e[ܨE/_'y'[Vm <~z5] JIDATKaj 4<ݛ{LIF,[>R` tj.޴͛9f*,{㍹l[[bCNᖯVK{eG{r+UL\uph1Sbb)g뀮nؠ'Jj?!Y, "z}Zڇ ,D1?t]L som%?DOx^zN'&1yaE"嗭tt7٨D=建<cFV[#"}p.ş/sOM1\[+Rs AO$OP2͵kY/X|QoswG@/#z!-@$MV遵?]}dJ8=  dAG&/M,`O s^e lœ`{{;sV/}kd1\}3$NJ񟁋.IUXD@yWg=b" inWRP2Kۊu͸}}N(m _) Rrs-s,ӥRl6%2J!W,EFK[>I[R,$)W(qؐ]R?_v 3k3!3ۤ_Pn'? jb")y$~te@ |p^rdE tڄYzځ~Q}D%I`x٠t\Go6R j} XB"1ց1Y D,$:,_/hY@'-Xp0]4YɓCl$pKkegYty>x9|ԉX)C ,gpA4_YoCQ{iMUQs"9|F?dׯd80ؽw'lX uo6vvyRi-*$eeg0'~E?+oQ~Gư?)?"!,x@q IlD0&2ۗ_AqH帯?b8, {[Cd=LN$5ٕWPrE$Tý:u/[[trJFJXOۇASE I=KahwC\Yj G@-K/9ZRnx齰!=4#9`aþ` Kk׻sug)kjwӄ#t|^%&<'u!FD$tmxP|PYѫ|;ͯE߇׈?O $̫B^h_ s} 4WI-I$ӻpti h]ZF ^\Wn [w5Ƙ/<3 !e. }@$'-Ӱ)3x=֛f)G~I/ BOW׮dg2Ep9pRDd3,U=z 5p„3dUؘƒ$3;`7টV._vF|uqNU3 IPZG@% %cLJ70 x= !>p$kỔ~DUh@W޳̏䃺O_;éH/JW{$ %erY jj_OpVQ+t乥T FJ8ppnfMVO[Ctd쀗5 'q(>vGFz@D[K3aTt/'~T)T'D_rF nM2PIJu"ĖTTI-.tuMB awU$?f._" r}*~+> 7St`l${`ߛ7 c|W|c"cIyMSXA>8[OKdns΁g Sk>tw;Ô8M@^ʁ `D0" ?0=lÒ$(mo.~0\VY1JPLk}Âp ^ػeafx\|ij?IS9P"C6QV\4Ni3aT 3ТJ+7}}нow^ST"3Y{RJr@`!TWSEV[Ɗ^,EWU .H1uǫbjt0Lf\ "&+j5_2WjDH5U^N)Idۃ- F$9ХJ2 fm\EA>+A! .,H I?T%8~IENDB`kdocker-4.6/resources/images/iconify.png000644 000765 000024 00000005563 11570604611 020545 0ustar00johnstaff000000 000000 PNG  IHDR>asBIT|d *IDATx]lUq$v>h8QBZҦ]Aª+"E (b[ $HHEZEVkAI*ЇJmC4(um;>8Svߵ&*VBPx8锂#BP+o-@)kqq%f~~~%`/EEE}H`0e)IfQp:YO\D"&'bqq1ITWWA\pdp8q߶/a?HT@^(qiڪPǃ]ӹ`0ܜټ뷺NZ@UU*Εw.ˉSϗE뷢 ( UUQU5UU\>w[>Ã?EE.p(cy5fhUOo[P,p (f ^U!A 8pDSȯo]{C {UUQյ)+~ 4)9v{ 0{VppA( u:\Ey'oU{O++#\*bݺIO˘~/''w/ԍXGee%e[^X@ez*+ݗ_뷺=!#@ P  P  !$Q8@N PSSCMMM}X@#PH8R@#PH8FQBծdP$HQ4?$ @Cr k"A?+rA[R:7gVz?@1[2_']©fbR>tlX-Kл &z8|E}}"]Lʠ^o'q_{ +ŔD{6=uV=n5 O_X̢&X9p1/=&1B& A6'fwO3W/qH@D{Atnev4:Ml!.SlDښN.S]H,@ (e=Ԕ +iqfuS" 3H4Ŏ߼7í^[٤^!0cWJ%l,ݼBM35$QFwo4܈_x[mXl'XtA<4cftv_/} zg#O:j:w-vhi4ulc{iӸBzw+L@s-bzln_/^殙?6wGmnK"")G (p )G A>Fw y (Q#{Mۯwo|2|-`PZQOOI@etA+\X !u2?ņmBHX ?d/B/Í2㳫|vN km3Ŏa~巁Ŏf3vJXvu8b6deێ".ڒ5x-O?o:v0W;/osqg2v}۞㫝M,@k뾺2h}W%dlc,**v|]M+"Uıߺ5X"j-tm91־t: \%8u}!K7m莏P5+_ UQ9㣄WFEpL KDӳ<ԕTWm7ifQ6msQTEdSO4=+ŔlJX7n  J={AAbBlps[&Hwalή1zD "f61lK^9HSWM]? $#^ `+%dEuDbwH,_M?\9%@XC:p.}&/4 L7KY@! 86H2F7?̲.@"H$D"H$D"㚻p3IENDB`kdocker-4.6/resources/images/kdocker.png000644 000765 000024 00000036351 11570604611 020526 0ustar00johnstaff000000 000000 PNG  IHDR9Q]bKGD pHYs  tIME J IDATx^wE?=q#ld s*bs@=)33(rs, wɛ`8;G.;;ՕWU2$&Kل?\ |k!"gʽ9Zfeӡcg4!(Nk hjcuZBH!+K+嶲jw%k_lLA ʚz,ߧްRR.%0OFR5*AMTU#lymL`eBJMH4M";s+؄)qD4C֭@Z̘c멘6MȄL`[Q,ƎStr&ye)b"kM5`cmO s#RJyjj,x#(~NRJxŅU^x~vr5lw;gFoסeU5[xJ.~.;wt'GGnTJ,J*Y] R5~CaޔG&+Ghi6G1d1@6Lj ڴkϿ9gvVaSa҄T޹ 5K&(.O琴s )A=$ 12IfhB˜94Kø{ă 2 P8[B$cU0hp l@Rf.AR^;ON}P tЕ U`H?5MPU{~՛(~mٴ&/ NL0>4"bPHl޸>?e/E=t[vտ2kP +T?kA (u.t7 xTDx ;`J JR2P/@m;v =BJ*zYOV  ~g=T;ӣt=+jh5xe2#t7ݞ4nxl9-t{i!I<{#6k(\j:Q ~T#({}4ҼQdy[GyVz6ɍRR?A !aC9yvl/.~5 !$^37Q^>]{&rWDqP[W<7B$I!B +d/9@I֕7pԩ7-S/7'@J竟ךUCXe LvQ]鱗KO 7.]@-k6s9lE5jdGEo_>*?CyEtϋ+|ϖ[hGs#Z<7CffFz$--!VTJIӬ#ijBMISxhw]H1$LϢ )(NwPŹ7K D~D/!d3P +ѿ'ǔ u.z+;ThRtrQ2`4IFx f?zBI<;!*TUf/,S "]S,LvR֮Xߧv,*~x\19ڮg,N @{>ωLi#)vl'<侃 @-xَEs͝m TгS= )6l6BHlKyH㘠rn~hS(CEzJLj`52]/;(6Y'꾧3 ( > -,w[GU1D 5l2i/b6g>s)|_hm6 ;;xRj_myx?xT0Qff8vh߾x$/4MpB ƽtM+zMRLsF x=R!AUxMIQyV.R+Y EHy$ >Rj eej0U\N/_ŕ3/Я_/ǒ"cek۶5ʗ-_| #ݲf3y{XP;>$g I6'3{bDŽ ) ы}p؏U2HOd&Ky8u-&Î_[`W,ch;'~MVKU<54v[֢+9t?2uwM~"ͦc^rOm0lU|/HǏneh*j-g.j|`lج1q^ulUC"=tdlt|  tFπO#9CJ:Pߔšj 'h Toj쫪pv'r9Q[H*˰o~ L]ujNx(]s2эuڜh?S;I^H$-б$Ӷ'@F\[o& AfmY[-'n8۱haPb `a <*6le<04B۩kn6Ksv̜;@w1.CVrz" $Q g' {(//c[qG76)Iqْvxcr|Txf@ͤyȔXIsA6_?_˞r;nE/|KI$']'FZt>f ^69H4 J0Ơ1)zZYLC"z/<NJIπ!|w 9Ri|'xDM.fהu0Hg&؉:2Hf2I$Vn_sKPFrZe27p))l!H^MCmx,PDZ{yjddOeM5̘GTG#1e v=t.g@k QX> +#DHa%)D1&J}FRޚ%QEC$x*6(f*$ %B(2l#a5Uʈ_PaQ1L &A=5j*샟ޔq36fsѓtRi& 1!ep@Vv">97. &]`"N(M *A@% BkuYȐ_i(big|DރGT+ql>?|igϯE|tZP@O ÀudsQcNՙs[I$㲥D]J c&DŻ<VteTHt:&cNȍʠ0't٥$i.}Wc w>nbgژp[~ !)@)\1~J+Mr{YT~L<UL?OdV=}F+!PhY!dNg|^ctFL,Hr1o{RpR dT,X>]e//-+,aHũi._.WT4.XBho0=gK,WUK/X2aե/Jm׮= @yo1V(}ƬO*o%37yLg$shF0}IxPJ)Ǐ8H!4M|`Z[n^:I@"lYz~qv)[1Oi2TT|#oܢpx!(JaH8\|Aʅҋӿo[*y@Xb O,|K >9=y;`}e{qgxݷThu1ZTA裏M^맡Gr[něS7"ywzLtn?=)x 7ԕ¾"A= %L[=+/_^\'A2{r矯!~SO{6vm_ӂ,::uiTW boWm}l4AII9He‰㜎 VǗOFީks_9.ͅӧ@ |}G0Ϝ~4Iw c)ڟ{r2n:&Ns[[; uSWȆAG'_;3y]pzJaC`CP;J/WT꽁8Z %qWl#-5mUEU?},Ej<JKuϿw:SNן[">j>ՃRםb[ԟ/Tx$z}w|~.{ldU^uBkwE[ 8],</_ekTQU ~v慠NH&'w<1ry [gbژ ÂR?== p?O(Mp␃4")ɍMLl Ya6H$wr 8Qxq+>3g\ kS%Y829+.S#77fG"CJYf9<BJ6lȋ _Ԅ>'w:S:N B۶GѪy-:8al6ٟVETD^)_fHr$q̀08SgZf~d(p@4i]Li*h|.y>eÌ_hlۺ -lirӧo_>k4!X{1yo*:>}X@а'j[@&x02hr LfIIl>z&K7gʷ@|Hy!%RCݬWsli\<^5Oj7>l$@QCboE" /pWТ8쇮b}WxG`d.1+ԉU_aUMI7 [I&&V-u0L +ŭ&pؤ0.z;ShT ѷhu"T,VuN-6Rg'~4s-yz|CIh|]-Re]8.% i^?(Щ m;`>KPh٢_Y')B`2$c1OTz#>isTr# |lJG7ёv1p_7Hp\Fc#&.GgE8d 2ޮD)_~ff J/9t`WC3F\M/"JYC D 㸂Ӎ@B:zwJ,9Q uCQf6GO2'a'EKI/Љ^NYUNW_eEk(NLwqx0xCv>p~g(ĖV%qR:@'DRr̨^Oڣ ,X *ij'5lPdMgIл9SR6i^Q\PPlPQΜ:;c(lˣIQULZ\dg0 +6K2fcd t pЃT ";u~Zꨣ/54!OKB4gb҂ j]ش&wH %@@x!y(Ba`ȡ;/ZD#*!d#Ж#L zl'((2$(Q:4Cu.+O\Evh>'A.Be^mֳ֭N%A~a.Gjk,\ʏ;ƳAw8b j淰cd̡W-K|tJxbiw7%ܺ( ~@5,s4[|?f< bޱ{[lbT[,V gFvCC3/3ǥQ mۡy<^Apq/^re.uOa،Q/FƍLB?2CyR}}RJ!DhK?0Åg0ve[lE2ΝЌSc%خ]D>2%ĥ^Y<| Z2dAI=Ց3+S+HLkzW}.ʻ~CWSS/ܾ*].׫My0 W $id4QSpתjW:^_r4Zх=)@P/엽^?;}@,QӮ߼hKnBeg OY)aͼ|^MNG#\mѳggN9弟O<|YY=4WqWcƇgNq%%e]ڵgѭ8[i,2R~??4IlذRRG%enS =o}6˺;u%6Gk.E .X͸3RнQddQ]]RK &z@@@%;#mIZx~wǍAqu"Zn݋\+E4:L#``'nUq;,]Xͩ2hPdp>|hۦ5< nbP޹2A^?-f10iRSGHn\|A.֑sOaO/ 8< ^A3/wS.1-%Zr:KK-6BO˙|ڌ vNyjIDATࣺZIвe:UUu[C9JM gi: ̙݀ b'(m{5m_B38)m^J,f^ƞ"TO];̧mk:K,m_}5?|.G+y;s,?͝G w=yIe;jq}8%e__@Wx|A}AKf)ΪRJT 8:۶E4ϗau I?cu[).$n&BHMN%Q/P!FFFZ_V ;ɭvi=ؼ(jESihK^=dƈPVySd/7^TVVSz ZI3nsɶd! \ԩ4hD  !"3Z&H ?f=10+y@MF$b׋Dp3YhcF̣ߍSřg'WnNݞw61*}zRvQ+`?`K<N.8PyaOʧPWۨ wh8n̲obOn>;sj^7oo}&Mf1axF-c*]RӲŅ3t`}U|p:dVTUn5_}=ۼg̚RƝ LpVϤw;wm !}LVN'jb+|>sZ` X/?8-; ~q.H8k'ܵ;w>vCY͎ttpܸnII$%%v pz_S23*VL8M!&UUUf-@@ Py'n:D^GԔTsGeLM|7@GJR,Ioтz1>TT gulػ׽v^}8h9Tg*R"//ܼ|QKrGLoNC$;8挮gW,/]ƼsYR_jC M*/dUy!//aߩeWu=`WInHl98pW]OVvC#wөA4xn͌_$6"cxׁ:@Pĕ :磼r H(.pׯM}cN1ur_:565R3!)g9<* >7C.Q /enB )[I]x H +ʖ1mի쮋_Plz]q|!LHYH ^a1~k8`<*Q`t s(I-rPUݻwR^V]yylw WiGcW'_gOF@cov4#!8FE1ՊM7 ,, ](-+A ɒ^,^5)ǯ3'0'vlrۚqSf*}R)4PP(@Hb-, v-x6[~:`ǁ#F슓% 4ϔkh`&_0~Tn['JM1*VqZ096^}[1{ %Zc9ccWxaPU]0j/y~GHG GO y1>@RfKBgP4pZdd_-188>kJϟ3fpғSo"C $iOγons2ѸE_$uB̏!ش{Lb駩w+ƇD-2ZO. mmOb9iѭۂ! m(>V,+. ͩ`(FtTxcofhs/XfZi=,Ab'tVB;t]zϤSoU52cڞŪ c5`5ҨD8v7re>< /,ee|qgs 65[Bb1,L%!1ۇB~2B m_ԯ!s +6]zn3J>JqCQ=x J/I.}6<2>Zpr7z-}aB@g XG̀Pب02b/MXYe~ _aСs }&o3T|s۫q$t!iСy:25X" 7fjTpDByaj8TXG O`ͽ݁[@VR>k*:23Rܮm(B(EEwꀓ(.$z^bج >8fKya1æp`7^̂I#Q0X0?73;wR2.X#|E08ogp'i~FQ(%aDbVD9_J'c0a(_3Sc 61G(&/@"9`V[]µ+#\Ca0rnyweX]9LJa`FC3 {HLhdƈRHBDHHLǝf[QkXfM`D~pdLHpNx\I8`$smE!5=bSe%"0å?|12x$Ps;6y-0JnU?n^J@#[(Һ~ m0I)Gӄ~b=*9mF۰+*q;h4إ]Qq4*B:=g\g-h,~r8ăDM BQ!r+U&-,Q hBAsÚ@'PXlްUUQ[Ē_ 8m.6'NŅ#lp(o+ P2pafzHTz6]{,fs9z_$>PB3V#%)<u!}}v-%|v ?ADjFĎe_Gf0HtД@Z/('ta(Ix 'r'6\Mh -)C 7RE.U-t~;6+PLi\x>`"HxwcMNFӑN`3 ;~i6s?P55* `/դhlJG0kftsa Tu]=8lWW\@;5nk#3q9S]`2?P!'(:C`x ULSOZ{l 5$rzЊ8&S0khUfqLmfzţfB_0cV-_g2ѻiDo @݋("8PJظT%F˂h7ta|O =1 =?+(cC0/4R*B΍OF.a ϳ6hZGO@P=A70N\NƁnR8 j͗PV걊J؂U` IKK˯vTU;}* 0&Zp'W29Q!5hlGlCMx?)"I&g,99_n۶}\jjtmx%`,hاO/^yy =ܻ端>~xtrIK t%䷷aL`u^p_M"Z4`0 xᕵv Cl{'M.=6\yy83Wo:؞f`#Pl~'[(13~z ,ql@*/x$h5vW`b$Z6l!,Yv]v=p($~?g>KJ4t)q[0rܹMś0Jc_q&u\#HWyo̯=b|H\1i]]@ VBvvmi^-R@RJ֯/"55vZm -,\qƩs);}͚Ql lDkrP!Q7pſ<xL#;;SIuvSD?bpl/.|ABQ]S[Eu#0p>AU DDrCgTpW yzyݗF$*VZmך^v_}'1i19#g1q6F(ۋ iL}=6n,FlddЪ#GdX5 ZAP(Ԧ%33UشR߶#&B,]O}[6u*f瑇:54xYZHTMu WZ[=]tpYƅd[тLL`yd#asNg}m1uڻ$'3Tٶ)%Bj5`~HhIҮ?aEtv.a?װ4.]zNiV~fm㗹 Xv3U A슍T7¨о=1^.c" ñit8f[-^99˹(v֛PM28/`P#Tۇ5~h[].JJvKܹ+g}wZ r&8ZN ?`k'[ Cݻ+1c})n_oL}V&wP:t ѤƧ%ђRMaǛplxˏ? v$B3k:ҫ[o%GNAֽ !%%`H#Q[/h￟g/2v9HM. SR ?6+&7,9L}Iò>]%>\³y^HTj:$d.vlE4E3HNoI i*O?/>Zrr[OF/Hg@$"]IHp"m6EuTb9Nygӯyч)(@i:&\>'(H)5j6¬YKi\z/]o{TVQI38!&\v{ǜVԑ8 RPpIx.JJN//se?;gH@JiS{iBBK4#hر'P:WN"4PlH-)-xY]܍56y{v"̜5EKvpMi"=<߸8ءMom啩ﱡNeA鄰 7͍7zVql~"ڵkT{+\5o- G5v،M¨c޼E,_UhBۂfȡic~FUUƝ98PU>IYyk}獇={ٰa3eex}~R((ȧGdg-=[Y !E_ęMc&p1F0kasRGBbKGD pHYs }tIME 6 IDATxmhǿ;tk.륩[>!EZET|D R}/}+E}"RP`sI&ݻXn$vg8afvf    ",H50̗JMx^{t*C"GG®'<@6}=dxx8ӳ w&R I\m6Jjpce} `P,zDՕl RB_$ "J4M#28d5("*LӀ$ 岅R!BT ۮ,LOOMӀiPU je#ömc]סi8, |ey¯8#A@az:3UUՕsb!/ed' #ҐǐM`jgdlYѺ @,&&&88G0!2FFFl|YfHSSf݅ѳMiINwCUզ%IBg2pLMM5Օl*3Mm@4 2g//>( ¶n>0=PT mi*Eq<=w,3U &%IU_02ea,[^YP*_.sNݎTl 6L!$ɿ{Ul)Ih+H[/38ceLض *%Ilۑ5)_[xrJ]aD@;ߙ-hPպ{/(FEQiR^EpRU h JJ)M\۶|Pv?/d 4MDed)IeB(꺁sϘ`Hٳ>ѡjSS-Ex}acg"l6bR4c @=DWŹsg=T*ݴ cck|:;d˹?@9sKooG- vAl"o¹8wZ!`1(7;.R8u xYx] /k Zʼn~xQ`bp##[ϑ#7:˄?v8p5@: &p<04/{R) SsMk̩*;v8-or~ o)p 0mίuCmùa]Hn;{|+~+hY'ލsNoN༳ӻu%O400px}/@K{8Bp֭Dǎ;w.lg$%q񸺭[ڵ 7x _N_zo=-%,➖H_8\vdS˗68=Gr.^c1ϜϓFA+ӧi oao 6ehoW7w=$ @Xx=}&g @@=T`/ũSw8s|76nO@('O:gxMx@I{7$7wN {۳x_. Gr zK/ q$~hL<=%$ÇVviP~ l=g xmh`[ lUe&l9G'+{~rODKl, z~(|Wz/ asBIT|d IDATxkSY?䥭Ock>ka| AFP7B RtUx\XFP e*B*hQ4MrE^lӼsoL} ޜsr~;'{. EwUWH Hd^A7&CЁ8f("#:0!p֐6Be^qHU 'sc=7W!#i|q t"~uX,6πPgo_|>7XA_*"[)ay4x<STI&Z9:\.֮m-hD$ePHƆ%Eh^t lE1= @4Fx> >|.?oYzhl"+4Mu .d[[[]$ZGyH̓HJT?/:>&H$Rói6Rbsh +fUb2.V6m]~PѽPڕ*~:DQChhh]`Οrz}3ϗz<^ `_+--~=A<>W}GsZ_+_|۷d&iiiA4[_ hiYCK˚UXm:eG"C D"C D"C D"C؂aeRLNmmmU.B pG p򿯿Ʒa^6nB  "%嗒aS.1uRh U)cc>|H^k;tlzL] |2Dӎz{Ltl,<@ooq~0\Ao0H/%zz+%a:߿Ą_.5M' v +k_CN+E==!(Itt4-v&_{;_-9oCwz{s!_ \›+W_P=xW}rB2aڵm는k$>+uYL߸A{Njય'=7nTL|0!4X"܁[o"xx\g[iT3CB-U/=y.eٍ]#;;-ko7k@}J1wL7pKؙ-[_;-aXǏmܫW.)WfۖHGnBOdyh.ӧi6_E+0;8<}qN%3o8hx{玘 Y޹c*FJ2Ǫ,^⃺FJBx7tu-CLKco0<"X ;ƶǏiٽlbO߲{7?&xXtرcɱ;t,u7o *~͛ykjwg3Y-U]R8S?n_398Hw- "c>Tx_Dtk0. g_La#5Y]5  ySHF"J- u , 5kUM2իL J[&GĊ`P7W)<ɓ{d:wL2y႙H&/\(*~&xw./N$6LA"##ӨvHms Constants KDocker will help you dock any application into the system tray. This means you can dock openoffice, xmms, firefox, thunderbird, anything! Just point and click. Works for all NET WM compliant window managers - that includes KDE, GNOME, Xfce, Fluxbox and many more. Created by %1. Updated and maintained by %2. KDocker Usage: %1 [options] [command] -- [command options] Docks any application into the system tray Command Run command and dock window Use -- after command to specify options for command Options Show author information Don't warn about non-normal windows (blind mode) Don't iconify on close Maximum time in seconds to allow for command to start and open a window (defaults to 5 sec) Dock window that has focus (active window) Display this help Iconify when focus lost Keep application window showing (dont hide on dock) Name used for matching when running command (fall back in case command is a launcher so pid and command won't match the window tile or class) Iconify when obscured Set ballooning timeout (popup time) Disable ballooning title changes (quiet) Remove this application from the pager Make the window sticky (appears on all desktops) Remove this application from the taskbar Display version Window id of the application to dock Process id of the application to dock Force matching of command by using name instead of pid Bugs and wishes to https://bugs.launchpad.net/kdocker Project information at https://launchpad.net/kdocker Usage: %1 [options] command Try `%1 -h' for more information %1 version: %2 Using Qt version: %1 Scanner KDocker %1 did not start properly. Could not find a matching window for %1 in the specified time: %2 seconds. TrayItem Select Icon Show %1 Hide %1 About %1 Options Set icon Skip taskbar Skip pager Sticky Iconify when minimized Iconify when obscured Iconify when focus lost Iconify on close Balloon title changes Dock Another Undock All Toggle Undock Close TrayItemManager Cannot dock the active window because no window has focus. Invalid window id. This window is already docked. Click on system tray icon to toggle docking. Select the application/window to dock with the left mouse button. Click any other mouse button to abort. The window you are attempting to dock does not seem to be a normal window. About %1 - %2 See %1 for more information. XLibUtil Failed to create XC_draped_box Failed to grab mouse kdocker-4.6/i18n/kdocker_it_IT.ts000644 000765 000024 00000040576 11570604611 016764 0ustar00johnstaff000000 000000 Constants KDocker will help you dock any application into the system tray. This means you can dock openoffice, xmms, firefox, thunderbird, anything! Just point and click. Works for all NET WM compliant window managers - that includes KDE, GNOME, Xfce, Fluxbox and many more. Created by %1. Updated and maintained by %2. KDocker ti permetterà di ridurre ad icona nel vassoio di sistema qualsiasi applicazione. Questo significa che potrai ridurre ad icona openoffice, xmms, firefox, thunderbird, qualsiasi cosa! Semplicemente puntando e cliccando. Funziona con tutti i window managers conformi a NET WM come KDE, GNOME, Xfce, Fluxbox e molti altri ancora. Creato da %1. Aggiornato e mantenuto da: %2. KDocker Usage: %1 [options] [command] -- [command options] Uso: %1 [opzioni] [comando] -- [opzioni comando] Docks any application into the system tray Aggancia al vassoio di sistema qualsiasi applicazione Command Comando Run command and dock window Esegui comando e aggancia la finestra Use -- after command to specify options for command Usa -- dopo il comando per specificare opzioni aggiuntive Options Opzioni Show author information Mostra informazioni sull'autore Don't warn about non-normal windows (blind mode) Non avvisare in caso di finestre anomale (modalità cieca) Remove the window border Rimuovi il bordo della finestra Don't iconify on close Non ridurre ad icona se chiuso Maximum time in seconds to allow for command to start and open a window (defaults to 5 sec) Tempo massimo di esecuzione per permettere al comando di aprire una finestra (default 5 secondi) Dock window that has focus (active window) Aggancia la finestra che ha focus (finestra attiva) Display this help Mostra questo aiuto Iconify when focus lost Riduci ad icona quando perde focus Keep application window showing (dont hide on dock) Mantieni in primo piano la finestra (non nascondere quando agganciata) Name used for matching when running command (fall back in case command is a launcher so pid and command won't match the window tile or class) Nome usato da associare quando si esegue il comando (fall back nel caso in cui il comando sia un launcher quindi pid e comando non corrispondano alla classe o tessera della finestra) Iconify when obscured Riduci ad incona quando oscurato Set ballooning timeout (popup time) Imposta durata fumetto (durata popup) Disable ballooning title changes (quiet) Disabilita modifiche al titolo del fumetto (silenzioso) Remove this application from the pager Rimuovi dal pager questa applicazione Make the window sticky (appears on all desktops) Rendi fissa questa finestra (apparirà su tutti i desktops) Remove this application from the taskbar Rimuovi dalla taskbar questa applicazione Display version Mostra versione Window id of the application to dock Id finestra dell'applicazione da agganciare Process id of the application to dock Id processo dell'applicazione da agganciare Force matching of command by using name instead of pid Forza il comando ad utlizzare il nome anzichè il pid Bugs and wishes to https://bugs.launchpad.net/kdocker Bugs e suggerimenti a https://bugs.launchpad.net/kdocker Project information at https://launchpad.net/kdocker Informazioni sul progetto disponibili all'indirizzo https://bugs.launchpad.net/kdocker Usage: %1 [options] command Uso: %1 [opzioni] comando Try `%1 -h' for more information Prova `%1 -h' per aver maggiorni informazioni %1 version: %2 %1 versione %2 Using Qt version: %1 Versione Qt in uso: %1 QObject KDocker will help you dock any application into the system tray. This means you can dock openoffice, xmms, firefox, thunderbird, anything! Just point and click. Works for all NET WM compliant window managers - that includes KDE, GNOME, Xfce, Fluxbox and many more. Created by %1. Updated and maintained by %2. KDocker ti permetterà di ridurre ad icona nel vassoio di sistema qualsiasi applicazione. Questo significa che potrai ridurre ad icona openoffice, xmms, firefox, thunderbird, qualsiasi cosa! Semplicemente puntando e cliccando. Funziona con tutti i window managers conformi a NET WM come KDE, GNOME, Xfce, Fluxbox e molti altri ancora. Creato da %1. Aggiornato e mantenuto da: %2. Scanner KDocker KDocker %1 did not start properly. %1 non è stato avviato correttamente. Could not find a matching window for %1 in the specified time: %2 seconds. Impossibile trovare una finestra corrispondente per %1 nel lasso di tempo specificato: %2 secondi. TrayItem Select Icon Seleziona Icona About %1 - %2 A proposito di %1 - %2 See %1 for more information. Consulta %1 per maggiori informazioni. Show %1 Mostra %1 Hide %1 Nascondi %1 About %1 A proposito di %1 Options Opzioni Set icon Imposta icona Skip taskbar Salta taskbar Skip pager Salta pager Sticky Fissa Iconify when minimized Riduci ad icona quando minimizzata Iconify when obscured Riduci ad icona quando oscurata Iconify when focus lost Riduci ad icona quando perde focus Iconify on close Riduci ad icona quando chiuso Balloon title changes Il titolo del fumetto cambia Dock Another Aggancia un'altra Undock All Sgancia tutti Toggle Commuta Undock Sgancia Close Chiudi TrayItemManager KDocker KDocker Cannot dock the active window because no window has focus. Impossibile agganciare la finestra attiva perchè priva di focus. Invalid window id. Id finestra invalido. This window is already docked. Click on system tray icon to toggle docking. Questa finestra è già agganciata. Clicca sull'icona corrispondente nel vassoio di sistema per commutare. Select the application/window to dock with the left mouse button. Seleziona l'applicazione/finestra da agganciare cliccando con il tasto sinistro del mouse. Click any other mouse button to abort. Click con un qualsiasi tasto del mouse per annullare. The window you are attempting to dock does not seem to be a normal window. La finestra che stai cercando di agganciare sembra non essere una normale finestra. About %1 - %2 A proposito di %1 - %2 See %1 for more information. Consulta %1 per maggiori informazioni. XLibUtil Failed to create XC_draped_box Impossibile creare XC_draped_box Failed to grab mouse Impossibile catturare il mouse kdocker-4.6/helpers/kdocker000644 000765 000024 00000000320 11570604611 016111 0ustar00johnstaff000000 000000 have kdocker && _kdocker() { local cur COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} COMPREPLY=($( compgen -A command $cur ) ) } [ "${have:-}" ] && complete -F _kdocker kdocker kdocker-4.6/helpers/kdocker.desktop000644 000765 000024 00000000306 11570604611 017565 0ustar00johnstaff000000 000000 [Desktop Entry] Name=KDocker GenericName=Docking utility Comment=Docks any application into system tray Exec=kdocker TryExec=kdocker Icon=kdocker Terminal=false Type=Application Categories=Utility;