Sublime Forum

Change the view with the focus in another group without swtiching focus to it

#1

Is it possible to change the view that has the focus in a different group from the active group without actually switching focus to it?

I should add that I need to do this from within the show_quick_panel() - on_highlighted method so I can’t just use focus_view() to switch focus to the view in the different group and then use focus_view() to switch the focus back again without killing the show_quick_panel().

You can use active_view_in_group(group) to get the currently edited view in the given group but there is no set_active_view_in_group(group, view) method.

While looking through sublime.py I discovered a whole undocumented class called Sheet and the Window class has lots of sheet related methods, might one of those be able to do what I want?

Thanks.

2 Likes

#2

you could show the quick panel with the flag sublime.KEEP_OPEN_ON_FOCUS_LOST

2 Likes

#3

Thanks kingkeith.

With KEEP_OPEN_ON_FOCUS_LOST you can switch focus in to the view in another group and then switch focus back again, which has the desired effect, but unfortunately when you switch back the show_quick_panel() loses the focus. It is still displayed but you have to click on it to regain the focus so it is not a solution for what I need.

1 Like

#4

I’ve just had a play with the sheet methods and they can’t be used to switch active focus in another group, although you can switch focus using them with focus_sheet(sheet) but it just does the same thing as focus_view(view).

Is there any way to give the focus back to the show_quick_panel() if it loses focus (using the API)?

1 Like

#5

I had the idea that maybe a view object is created for a quick panel, even if it isn’t returned by the API, and could therefore be discovered by checking the window’s views immediately before and after showing the quick panel (and thus allow one to use window.focus_view) but unfortunately this seems to not be the case:

print(len(view.window().views()))
view.window().show_quick_panel(['abc'], lambda index: print(index))
print(len(view.window().views()))

the before and after lists of views are the same

I think the only way to re-focus the quick panel is to re-show it

1 Like

#6

Thanks, that’s a very good idea. BUT…

When I call show_quick_panel() from the on_highlighted method, it doesn’t work - a message is displayed in the console which says “Quick panel unavailable”. The same message is shown if instead I try to re-launch the plugin using a window.run_command().

Any ideas?

1 Like

#7

Update:

You can close the panel and then relaunch the plugin from the on_highlighted method using hide_panel and set_timeout with something like:

self.window.run_command("hide_panel", {"cancel": True})
sublime.set_timeout(lambda: self.window.run_command("command_name", args), 1)

However when you do this there is often a noticeable flicker, so no luck there.

What is really needed is this, but I won’t be holding my breath.

Cheers.

1 Like

#8

I might be wrong about this, but iirc both on_activated and on_deactivated get called for the quick panel views. I seem to remember that I experimented with this a while ago and that there were problems with focussing the quick panel again since none of the “usual” methods worked, but can’t find the thread right now.

1 Like

#9

Sorry to take so long to say thanks for the info., I’ve been unwell and then catching up. I appreciate the pointer to the EventListener class and I’ll have a play with it. Cheers.

1 Like

Package Control setting up a single package for use with 'Add Repository'
#10

You can catch their views while they are open by running a window command. I used this technique to create this package to remember the Command Palette input.

import sublime
import sublime_plugin

class BugCommand(sublime_plugin.WindowCommand):

    def run(self):
        self.window.run_command( "show_overlay", {"overlay": "command_palette"} )
        self.window.run_command( "select_all" )
        self.window.run_command( "bug_helper" )
        self.window.run_command( "select_all" )

# Now, this text command will be called with the Command Palette view 
#  and I can capture its input text and save it for later on
class BugHelperCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        selections = self.view.sel()
        current_widget_text = self.view.substr( selections[0] )

        if len( current_widget_text ):
            print( 'current_widget_text', current_widget_text )
            self.view.erase( edit, selections[0] )

        self.view.run_command( "append", {"characters": "about"} )
1 Like