Hello community, here is the log from the commit of package krunner for openSUSE:Factory checked in at 2020-10-12 13:56:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/krunner (Old) and /work/SRC/openSUSE:Factory/.krunner.new.3486 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "krunner" Mon Oct 12 13:56:08 2020 rev:82 rq:840846 version:5.75.0 Changes: -------- --- /work/SRC/openSUSE:Factory/krunner/krunner.changes 2020-09-18 14:43:08.560095637 +0200 +++ /work/SRC/openSUSE:Factory/.krunner.new.3486/krunner.changes 2020-10-12 13:57:58.874182739 +0200 @@ -1,0 +2,9 @@ +Mon Oct 5 08:33:33 UTC 2020 - Christophe Giboudeaux <christo...@krop.fr> + +- Update to 5.75.0 + * New feature release + * For more details please see: + * https://kde.org/announcements/kde-frameworks-5.75.0 +- Too many changes to list here. + +------------------------------------------------------------------- Old: ---- krunner-5.74.0.tar.xz krunner-5.74.0.tar.xz.sig New: ---- krunner-5.75.0.tar.xz krunner-5.75.0.tar.xz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ krunner.spec ++++++ --- /var/tmp/diff_new_pack.MCUJYG/_old 2020-10-12 13:57:59.398182958 +0200 +++ /var/tmp/diff_new_pack.MCUJYG/_new 2020-10-12 13:57:59.402182960 +0200 @@ -17,7 +17,7 @@ %define lname libKF5Runner5 -%define _tar_path 5.74 +%define _tar_path 5.75 # Full KF5 version (e.g. 5.33.0) %{!?_kf5_version: %global _kf5_version %{version}} # Last major and minor KF5 version (e.g. 5.33) @@ -25,7 +25,7 @@ # Only needed for the package signature condition %bcond_without lang Name: krunner -Version: 5.74.0 +Version: 5.75.0 Release: 0 Summary: KDE Framework for providing different actions given a string query License: LGPL-2.1-or-later ++++++ krunner-5.74.0.tar.xz -> krunner-5.75.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/CMakeLists.txt new/krunner-5.75.0/CMakeLists.txt --- old/krunner-5.74.0/CMakeLists.txt 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/CMakeLists.txt 2020-10-04 11:56:50.000000000 +0200 @@ -1,12 +1,12 @@ cmake_minimum_required(VERSION 3.5) -set(KF5_VERSION "5.74.0") # handled by release scripts -set(KF5_DEP_VERSION "5.74.0") # handled by release scripts +set(KF5_VERSION "5.75.0") # handled by release scripts +set(KF5_DEP_VERSION "5.75.0") # handled by release scripts project(KRunner VERSION ${KF5_VERSION}) # ECM setup include(FeatureSummary) -find_package(ECM 5.74.0 NO_MODULE) +find_package(ECM 5.75.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://commits.kde.org/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) @@ -62,7 +62,7 @@ add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050d00) add_definitions(-DKF_DISABLE_DEPRECATED_BEFORE_AND_AT=0x054900) add_definitions(-DPLASMA_DISABLE_DEPRECATED_BEFORE_AND_AT=0x050500) # needed because we use Plasma::Package in the API -add_definitions(-DQT_NO_FOREACH) +add_definitions(-DQT_NO_FOREACH -DQT_NO_KEYWORDS) # Subdirectories add_subdirectory(src) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/LICENSES/LGPL-2.0-only.txt new/krunner-5.75.0/LICENSES/LGPL-2.0-only.txt --- old/krunner-5.74.0/LICENSES/LGPL-2.0-only.txt 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/LICENSES/LGPL-2.0-only.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,446 +0,0 @@ -GNU LIBRARY GENERAL PUBLIC LICENSE - -Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. - -51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is numbered 2 because -it goes with version 2 of the ordinary GPL.] - -Preamble - -The licenses for most software are designed to take away your freedom to share -and change it. By contrast, the GNU General Public Licenses are intended to -guarantee your freedom to share and change free software--to make sure the -software is free for all its users. - -This license, the Library General Public License, applies to some specially -designated Free Software Foundation software, and to any other libraries whose -authors decide to use it. You can use it for your libraries, 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 library, or if you modify it. - -For example, if you distribute copies of the library, whether gratis or for -a fee, you must give the recipients all the rights that we gave you. You must -make sure that they, too, receive or can get the source code. If you link -a program with the library, you must provide complete object files to the -recipients so that they can relink them with the library, after making changes -to the library and recompiling it. And you must show them these terms so they -know their rights. - -Our method of protecting your rights has two steps: (1) copyright the library, -and (2) offer you this license which gives you legal permission to copy, distribute -and/or modify the library. - -Also, for each distributor's protection, we want to make certain that everyone -understands that there is no warranty for this free library. If the library -is modified by someone else and passed on, we want its recipients to know -that what they have is not the original version, 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 companies distributing free software will individually -obtain patent licenses, thus in effect transforming the program into proprietary -software. To prevent this, we have made it clear that any patent must be licensed -for everyone's free use or not licensed at all. - -Most GNU software, including some libraries, is covered by the ordinary GNU -General Public License, which was designed for utility programs. This license, -the GNU Library General Public License, applies to certain designated libraries. -This license is quite different from the ordinary one; be sure to read it -in full, and don't assume that anything in it is the same as in the ordinary -license. - -The reason we have a separate public license for some libraries is that they -blur the distinction we usually make between modifying or adding to a program -and simply using it. Linking a program with a library, without changing the -library, is in some sense simply using the library, and is analogous to running -a utility program or application program. However, in a textual and legal -sense, the linked executable is a combined work, a derivative of the original -library, and the ordinary General Public License treats it as such. - -Because of this blurred distinction, using the ordinary General Public License -for libraries did not effectively promote software sharing, because most developers -did not use the libraries. We concluded that weaker conditions might promote -sharing better. - -However, unrestricted linking of non-free programs would deprive the users -of those programs of all benefit from the free status of the libraries themselves. -This Library General Public License is intended to permit developers of non-free -programs to use free libraries, while preserving your freedom as a user of -such programs to change the free libraries that are incorporated in them. -(We have not seen how to achieve this as regards changes in header files, -but we have achieved it as regards changes in the actual functions of the -Library.) The hope is that this will lead to faster development of free libraries. - -The precise terms and conditions for copying, distribution and modification -follow. Pay close attention to the difference between a "work based on the -library" and a "work that uses the library". The former contains code derived -from the library, while the latter only works together with the library. - -Note that it is possible for a library to be covered by the ordinary General -Public License rather than by this special one. - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - -0. This License Agreement applies to any software library which contains a -notice placed by the copyright holder or other authorized party saying it -may be distributed under the terms of this Library General Public License -(also called "this License"). Each licensee is addressed as "you". - -A "library" means a collection of software functions and/or data prepared -so as to be conveniently linked with application programs (which use some -of those functions and data) to form executables. - -The "Library", below, refers to any such software library or work which has -been distributed under these terms. A "work based on the Library" means either -the Library or any derivative work under copyright law: that is to say, a -work containing the Library or a portion of it, either verbatim or with modifications -and/or translated straightforwardly into another language. (Hereinafter, translation -is included without limitation in the term "modification".) - -"Source code" for a work means the preferred form of the work for making modifications -to it. For a library, complete source code means all the source code for all -modules it contains, plus any associated interface definition files, plus -the scripts used to control compilation and installation of the library. - -Activities other than copying, distribution and modification are not covered -by this License; they are outside its scope. The act of running a program -using the Library is not restricted, and output from such a program is covered -only if its contents constitute a work based on the Library (independent of -the use of the Library in a tool for writing it). Whether that is true depends -on what the Library does and what the program that uses the Library does. - -1. You may copy and distribute verbatim copies of the Library's complete source -code as you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice and disclaimer -of warranty; keep intact all the notices that refer to this License and to -the absence of any warranty; and distribute a copy of this License along with -the Library. - -You may charge a fee for the physical act of transferring a copy, and you -may at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Library or any portion of it, -thus forming a work based on the Library, and copy and distribute such modifications -or work under the terms of Section 1 above, provided that you also meet all -of these conditions: - - a) The modified work must itself be a software library. - -b) You must cause the files modified to carry prominent notices stating that -you changed the files and the date of any change. - -c) You must cause the whole of the work to be licensed at no charge to all -third parties under the terms of this License. - -d) If a facility in the modified Library refers to a function or a table of -data to be supplied by an application program that uses the facility, other -than as an argument passed when the facility is invoked, then you must make -a good faith effort to ensure that, in the event an application does not supply -such function or table, the facility still operates, and performs whatever -part of its purpose remains meaningful. - -(For example, a function in a library to compute square roots has a purpose -that is entirely well-defined independent of the application. Therefore, Subsection -2d requires that any application-supplied function or table used by this function -must be optional: if the application does not supply it, the square root function -must still compute square roots.) - -These requirements apply to the modified work as a whole. If identifiable -sections of that work are not derived from the Library, and can be reasonably -considered independent and separate works in themselves, then this License, -and its terms, do not apply to those sections when you distribute them as -separate works. But when you distribute the same sections as part of a whole -which is a work based on the Library, the distribution of the whole must be -on the terms of this License, whose permissions for other licensees extend -to the entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest your -rights to work written entirely by you; rather, the intent is to exercise -the right to control the distribution of derivative or collective works based -on the Library. - -In addition, mere aggregation of another work not based on the Library with -the Library (or with a work based on the Library) on a volume of a storage -or distribution medium does not bring the other work under the scope of this -License. - -3. You may opt to apply the terms of the ordinary GNU General Public License -instead of this License to a given copy of the Library. To do this, you must -alter all the notices that refer to this License, so that they refer to the -ordinary GNU General Public License, version 2, instead of to this License. -(If a newer version than version 2 of the ordinary GNU General Public License -has appeared, then you can specify that version instead if you wish.) Do not -make any other change in these notices. - -Once this change is made in a given copy, it is irreversible for that copy, -so the ordinary GNU General Public License applies to all subsequent copies -and derivative works made from that copy. - -This option is useful when you wish to copy part of the code of the Library -into a program that is not a library. - -4. You may copy and distribute the Library (or a portion or derivative of -it, under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you accompany it with the complete corresponding -machine-readable source code, which must be distributed under the terms of -Sections 1 and 2 above on a medium customarily used for software interchange. - -If distribution of object code is made by offering access to copy from a designated -place, then offering equivalent access to copy the source code from the same -place satisfies the requirement to distribute the source code, even though -third parties are not compelled to copy the source along with the object code. - -5. A program that contains no derivative of any portion of the Library, but -is designed to work with the Library by being compiled or linked with it, -is called a "work that uses the Library". Such a work, in isolation, is not -a derivative work of the Library, and therefore falls outside the scope of -this License. - -However, linking a "work that uses the Library" with the Library creates an -executable that is a derivative of the Library (because it contains portions -of the Library), rather than a "work that uses the library". The executable -is therefore covered by this License. Section 6 states terms for distribution -of such executables. - -When a "work that uses the Library" uses material from a header file that -is part of the Library, the object code for the work may be a derivative work -of the Library even though the source code is not. Whether this is true is -especially significant if the work can be linked without the Library, or if -the work is itself a library. The threshold for this to be true is not precisely -defined by law. - -If such an object file uses only numerical parameters, data structure layouts -and accessors, and small macros and small inline functions (ten lines or less -in length), then the use of the object file is unrestricted, regardless of -whether it is legally a derivative work. (Executables containing this object -code plus portions of the Library will still fall under Section 6.) - -Otherwise, if the work is a derivative of the Library, you may distribute -the object code for the work under the terms of Section 6. Any executables -containing that work also fall under Section 6, whether or not they are linked -directly with the Library itself. - -6. As an exception to the Sections above, you may also compile or link a "work -that uses the Library" with the Library to produce a work containing portions -of the Library, and distribute that work under terms of your choice, provided -that the terms permit modification of the work for the customer's own use -and reverse engineering for debugging such modifications. - -You must give prominent notice with each copy of the work that the Library -is used in it and that the Library and its use are covered by this License. -You must supply a copy of this License. If the work during execution displays -copyright notices, you must include the copyright notice for the Library among -them, as well as a reference directing the user to the copy of this License. -Also, you must do one of these things: - -a) Accompany the work with the complete corresponding machine-readable source -code for the Library including whatever changes were used in the work (which -must be distributed under Sections 1 and 2 above); and, if the work is an -executable linked with the Library, with the complete machine-readable "work -that uses the Library", as object code and/or source code, so that the user -can modify the Library and then relink to produce a modified executable containing -the modified Library. (It is understood that the user who changes the contents -of definitions files in the Library will not necessarily be able to recompile -the application to use the modified definitions.) - -b) Accompany the work with a written offer, valid for at least three years, -to give the same user the materials specified in Subsection 6a, above, for -a charge no more than the cost of performing this distribution. - -c) If distribution of the work is made by offering access to copy from a designated -place, offer equivalent access to copy the above specified materials from -the same place. - -d) Verify that the user has already received a copy of these materials or -that you have already sent this user a copy. - -For an executable, the required form of the "work that uses the Library" must -include any data and utility programs needed for reproducing the executable -from it. However, as a special exception, the 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. - -It may happen that this requirement contradicts the license restrictions of -other proprietary libraries that do not normally accompany the operating system. -Such a contradiction means you cannot use both them and the Library together -in an executable that you distribute. - -7. You may place library facilities that are a work based on the Library side-by-side -in a single library together with other library facilities not covered by -this License, and distribute such a combined library, provided that the separate -distribution of the work based on the Library and of the other library facilities -is otherwise permitted, and provided that you do these two things: - -a) Accompany the combined library with a copy of the same work based on the -Library, uncombined with any other library facilities. This must be distributed -under the terms of the Sections above. - -b) Give prominent notice with the combined library of the fact that part of -it is a work based on the Library, and explaining where to find the accompanying -uncombined form of the same work. - -8. You may not copy, modify, sublicense, link with, or distribute the Library -except as expressly provided under this License. Any attempt otherwise to -copy, modify, sublicense, link with, or distribute the Library is void, and -will automatically terminate your rights under this License. However, parties -who have received copies, or rights, from you under this License will not -have their licenses terminated so long as such parties remain in full compliance. - -9. You are not required to accept this License, since you have not signed -it. However, nothing else grants you permission to modify or distribute the -Library or its derivative works. These actions are prohibited by law if you -do not accept this License. Therefore, by modifying or distributing the Library -(or any work based on the Library), you indicate your acceptance of this License -to do so, and all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - -10. Each time you redistribute the Library (or any work based on the Library), -the recipient automatically receives a license from the original licensor -to copy, distribute, link with or modify the Library subject to these terms -and conditions. You may not impose any further restrictions on the recipients' -exercise of the rights granted herein. You are not responsible for enforcing -compliance by third parties to this License. - -11. If, as a consequence of a court judgment or allegation of patent infringement -or for any other reason (not limited to patent issues), conditions are imposed -on you (whether by court order, agreement or otherwise) that contradict the -conditions of this License, they do not excuse you from the conditions of -this License. If you cannot distribute so as to satisfy simultaneously your -obligations under this License and any other pertinent obligations, then as -a consequence you may not distribute the Library at all. For example, if a -patent license would not permit royalty-free redistribution of the Library -by all those who receive copies directly or indirectly through you, then the -only way you could satisfy both it and this License would be to refrain entirely -from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any patents -or other property right claims or to contest validity of any such claims; -this section has the sole purpose of protecting the integrity of the free -software distribution system which is implemented by public license practices. -Many people have made generous contributions to the wide range of software -distributed through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing to -distribute software through any other system and a licensee cannot impose -that choice. - -This section is intended to make thoroughly clear what is believed to be a -consequence of the rest of this License. - -12. If the distribution and/or use of the Library is restricted in certain -countries either by patents or by copyrighted interfaces, the original copyright -holder who places the Library under this License may add an explicit geographical -distribution limitation excluding those countries, so that distribution is -permitted only in or among countries not thus excluded. In such case, this -License incorporates the limitation as if written in the body of this License. - -13. The Free Software Foundation may publish revised and/or new versions of -the Library General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to address -new problems or concerns. - -Each version is given a distinguishing version number. If the Library specifies -a version number of this License which applies to it and "any later version", -you have the option of following the terms and conditions either of that version -or of any later version published by the Free Software Foundation. If the -Library does not specify a license version number, you may choose any version -ever published by the Free Software Foundation. - -14. If you wish to incorporate parts of the Library into other free programs -whose distribution conditions are incompatible with these, write to the author -to ask for permission. For software which is copyrighted by the Free Software -Foundation, write to the Free Software Foundation; we sometimes make exceptions -for this. Our decision will be guided by the two goals of preserving the free -status of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - -15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR -THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE -STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY -"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE -OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE -THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE -OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA -OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES -OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH -HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -END OF TERMS AND CONDITIONS - -How to Apply These Terms to Your New Libraries - -If you develop a new library, and you want it to be of the greatest possible -use to the public, we recommend making it free software that everyone can -redistribute and change. You can do so by permitting redistribution under -these terms (or, alternatively, under the terms of the ordinary General Public -License). - -To apply these terms, attach the following notices to the library. It is safest -to attach them to the start of each source file to most effectively convey -the exclusion of warranty; and each file should have at least the "copyright" -line and a pointer to where the full notice is found. - -one line to give the library's name and an idea of what it does. - -Copyright (C) year name of author - -This library is free software; you can redistribute it and/or modify it under -the terms of the GNU Library General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. - -This library is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more -details. - -You should have received a copy of the GNU Library General Public License -along with this library; if not, write to the Free Software Foundation, Inc., -51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your school, -if any, to sign a "copyright disclaimer" for the library, if necessary. Here -is a sample; alter the names: - -Yoyodyne, Inc., hereby disclaims all copyright interest in - -the library `Frob' (a library for tweaking knobs) written - -by James Random Hacker. - -signature of Ty Coon, 1 April 1990 - -Ty Coon, President of Vice - -That's all there is to it! diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/autotests/dbusrunnertest.cpp new/krunner-5.75.0/autotests/dbusrunnertest.cpp --- old/krunner-5.74.0/autotests/dbusrunnertest.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/autotests/dbusrunnertest.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -1,7 +1,7 @@ /* SPDX-FileCopyrightText: 2017 David Edmundson <davidedmund...@kde.org> - SPDX-License-Identifier: LGPL-2.0-only + SPDX-License-Identifier: LGPL-2.0-or-later */ #include "runnermanager.h" @@ -44,6 +44,8 @@ #endif void testMatch(); void testMulti(); + void testFilterProperties(); + void testFilterProperties_data(); void testRequestActionsOnce(); #if WITH_KSERVICE void testMatch_data(); @@ -161,12 +163,12 @@ QSignalSpy processSpy(&process, &QProcess::readyRead); m.run(result); processSpy.wait(); - QCOMPARE(process.readAllStandardOutput().trimmed(), QByteArray("Running:id1:")); + QCOMPARE(process.readAllStandardOutput().trimmed().split('\n').constLast(), QByteArray("Running:id1:")); result.setSelectedAction(action); m.run(result); processSpy.wait(); - QCOMPARE(process.readAllStandardOutput().trimmed(), QByteArray("Running:id1:action1")); + QCOMPARE(process.readAllStandardOutput().trimmed().split('\n').constLast(), QByteArray("Running:id1:action1")); process.kill(); process.waitForFinished(); @@ -220,8 +222,8 @@ //verify matches, must be one from each QCOMPARE(m.matches().count(), 2); - QString first = m.matches().at(0).data().toString(); - QString second = m.matches().at(1).data().toString(); + const QString first = m.matches().at(0).data().toList().constFirst().toString(); + const QString second = m.matches().at(1).data().toList().constFirst().toString(); QVERIFY(first != second); QVERIFY(first == QLatin1String("net.krunnertests.multi.a1") || first == QStringLiteral("net.krunnertests.multi.a2")); QVERIFY(second == QLatin1String("net.krunnertests.multi.a1") || second == QStringLiteral("net.krunnertests.multi.a2")); @@ -278,13 +280,53 @@ // Construct a fake match with necesarry data QueryMatch fakeMatch(m.runner(QStringLiteral("dbusrunnertest"))); fakeMatch.setId(QStringLiteral("dbusrunnertest_id1")); - fakeMatch.setData(QStringLiteral("net.krunnertests.dave")); + fakeMatch.setData(QVariantList({ + QStringLiteral("net.krunnertests.dave"), + QStringList({QStringLiteral("action1"), QStringLiteral("action2")}) + })); // We haven't called the prepare slot, if the implementation works // the actions should alredy be available auto actions = m.actionsForMatch(fakeMatch); - QCOMPARE(actions.count(), 1); + QCOMPARE(actions.count(), 2); + + process.kill(); + process.waitForFinished(); +} + +void DBusRunnerTest::testFilterProperties_data() +{ + QTest::addColumn<QString>("rejectedQuery"); + QTest::addColumn<QString>("acceptedQuery"); + + QTest::newRow("min-letter-count") << "fo" << "foo"; + QTest::newRow("match-regex") << "barfoo" << "foobar"; +} + +void DBusRunnerTest::testFilterProperties() +{ + QFETCH(QString, rejectedQuery); + QFETCH(QString, acceptedQuery); + QProcess process; + process.start(QFINDTESTDATA("testremoterunner"), QStringList({QStringLiteral("net.krunnertests.dave")})); + QVERIFY(process.waitForStarted()); + + QTest::qSleep(500); + + RunnerManager m; + auto md = KPluginMetaData::fromDesktopFile(QFINDTESTDATA("dbusrunnertest.desktop"), {QStringLiteral("plasma-runner.desktop")}); + QVERIFY(md.isValid()); + m.loadRunner(md); + m.launchQuery(rejectedQuery); + QSignalSpy spy(&m, &RunnerManager::matchesChanged); + QVERIFY(spy.wait()); + // Match method was not called, because the min letter count is 3 + QVERIFY(process.readAllStandardOutput().isEmpty()); + m.launchQuery(acceptedQuery); + QSignalSpy spy2(&m, &RunnerManager::matchesChanged); + QVERIFY(spy2.wait()); + QCOMPARE(process.readAllStandardOutput().trimmed(), QString(QStringLiteral("Matching:") + acceptedQuery).toLocal8Bit()); process.kill(); process.waitForFinished(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/autotests/dbusrunnertest.desktop new/krunner-5.75.0/autotests/dbusrunnertest.desktop --- old/krunner-5.74.0/autotests/dbusrunnertest.desktop 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/autotests/dbusrunnertest.desktop 2020-10-04 11:56:50.000000000 +0200 @@ -14,3 +14,5 @@ X-Plasma-DBusRunner-Service=net.krunnertests.dave X-Plasma-DBusRunner-Path=/dave X-Plasma-Request-Actions-Once=true +X-Plasma-Runner-Min-Letter-Count=3 +X-Plasma-Runner-Match-Regex=^fo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/autotests/testremoterunner.cpp new/krunner-5.75.0/autotests/testremoterunner.cpp --- old/krunner-5.74.0/autotests/testremoterunner.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/autotests/testremoterunner.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -1,7 +1,7 @@ /* SPDX-FileCopyrightText: 2017 David Edmundson <davidedmund...@kde.org> - SPDX-License-Identifier: LGPL-2.0-only + SPDX-License-Identifier: LGPL-2.0-or-later */ #include "testremoterunner.h" @@ -30,6 +30,7 @@ RemoteMatches TestRemoteRunner::Match(const QString& searchTerm) { RemoteMatches ms; + std::cout << "Matching:" << qPrintable(searchTerm) << std::endl; if (searchTerm.contains(QLatin1String("foo"))) { RemoteMatch m; m.id = QStringLiteral("id1"); @@ -37,6 +38,7 @@ m.iconName = QStringLiteral("icon1"); m.type = Plasma::QueryMatch::ExactMatch; m.relevance = 0.8; + m.properties[QStringLiteral("actions")] = QStringList(QStringLiteral("action1")); ms << m; } return ms; @@ -50,7 +52,12 @@ action.text = QStringLiteral("Action 1"); action.iconName = QStringLiteral("document-browser"); - return RemoteActions({action}); + RemoteAction action2; + action2.id = QStringLiteral("action2"); + action2.text = QStringLiteral("Action 2"); + action2.iconName = QStringLiteral("document-browser"); + + return RemoteActions({action, action2}); } void TestRemoteRunner::Run(const QString &id, const QString &actionId) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/abstractrunner.cpp new/krunner-5.75.0/src/abstractrunner.cpp --- old/krunner-5.74.0/src/abstractrunner.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/abstractrunner.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -162,9 +162,7 @@ QList<QAction*> AbstractRunner::actionsForMatch(const Plasma::QueryMatch &match) { - Q_UNUSED(match) - QList<QAction*> ret; - return ret; + return match.isValid() ? match.actions() : QList<QAction *>(); } QAction* AbstractRunner::addAction(const QString &id, const QIcon &icon, const QString &text) @@ -203,7 +201,7 @@ QMimeData *AbstractRunner::mimeDataForMatch(const QueryMatch &match) { - if (match.urls().isEmpty()) { + if (match.urls().isEmpty()) { return nullptr; } QMimeData *result = new QMimeData(); @@ -376,7 +374,54 @@ } d->suspendMatching = suspend; - emit matchingSuspended(suspend); + Q_EMIT matchingSuspended(suspend); +} + +int AbstractRunner::minLetterCount() const +{ + return d->minLetterCount; +} + +void AbstractRunner::setMinLetterCount(int count) +{ + d->minLetterCount = count; +} + +QRegularExpression AbstractRunner::matchRegex() const +{ + return d->matchRegex; +} + +void AbstractRunner::setMatchRegex(const QRegularExpression ®ex) +{ + d->matchRegex = regex; + d->hasMatchRegex = regex.isValid() && !regex.pattern().isEmpty(); +} + +void AbstractRunner::setTriggerWords(const QStringList &triggerWords) +{ + int minTriggerWordLetters = 0; + QString constructedRegex = QStringLiteral("^"); + for (const QString &triggerWord : triggerWords) { + // We want to link them with an or + if (constructedRegex.length() > 1) { + constructedRegex += QLatin1Char('|'); + } + constructedRegex += QRegularExpression::escape(triggerWord); + if (minTriggerWordLetters == 0 || triggerWord.length() < minTriggerWordLetters) { + minTriggerWordLetters = triggerWord.length(); + } + } + // If we can reject the query because of the length we don't need the regex + setMinLetterCount(minTriggerWordLetters); + QRegularExpression regex(constructedRegex); + regex.optimize(); + setMatchRegex(regex); +} + +bool AbstractRunner::hasMatchRegex() const +{ + return d->hasMatchRegex; } AbstractRunnerPrivate::AbstractRunnerPrivate(AbstractRunner *r) @@ -395,9 +440,22 @@ { } +void AbstractRunnerPrivate::init() +{ + if (runnerDescription.isValid()) { + const auto rawData = runnerDescription.rawData(); + minLetterCount = rawData.value(QStringLiteral("X-Plasma-Runner-Min-Letter-Count")).toInt(); + if (rawData.contains(QStringLiteral("X-Plasma-Runner-Match-Regex"))) { + matchRegex = QRegularExpression(rawData.value(QStringLiteral("X-Plasma-Runner-Match-Regex")).toString()); + hasMatchRegex = matchRegex.isValid() && !matchRegex.pattern().isEmpty(); + } + } +} + void AbstractRunnerPrivate::init(const KPluginMetaData &pluginMetaData) { runnerDescription = pluginMetaData; + init(); } #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 72) && KSERVICE_BUILD_DEPRECATED_SINCE(5, 0) @@ -409,12 +467,14 @@ const KPluginInfo pluginInfo(service); runnerDescription = pluginInfo.isValid() ? pluginInfo.toMetaData() : KPluginMetaData(); QT_WARNING_POP + init(); } #endif void AbstractRunnerPrivate::init(const QString &path) { runnerDescription = KPluginMetaData(path + QStringLiteral("/metadata.desktop")); + init(); } } // Plasma namespace diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/abstractrunner.h new/krunner-5.75.0/src/abstractrunner.h --- old/krunner-5.74.0/src/abstractrunner.h 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/abstractrunner.h 2020-10-04 11:56:50.000000000 +0200 @@ -26,6 +26,7 @@ class QAction; class QMimeData; +class QRegularExpression; namespace Plasma { @@ -58,6 +59,9 @@ Q_PROPERTY(QString description READ description) Q_PROPERTY(QString name READ name) Q_PROPERTY(QIcon icon READ icon) + Q_PROPERTY(int minLetterCount READ minLetterCount WRITE setMinLetterCount) + Q_PROPERTY(QRegularExpression matchRegex READ matchRegex WRITE setMatchRegex) + public: /** Specifies a nominal speed for the runner */ enum Speed { @@ -306,6 +310,60 @@ */ bool isMatchingSuspended() const; + /** + * This is the minimum letter count for the query. If the query is shorter than this value + * and KRunner is not in the singleRunnerMode, the performMatch and consequently match method is not called. + * This can be set using the X-Plasma-Runner-Min-Letter-Count property or the setMinLetterCount method. + * @see setMinLetterCount + * @see match + * @see performMatch + * @return minLetterCount property + * @since 5.75 + */ + int minLetterCount() const; + + /** + * Set the minLetterCount property + * @param count + * @since 5.75 + */ + void setMinLetterCount(int count); + + /** + * If this regex is set with a not empty pattern it must match the query in + * order for the performMatch/match being called. + * Just like the minLetterCount property this check is ignored when the runner is in the singleRunnerMode. + * In case both the regex and the letter count is set the letter count is checked first. + * @return matchRegex property + * @see hasMatchRegex + * @since 5.75 + */ + QRegularExpression matchRegex() const; + + /** + * Set the matchRegex property + * @param regex + * @since 5.75 + */ + void setMatchRegex(const QRegularExpression ®ex); + + /** + * Constructs internally a regex which requires the query to start with the trigger words. + * Multiple words are concatenated with or, for instance: "^word1|word2|word3". + * The trigger words are internally escaped. + * Also the minLetterCount is set to the shortest word in the list. + * @since 5.75 + * @see matchRegex + */ + void setTriggerWords(const QStringList &triggerWords); + + /** + * If the runner has a valid regex and non empty regex + * @return hasMatchRegex + * @since 5.75 + */ + bool hasMatchRegex() const; + Q_SIGNALS: /** * This signal is emitted when matching is about to commence, giving runners @@ -561,13 +619,16 @@ K_PLUGIN_FACTORY_WITH_JSON(classname ## Factory, jsonFile, registerPlugin<classname>();) \ K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION) +#if KRUNNER_ENABLE_DEPRECATED_SINCE(5, 75) /** * These plugins are Used by the plugin selector dialog to show * configuration options specific to this runner. These options * must be runner global and not pertain to a specific match. + * @deprecated Since 5.0, use K_PLUGIN_FACTORY directly */ #define K_EXPORT_RUNNER_CONFIG( name, classname ) \ K_PLUGIN_FACTORY(ConfigFactory, registerPlugin<classname>();) \ K_EXPORT_PLUGIN_VERSION(PLASMA_VERSION) +#endif #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/abstractrunner_p.h new/krunner-5.75.0/src/abstractrunner_p.h --- old/krunner-5.74.0/src/abstractrunner_p.h 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/abstractrunner_p.h 2020-10-04 11:56:50.000000000 +0200 @@ -8,6 +8,7 @@ #define ABSTRACTRUNNER_P_H #include <QReadWriteLock> +#include <QRegularExpression> #include <KPluginMetaData> @@ -28,6 +29,7 @@ public: AbstractRunnerPrivate(AbstractRunner *r); ~AbstractRunnerPrivate(); + void init(); void init(const KPluginMetaData &pluginMetaData); #if KRUNNER_BUILD_DEPRECATED_SINCE(5, 72) && KSERVICE_BUILD_DEPRECATED_SINCE(5, 0) void init(const KService::Ptr service); @@ -46,6 +48,9 @@ RunnerSyntax *defaultSyntax; bool hasRunOptions : 1; bool suspendMatching : 1; + int minLetterCount = 0; + QRegularExpression matchRegex; + bool hasMatchRegex = false; }; } // namespace Plasma diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/data/org.kde.krunner1.xml new/krunner-5.75.0/src/data/org.kde.krunner1.xml --- old/krunner-5.74.0/src/data/org.kde.krunner1.xml 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/data/org.kde.krunner1.xml 2020-10-04 11:56:50.000000000 +0200 @@ -47,6 +47,13 @@ - Type (see PlasmaQuery::Type) - Relevance - Properties (VariantMap) + - Urls (StringList) + - Category + - Subtext + - Action Ids (StringList). In case you don't want to display any actions set this to an empty list. + Otherwise all the actions will be shown for compatibility with the previous versions of the D-Bus API. + When the actions ony need to be fetched once you can set the X-Plasma-Request-Actions-Once property of + the service file to true. --> <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="RemoteMatches"/> <arg name="matches" type="a(sssuda{sv})" direction="out"/> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/data/servicetypes/plasma-runner.desktop new/krunner-5.75.0/src/data/servicetypes/plasma-runner.desktop --- old/krunner-5.74.0/src/data/servicetypes/plasma-runner.desktop 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/data/servicetypes/plasma-runner.desktop 2020-10-04 11:56:50.000000000 +0200 @@ -83,3 +83,15 @@ # Description for the syntaxes [PropertyDef::X-Plasma-Runner-Syntax-Descriptions] Type=QStringList + +# Minimum letter count, if the query is shorter than this number the match method will not be called +# unless the runner is called in the single runner mode +# This value defaults to 0 +[PropertyDef::X-Plasma-Runner-Min-Letter-Count] +Type=int + +# If this regex is set with a not empty pattern it must match the query in order for the performMatch/match being called +# It does not differentiate between the single and normal runner mode +# In case both the regex and the letter count is set the letter count is checked first +[PropertyDef::X-Plasma-Runner-Match-Regex] +Type=QString diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/dbusrunner.cpp new/krunner-5.75.0/src/dbusrunner.cpp --- old/krunner-5.74.0/src/dbusrunner.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/dbusrunner.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -1,7 +1,8 @@ /* SPDX-FileCopyrightText: 2017, 2018 David Edmundson <davidedmund...@kde.org> + SPDX-FileCopyrightText: 2020 Alexander Lohnau <alexander.loh...@gmx.de> - SPDX-License-Identifier: LGPL-2.0-only + SPDX-License-Identifier: LGPL-2.0-or-later */ #include "dbusrunner_p.h" @@ -109,6 +110,7 @@ watcher->deleteLater(); QDBusReply<RemoteActions> reply = *watcher; if (!reply.isValid()) { + qCDebug(KRUNNER) << "Error requestion actions; calling" << service << " :" << reply.error().name() << reply.error().message(); return; } const auto actions = reply.value(); @@ -140,7 +142,7 @@ watchers << QSharedPointer<QDBusPendingCallWatcher>(watcher); connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, service, &context, reply]() { if (reply.isError()) { - qCDebug(KRUNNER) << "Error calling" << service << " :" << reply.error().name() << reply.error().message(); + qCDebug(KRUNNER) << "Error requesting matches; calling" << service << " :" << reply.error().name() << reply.error().message(); return; } const auto matches = reply.value(); @@ -149,7 +151,6 @@ m.setText(match.text); m.setId(match.id); - m.setData(service); m.setIconName(match.iconName); m.setType(match.type); m.setRelevance(match.relevance); @@ -158,6 +159,11 @@ m.setUrls(QUrl::fromStringList(match.properties.value(QStringLiteral("urls")).toStringList())); m.setMatchCategory(match.properties.value(QStringLiteral("category")).toString()); m.setSubtext(match.properties.value(QStringLiteral("subtext")).toString()); + if (match.properties.contains(QStringLiteral("actions"))) { + m.setData(QVariantList({service, match.properties.value(QStringLiteral("actions"))})); + } else { + m.setData(QVariantList({service})); + } context.addMatch(m); }; @@ -171,9 +177,20 @@ QList<QAction*> DBusRunner::actionsForMatch(const Plasma::QueryMatch &match) { - Q_UNUSED(match) - const QString service = match.data().toString(); - return m_actions.value(service); + const QVariantList data = match.data().toList(); + if (data.count() > 1) { + const QStringList actionIds = data.at(1).toStringList(); + const QList<QAction *> actionList = m_actions.value(data.constFirst().toString()); + QList<QAction *> requestedActions; + for (QAction *action : actionList) { + if (actionIds.contains(action->data().toString())) { + requestedActions << action; + } + } + return requestedActions; + } else { + return m_actions.value(data.constFirst().toString()); + } } void DBusRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) @@ -181,8 +198,8 @@ Q_UNUSED(context); QString actionId; - QString matchId = match.id().mid(id().length() + 1); //QueryMatch::setId mangles the match ID with runnerID + '_'. This unmangles it - QString service = match.data().toString(); + const QString matchId = match.id().mid(id().length() + 1); //QueryMatch::setId mangles the match ID with runnerID + '_'. This unmangles it + const QString service = match.data().toList().constFirst().toString(); if (match.selectedAction()) { actionId = match.selectedAction()->data().toString(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/dbusrunner_p.h new/krunner-5.75.0/src/dbusrunner_p.h --- old/krunner-5.74.0/src/dbusrunner_p.h 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/dbusrunner_p.h 2020-10-04 11:56:50.000000000 +0200 @@ -1,7 +1,7 @@ /* SPDX-FileCopyrightText: 2017 David Edmundson <davidedmund...@kde.org> - SPDX-License-Identifier: LGPL-2.0-only + SPDX-License-Identifier: LGPL-2.0-or-later */ #pragma once diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/declarative/runnermodel.cpp new/krunner-5.75.0/src/declarative/runnermodel.cpp --- old/krunner-5.74.0/src/declarative/runnermodel.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/declarative/runnermodel.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -15,18 +15,16 @@ RunnerModel::RunnerModel(QObject *parent) : QAbstractListModel(parent), - m_manager(nullptr), m_startQueryTimer(new QTimer(this)), - m_runningChangedTimeout(new QTimer(this)), - m_running(false) + m_runningChangedTimeout(new QTimer(this)) { m_startQueryTimer->setSingleShot(true); m_startQueryTimer->setInterval(10); - connect(m_startQueryTimer, SIGNAL(timeout()), this, SLOT(startQuery())); + connect(m_startQueryTimer, &QTimer::timeout, this, &RunnerModel::startQuery); //FIXME: HACK: some runners stay in a running but finished state, not possible to say if it's actually over m_runningChangedTimeout->setSingleShot(true); - connect(m_runningChangedTimeout, SIGNAL(timeout()), this, SLOT(queryHasFinished())); + connect(m_runningChangedTimeout, &QTimer::timeout, this, &RunnerModel::queryHasFinished); } QHash<int, QByteArray> RunnerModel::roleNames() const @@ -90,7 +88,7 @@ } else { m_singleRunnerId.clear(); } - emit runnersChanged(); + Q_EMIT runnersChanged(); } void RunnerModel::run(int index) @@ -168,9 +166,9 @@ if (createManager() || m_pendingQuery != m_manager->query()) { m_manager->launchQuery(m_pendingQuery, m_singleRunnerId); - emit queryChanged(); + Q_EMIT queryChanged(); m_running = true; - emit runningChanged(true); + Q_EMIT runningChanged(true); } } @@ -178,10 +176,10 @@ { if (!m_manager) { m_manager = new Plasma::RunnerManager(this); - connect(m_manager, SIGNAL(matchesChanged(QList<Plasma::QueryMatch>)), - this, SLOT(matchesChanged(QList<Plasma::QueryMatch>))); - connect(m_manager, SIGNAL(queryFinished()), - this, SLOT(queryHasFinished())); + connect(m_manager, &Plasma::RunnerManager::matchesChanged, + this, &RunnerModel::matchesChanged); + connect(m_manager, &Plasma::RunnerManager::queryFinished, + this, &RunnerModel::queryHasFinished); if (!m_pendingRunnersList.isEmpty()) { setRunners(m_pendingRunnersList); @@ -214,7 +212,7 @@ beginInsertRows(QModelIndex(), oldCount, newCount-1); m_matches = matches; endInsertRows(); - emit countChanged(); + Q_EMIT countChanged(); } } else { fullReset = true; @@ -224,7 +222,7 @@ beginResetModel(); m_matches = matches; endResetModel(); - emit countChanged(); + Q_EMIT countChanged(); } m_runningChangedTimeout->start(3000); } @@ -232,7 +230,7 @@ void RunnerModel::queryHasFinished() { m_running = false; - emit runningChanged(false); + Q_EMIT runningChanged(false); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/declarative/runnermodel.h new/krunner-5.75.0/src/declarative/runnermodel.h --- old/krunner-5.74.0/src/declarative/runnermodel.h 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/declarative/runnermodel.h 2020-10-04 11:56:50.000000000 +0200 @@ -103,14 +103,14 @@ void queryHasFinished(); private: - Plasma::RunnerManager *m_manager; + Plasma::RunnerManager *m_manager = nullptr; QList<Plasma::QueryMatch> m_matches; QStringList m_pendingRunnersList; QString m_singleRunnerId; QString m_pendingQuery; - QTimer *m_startQueryTimer; - QTimer *m_runningChangedTimeout; - bool m_running; + QTimer *const m_startQueryTimer; + QTimer *const m_runningChangedTimeout; + bool m_running = false; }; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/querymatch.cpp new/krunner-5.75.0/src/querymatch.cpp --- old/krunner-5.74.0/src/querymatch.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/querymatch.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -54,6 +54,7 @@ data = other.data; mimeType = other.mimeType; urls = other.urls; + actions = other.actions; } ~QueryMatchPrivate() @@ -77,6 +78,7 @@ QAction *selAction; bool enabled : 1; bool idSetByData : 1; + QList<QAction *> actions; }; QueryMatch::QueryMatch(AbstractRunner *runner) @@ -332,5 +334,23 @@ } #endif +void QueryMatch::setActions(const QList<QAction *> &actions) +{ + QWriteLocker locker(d->lock); + d->actions = actions; +} + +void QueryMatch::addAction(QAction *action) +{ + QWriteLocker locker(d->lock); + d->actions << action; +} + +QList<QAction *> QueryMatch::actions() const +{ + QReadLocker locker(d->lock); + return d->actions; +} + } // Plasma namespace diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/querymatch.h new/krunner-5.75.0/src/querymatch.h --- old/krunner-5.74.0/src/querymatch.h 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/querymatch.h 2020-10-04 11:56:50.000000000 +0200 @@ -267,6 +267,28 @@ bool isEnabled() const; /** + * Set the actions for this match. + * This method allows you to set the actions inside of the AbstractRunner::match() method + * and the default implementation of AbstractRunner::actionsForMatch() will return these. + * @since 5.75 + */ + void setActions(const QList<QAction *> &actions); + + /** + * Adds an action to this match + * @since 5.75 + * @see setActions + */ + void addAction(QAction *actions); + + /** + * List of actions set for this match + * @return actions + * @since 5.75 + */ + QList<QAction *> actions() const; + + /** * The current action. */ QAction* selectedAction() const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/runnercontext.cpp new/krunner-5.75.0/src/runnercontext.cpp --- old/krunner-5.74.0/src/runnercontext.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/runnercontext.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -295,7 +295,7 @@ if (!d->matches.isEmpty()) { d->matchesById.clear(); d->matches.clear(); - emit matchesChanged(); + Q_EMIT matchesChanged(); } d->term.clear(); @@ -375,7 +375,7 @@ // A copied searchContext may share the d pointer, // we always want to sent the signal of the object that created // the d pointer - emit d->q->matchesChanged(); + Q_EMIT d->q->matchesChanged(); return true; } @@ -398,7 +398,7 @@ d->matches.append(m); d->matchesById.insert(m.id(), &d->matches.at(d->matches.size() - 1)); UNLOCK(d); - emit d->q->matchesChanged(); + Q_EMIT d->q->matchesChanged(); return true; } @@ -435,7 +435,7 @@ } UNLOCK(d) - emit d->q->matchesChanged(); + Q_EMIT d->q->matchesChanged(); return true; } @@ -455,7 +455,7 @@ d->matches.removeAll(*match); d->matchesById.remove(matchId); UNLOCK(d) - emit d->q->matchesChanged(); + Q_EMIT d->q->matchesChanged(); return true; } @@ -487,7 +487,7 @@ } UNLOCK(d) - emit d->q->matchesChanged(); + Q_EMIT d->q->matchesChanged(); return true; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/runnerjobs.cpp new/krunner-5.75.0/src/runnerjobs.cpp --- old/krunner-5.74.0/src/runnerjobs.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/runnerjobs.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -140,7 +140,7 @@ if (m_context.isValid()) { m_runner->performMatch(m_context); } - emit done(self); + Q_EMIT done(self); } int FindMatchesJob::priority() const @@ -159,7 +159,7 @@ m_jobs(jobs), m_runners(runners) { - connect(m_weaver, SIGNAL(finished()), this, SLOT(checkIfFinished())); + connect(m_weaver, &ThreadWeaver::QueueSignals::finished, this, &DelayedJobCleaner::checkIfFinished); for (auto it = m_jobs.constBegin(); it != m_jobs.constEnd(); ++it) { connect(it->data(), &FindMatchesJob::done, this, &DelayedJobCleaner::jobDone); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/src/runnermanager.cpp new/krunner-5.75.0/src/runnermanager.cpp --- old/krunner-5.74.0/src/runnermanager.cpp 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/src/runnermanager.cpp 2020-10-04 11:56:50.000000000 +0200 @@ -13,6 +13,7 @@ #include <QCoreApplication> #include <QStandardPaths> #include <QDir> +#include <QRegularExpression> #include <KSharedConfig> #include <KPluginInfo> @@ -30,13 +31,10 @@ #include "runnerjobs_p.h" #include "querymatch.h" #include "krunner_debug.h" -#include <../krunner_version.h> using ThreadWeaver::Queue; using ThreadWeaver::Job; -//#define MEASURE_PREPTIME - namespace Plasma { @@ -63,12 +61,6 @@ #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 0) void warnAboutDeprecatedMetaData(const KPluginInfo &pluginInfo) { - // only start to emit runtime warnings at the time Plasma 5.20 is to be released - // because the majority of runner plugins comes from Plasma - // and for 5.19 they cannot be ported (have been ported for what will be 5.20 already) - // so there would be lots of useless noise in the logs -#if KRUNNER_VERSION >= QT_VERSION_CHECK(5, 75, 0) -#pragma message("Remove this build condition and the krunner_version.h include, now that we are becoming KF 5.75") if (!pluginInfo.libraryPath().isEmpty()) { qCWarning(KRUNNER).nospace() << "KRunner plugin " << pluginInfo.pluginName() << " still uses a .desktop file (" << pluginInfo.entryPath() << "). Please port it to JSON metadata."; @@ -76,9 +68,6 @@ qCWarning(KRUNNER).nospace() << "KRunner D-Bus plugin " << pluginInfo.pluginName() << " installs the .desktop file (" << pluginInfo.entryPath() << ") still in the kservices5 folder. Please install it to ${KDE_INSTALL_DATAROOTDIR}/krunner/dbusplugins."; } -#else - Q_UNUSED(pluginInfo); -#endif } #endif @@ -117,7 +106,7 @@ { if(lastMatchChangeSignalled.hasExpired(250)) { matchChangeTimer.stop(); - emit q->matchesChanged(context.matches()); + Q_EMIT q->matchesChanged(context.matches()); } else { matchChangeTimer.start(250 - lastMatchChangeSignalled.elapsed()); } @@ -125,7 +114,7 @@ void matchesChanged() { - emit q->matchesChanged(context.matches()); + Q_EMIT q->matchesChanged(context.matches()); } void loadConfiguration() @@ -210,7 +199,7 @@ currentSingleRunner = loadInstalledRunner(pluginMetaData); if (currentSingleRunner) { - emit currentSingleRunner->prepare(); + Q_EMIT currentSingleRunner->prepare(); singleRunnerWasLoaded = true; } } @@ -262,7 +251,6 @@ runner = loadInstalledRunner(description); } else { runner = runners.value(runnerName); - runner->reloadConfiguration(); } if (runner) { @@ -379,7 +367,7 @@ QObject::connect(runner, SIGNAL(matchingSuspended(bool)), q, SLOT(runnerMatchingSuspended(bool))); runner->init(); if (prepped) { - emit runner->prepare(); + Q_EMIT runner->prepare(); } } @@ -407,10 +395,10 @@ // we finished our run, and there are no valid matches, and so no // signal will have been sent out. so we need to emit the signal // ourselves here - emit q->matchesChanged(context.matches()); + Q_EMIT q->matchesChanged(context.matches()); } if (searchJobs.isEmpty()) { - emit q->queryFinished(); + Q_EMIT q->queryFinished(); } } @@ -428,7 +416,7 @@ if (searchJobs.isEmpty() && oldSearchJobs.isEmpty()) { if (allRunnersPrepped) { for (AbstractRunner *runner : qAsConst(runners)) { - emit runner->teardown(); + Q_EMIT runner->teardown(); } allRunnersPrepped = false; @@ -436,7 +424,7 @@ if (singleRunnerPrepped) { if (currentSingleRunner) { - emit currentSingleRunner->teardown(); + Q_EMIT currentSingleRunner->teardown(); } singleRunnerPrepped = false; @@ -487,7 +475,7 @@ // Delay in ms before slow runners are allowed to run static const int slowRunDelay = 400; - RunnerManager *q; + RunnerManager *const q; QueryMatch deferredRun; RunnerContext context; QTimer matchChangeTimer; @@ -830,12 +818,12 @@ d->prepped = true; if (d->singleMode) { if (d->currentSingleRunner) { - emit d->currentSingleRunner->prepare(); + Q_EMIT d->currentSingleRunner->prepare(); d->singleRunnerPrepped = true; } } else { for (AbstractRunner *runner : qAsConst(d->runners)) { - emit runner->prepare(); + Q_EMIT runner->prepare(); } d->allRunnersPrepped = true; @@ -905,13 +893,31 @@ runable = d->runners; } + const int queryLetterCount = term.count(); for (Plasma::AbstractRunner *r : qAsConst(runable)) { if (r->isMatchingSuspended()) { continue; } + // The runners can set the min letter count as a property, this way we don't + // have to spawn threads just for the runner to reject the query, because it is too short + if (!d->singleMode && queryLetterCount < r->minLetterCount()) { + continue; + } + // If the runner has one ore more trigger words it can set the matchRegex to prevent + // thread spawning if the pattern does not match + if (!d->singleMode && r->hasMatchRegex() && !r->matchRegex().match(term).hasMatch()) { + continue; + } d->startJob(r); } + // In the unlikely case that no runner gets queried we have to emit the signals here + if (d->searchJobs.isEmpty()) { + QTimer::singleShot(0, this, [this](){ + Q_EMIT matchesChanged({}); + Q_EMIT queryFinished(); + }); + } // Start timer to unblock slow runners d->delayTimer.start(RunnerManagerPrivate::slowRunDelay); @@ -943,7 +949,7 @@ } d->context.reset(); - emit queryFinished(); + Q_EMIT queryFinished(); } void RunnerManager::enableKNotifyPluginWatcher() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/templates/runner/runner.kdevtemplate new/krunner-5.75.0/templates/runner/runner.kdevtemplate --- old/krunner-5.74.0/templates/runner/runner.kdevtemplate 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/templates/runner/runner.kdevtemplate 2020-10-04 11:56:50.000000000 +0200 @@ -29,6 +29,7 @@ Name[pl]=C++ Name[pt]=C++ Name[pt_BR]=C++ +Name[ro]=C++ Name[ru]=C++ Name[sk]=C++ Name[sl]=C++ @@ -71,6 +72,7 @@ Comment[pl]=Szablon uruchamiania Plazmy. Szablon uruchamiania plazmy Comment[pt]=Modelo de Execução do Plasma. Um modelo de módulo de execução do Plasma Comment[pt_BR]=Modelo de módulo de execução do Plasma. Um modelo de módulos de execução do Plasma +Comment[ro]=Șablon de executor Plasma. Un șablon de executor Plasma Comment[ru]=Шаблон расширения для строки запуска Plasma Comment[sk]=Šablóna Plasma Runner. Šablóna plasma runner Comment[sl]=Predloga zaganjalnika Plasma. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/templates/runnerpython/install.sh new/krunner-5.75.0/templates/runnerpython/install.sh --- old/krunner-5.74.0/templates/runnerpython/install.sh 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/templates/runnerpython/install.sh 2020-10-04 11:56:50.000000000 +0200 @@ -3,11 +3,18 @@ # Exit if something fails set -e -mkdir -p ~/.local/share/kservices5/krunner/dbusplugins/ -mkdir -p ~/.local/share/dbus-1/services/ -cp plasma-runner-%{APPNAMELC}.desktop ~/.local/share/kservices5/krunner/dbusplugins/ -sed "s|%{PROJECTDIR}/%{APPNAMELC}.py|${PWD}/%{APPNAMELC}.py|" "org.kde.%{APPNAMELC}.service" > ~/.local/share/dbus-1/services/org.kde.%{APPNAMELC}.service +if [[ -z "$XDG_DATA_HOME" ]]; then + prefix=~/.local/share +else + prefix="$XDG_DATA_HOME" +fi + +mkdir -p $prefix/kservices5/krunner/dbusplugins/ +mkdir -p $prefix/dbus-1/services/ + +cp plasma-runner-%{APPNAMELC}.desktop $prefix/kservices5/krunner/dbusplugins/ +sed "s|%{PROJECTDIR}/%{APPNAMELC}.py|${PWD}/%{APPNAMELC}.py|" "org.kde.%{APPNAMELC}.service" > $prefix/dbus-1/services/org.kde.%{APPNAMELC}.service kquitapp5 krunner diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/templates/runnerpython/runnerpy.kdevtemplate new/krunner-5.75.0/templates/runnerpython/runnerpy.kdevtemplate --- old/krunner-5.74.0/templates/runnerpython/runnerpy.kdevtemplate 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/templates/runnerpython/runnerpy.kdevtemplate 2020-10-04 11:56:50.000000000 +0200 @@ -3,12 +3,19 @@ Name[az]=Python KRunner qoşması Name[ca]=Connector Python del KRunner Name[cs]=Modul KRunneru pr Python +Name[de]=KRunner-Modul für Python +Name[el]=Πρόσθετο Python KRunner +Name[en_GB]=Python KRunner Plugin Name[es]=Complemento en Python para KRunner +Name[fr]=module externe « KRunner » pour Python +Name[it]=Estensione Python di KRunner Name[ko]=Python KRunner 플러그인 Name[nl]=Python KRunner-plug-in +Name[nn]=Python KRunner-tillegg Name[pa]=ਪਾਈਥਨ ਕੇਰਨਰ ਪਲੱਗਇਨ Name[pt]='Plugin' do KRunner em Python Name[pt_BR]=Plugin Python do KRunner +Name[ro]=Extensie Python pentru KRunner Name[sk]=Zásuvný modul Python pre KRunner Name[sl]=Vtičnik za Python KRunner Name[sv]=Python-insticksprogram för Kör program @@ -17,11 +24,18 @@ Comment=Template for a KRunner Python Plugin using D-Bus Comment[az]=D-Bus ilə istifadə olunan KRunner Python Qoşması üçün nümunə Comment[ca]=Plantilla per a un connector Python del KRunner usant D-Bus +Comment[de]=Vorlage für ein KRunner-Modul für Python, das D-Bus verwendet +Comment[el]=Πρότυπο για ένα Python πρόσθετο του KRunner με χρήση D-Bus +Comment[en_GB]=Template for a KRunner Python Plugin using D-Bus Comment[es]=Plantilla para un complemento en Python para KRunner que usa D-Bus +Comment[fr]=Modèle pour le module externe « KRunner » pour Python, utilisant « D-Bus » +Comment[it]=Modello per un'estensione Python di KRunner che usa D-Bus Comment[ko]=D-Bus를 사용하는 KRunner Python 플러그인 템플릿 Comment[nl]=Sjabloon voor een Python-plug-in van KRunner met gebruik van D-Bus +Comment[nn]=Mal for eit Python-basert KRunner-tillegg som brukar D-Bus Comment[pt]=Modelo para um 'Plugin' em Python do KRunner que usa o D-Bus Comment[pt_BR]=Modelo para um plugin Python do KRunner usando o D-Bus +Comment[ro]=Șablon pentru o extensie KRunner în Python folosind DBus Comment[sk]=Šablóna pre KRunner Python plugin využívajúci D-Bus Comment[sl]=Predloga za vtičnik Python KRunner z uporabo D-Bus Comment[sv]=Mall för ett Python-insticksprogram för Kör program med användning av D-Bus diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/krunner-5.74.0/templates/runnerpython/uninstall.sh new/krunner-5.75.0/templates/runnerpython/uninstall.sh --- old/krunner-5.74.0/templates/runnerpython/uninstall.sh 2020-09-06 11:30:19.000000000 +0200 +++ new/krunner-5.75.0/templates/runnerpython/uninstall.sh 2020-10-04 11:56:50.000000000 +0200 @@ -3,7 +3,13 @@ # Exit if something fails set -e -rm ~/.local/share/kservices5/krunner/dbusplugins/plasma-runner-%{APPNAMELC}.desktop -rm ~/.local/share/dbus-1/services/org.kde.%{APPNAMELC}.service +if [[ -z "$XDG_DATA_HOME" ]]; then + prefix=~/.local/share +else + prefix="$XDG_DATA_HOME" +fi + +rm $prefix/kservices5/krunner/dbusplugins/plasma-runner-%{APPNAMELC}.desktop +rm $prefix/dbus-1/services/org.kde.%{APPNAMELC}.service kquitapp5 krunner