Homerun sources and Plasma runners
Aaron J. Seigo
aseigo at kde.org
Sat Nov 17 11:56:13 UTC 2012
On Friday, November 16, 2012 17:04:04 Aurélien Gâteau wrote:
> A preliminary subject is API compatibility: I don't think it is possible
> to extend the current AbstractRunner interface in a BC way to meet our
> needs. Would you be ready to create a new runner interface?
>
> This would require:
> - Defining and implementing this new interface (let's call it
> AbstractRunner2 for now)
> - Implementing an adapter to load old AbstractRunner-based runners
> - Porting KRunner to use AbstractRunner2 and the adapter
> - Progressively porting runners shipped in KDE SC to AbstractRunner2
this should be unnecessary. first, we can look at what API is missing or needs
adjusting.
assuming changes are needed, we can prototype this in homerun (and so homerun
can benefit from the improvements sooner) with an AbstratRunner subclass there
which runners built for homerun can utilize. this API would then go directly
into libplasma2 and Plasma Desktop 2 would include a krunner that uses this
new API.
> Sources features missing in Runners:
> - model-based => more QML friendly
as with Marco, i don't see any real need to have this in the libplasma API,
but if we do want this in the libplasma API, we don't need to expose it from
AbstractRunner ..
RunnerManager could provide access to a model. in libplasma2 it could even
become a model itself. right now, the runner model in kde-runtime is
essentially exactly that -> it provides access to setting the query (just
forwards that call to its internal RunnerManager), etc. so RunnerManager could
simply become a model libplasma2 .. and in libplasma1 we can continue to use
the model-on-top-of-RunnerManager.
so .. question is how best to implement that kind of model and that brings us
to the next point:
> - can update matches
matches have id()s which can be used to reference them. what would be needed
is for RunnerContext (which colates the matches from all the runners via
addMatches) to check the id of matches and replace them.
implementation detail: this could be done using a hash to keep lookup fast.
since id's are not guaranteed to be unique, this would need to be a multihash,
or possibly a hash of lists.
then there are two possibilities:
a) RunnerContext gets a new updateMatches(const QList<QueryMatch> &matches)
method which would add the matches and update matches with the same id.
(implementation: it could actually just remove the old match(es) and add the
new ones; as long as there is a model tracking the row<->match correlation
properly, these updates could be communicated via dataChanged signals)
b) RunnerContext::addMatches treats all calls as updates, so if a runner calls
addMatches more than once and there are matches with the same id's, they'd get
replaced. this could be problematic, however, as it would create a change in
behaviour for runners that call addMatches multiple times in their match
method and don't call setData or setId on the matches explicitly. for this
reason, i prefer (a)
note that both changes above are source and binary compatible!
> - "standardized" favoriteIds
because it uses strings and relies on parsing of them, i really dislike this
mechanism. it's too easy to get wrong (e.g. a runner that by chance uses one
of the prefix strings in a match id) and makes it unecessarily difficult to
change in future.
RunnerContext has this enum in it:
enum Type {
None = 0,
UnknownType = 1,
Directory = 2,
File = 4,
NetworkLocation = 8,
Executable = 16,
ShellCommand = 32,
Help = 64,
FileSystem = Directory | File | Executable | ShellCommand
};
this could be used in QueryMatch as well .. and then knowing what kind of
favourite it creates is a simple matter of checking this attribute. there is
already a type property in QueryMatch used with the QueryMatch::Type enum.
so perhaps:
void QueryMatch::setCategory(RunnerContext::Type category)
RunnerContext::Type QueryMatch::category() const
this means one more int stored for each QueryMatch and using RunnerContext's
header in QueryMatch (though in practice this is a complete non-issue since
almost everything that touches a QueryMatch also uses RunnerContext's API and
they are linked functionality-wise)
> - browsing support (as in: entering/leaving folders, application
> groups...) by invoking the source with named arguments
this is already possible -> simply run the result of QueryMatch as a new
query. this is close to how InformationalMatches are treated already, in fact.
so a runner that wants to list some directory structure could return a list of
matches, some of which represents folders which when selected would be used as
the new query. this would not work for viewing entire trees at once, unless a
different RunnerContext was used for each new "sub-"query of the runner.
however, i don't think viewing trees is a valid requirement for runners, so
this is imho a non-issue.
to make this easier and less hacky, a new value could be added to
QueryMatch::Type; e.g. QueryMatch. then items that can be re-used to query the
source runner can be marked with that type. voila.
> - future need: reorder items
can you describe the needs here more clearly? because i think this is already
possible given that sorting is done by the visualization anyways.
> If we create an interface which uses a Qt model to expose its items,
> this issue will become much easier to solve: we could create a model
> which groups all runner output models as a tree, then KRunner could use
> a KDescendantsProxyModel [1] on top of it to recreate a flat model, or
> just display all elements of the tree unindented.
accessing tree models in QML sucks. as in "unless you work around the
limitations of QML, you can't." i really still do not understand the need for
a tree at all.
if the requirement is to have a model per set of results (e.g. one model for
each runner's matches) that can be accomplished with a filter model on top of
the base model.
> This assumes we can make QML do what we want with that tree model, which
> may not be possible.
bingo.
> In that case we can always fallback to what
> Homerun::RunnerModel does: a "flat" model with one row per runner, each
> runner row exposing a "model" role
yes, that can work easily enough ..
something that is not covered here which would actually be very useful is
results paging. so a runner would return at most N results (so for a set of M
runners, the maximum number of returned matches would be N*M) but then could
be requested to get anothe rset of N results.
this would be very, very handy for runners that can return large datasets,
such as music player listings, nepomuk searches, etc.
that is something that is probably easiest to add directly to libplasma2 and
should not be targetted for libplasma1 in any way.
--
Aaron J. Seigo
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.kde.org/pipermail/plasma-devel/attachments/20121117/8f9f349e/attachment-0001.sig>
More information about the Plasma-devel
mailing list