Skip to content

Result comparison causing Query result's action to be outdated #2812

@HorridModz

Description

@HorridModz

I've been having a weird issue with my Add2Path plugin, which has been present ever since I started developing it. It seems that in my Query method (which returns the results for a query), query is getting outdated.

My plugin operates on one-word commands, like add and remove, which take the succeeding text in the query as the command's input:

path add foo - command add with input foo
path remove bar - command remove with input bar

I've been noticing that the input part - foo and bar - doesn't always update. It seems the input stays the same, even when I change . This has been bugging me a lot, and it makes the plugin practically unusable. So I did some investigating. I replaced my Query method with a simple tester that tells me the "query" passed to it when I click the result:

public List<Result> Query(Query query)
    {
        return new List<Result>
        {
            new Result
            {
                Title = "test - view query",
                SubTitle = "view query",
                Action = c => { Context.API.ShowMsg("Query", query.Search); return false; }
            }
        };
	}

Sure enough, the strange behavior occurs here. It might be better to fire it up and see yourself, but I'll try to explain what I'm experiencing:

  1. I open FlowLauncher and type my action keyword (path), so the query is path.
  2. I click the test result and get a notification reporting that the query is blank (as it should be - after the action keyword path, the query is just blank)
  3. I type the characters hello world, leading to the query being: path hello word.
  4. I once again click the test result, and the notification once again reports that the query is blank (this is wrong; the query should be hello world)
  5. Keep clicking, the buggy behavior still occurs and the reported query does not update
  6. Now, delete the text path (leaving hello world intact), and retype it.
  7. Click the test result. This time, it properly returns the query: hello world, rather than reporting that it is blank (this is right, though the query is the same as it was last time, in step 4)

So, why's it work the second time but not the first time? It seems that deleting and re-adding the action keyword (path) forces it to update. This means that simply changing the input - from blank to hello world does not trigger an update.

However, if I change the code to report the query directly passed into the Query method rather than the Action function in one of the results, it works properly:

public List<Result> Query(Query query)
    {
        return new List<Result>
        {
            new Result
            {
                Title = "Query",
                SubTitle = query.Search,
                Action = c => { return false; }
            }
        };
    }

This means that the Query method is getting passed the properly updated query parameter, as it should. However, the Action in the returned result has the old query parameter.

This perplexes me, as the Query method is creating a new Result every time it is called - and if the query parameter is correct, it should be passing it to the result's Action - right?

But no, the Action is old and only updates when the result visually updates. I'm not very experienced with C#, but there seems to be two possible things that could cause this:

  1. The Result constructor is not working intuitively, perhaps using some kind of caching. Thus, when I initialize the Action field in the new Result I am constructing and returning, it is not really making a new one but giving me an old one - which still contains the old Action field with the old query value.
  2. The Result constructor is indeed creating a new Result object when I initialize and return it, but the Action field is not being updated. Maybe because of some rule in C# having to do with delegates as fields? This seems unlikely as I can't see how it could happen, but it's a possibility as I don't understand how C# handles stuff under the hood.

Of course, I'm leading toward my first theory, which suggests something happening with FlowLauncher's handling of Results and their Actions rather than my plugin. But I'm completely perplexed here, and I wouldn't be surprised if I'm just doing something wrong and overlooking something silly.

If you'd like my full plugin's code, let me know (though I believe that the initial, published version of the plugin, which is in the official plugins directory, contains this bug itself).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions