fwextensions / QuicKey

Jump between recent tabs in Chrome via keyboard shortcuts or a most recently used (MRU) menu.
https://fwextensions.github.io/QuicKey
217 stars 22 forks source link

Separate QuicKey Window #31

Open MartinLichtblau opened 4 years ago

MartinLichtblau commented 4 years ago

I use another Chrome extension to switch tabs, namely Quick Tabs, and implemented some new features which proved utmost useful.

For one, the ability to open the extension from anywhere, even outside Chrome, with a global shortcut. This is a gamechanger in terms of uxp. If this short descriptions teased your interest I can tell you more and how it's done.

Further features are, 0 loading time to detect rapid key releases by keeping extension open as a distinct background tab and simply changing it's window id to move it in view, tab release functions to select, tab/window preview UI like windows Alt+Tab and Win+Tab, to get overview of tabs in window and select/search tabs based on preview.

MartinLichtblau commented 4 years ago

I wonder why you put all that effort in this project. Don't get me wrong, it's great work ‒ splendid code and overall professional project! But, there are many (4+) alternative chrome extensions you could use. Why create it all by yourself?

fwextensions commented 4 years ago

See my response in this issue: https://github.com/fwextensions/QuicKey/issues/27#issuecomment-600931662

I'm not entirely sure, but it sounds like you're suggesting focusing a tab when an extension command is pressed, rendering a MRU tab list in that tab, moving the selection down the list when the same shortcut is pressed, and then listening for the alt up event to switch to the selected tab.

QuicKey already does that using a different key to navigate the list from the key used to trigger the menu (since they can't be the same). The advantage of using a whole tab for the UI is using the same key to navigate the list, though it does feel heavier than just opening a menu from the toolbar.

MartinLichtblau commented 4 years ago

Thank you for the comprehensive explanation. I fixed most of the disadvantages in my Quicktabs fork. Having done that, I have to admit that your code is superior to that of Quicktabs. However there are many more extensions with the same functionality.

The advantage of separate tab is that it can be opened from anywhere (e.g. windows explorer, Desktop, Word), has zero delay and, as you mentioned, enables press/release shortcut to open, navigate/search and select tabs.

I deem such an extension highly useful in today's time where most activities happen inside the browser. What I want is to unify our efforts to build something bigger. I envision a OS>Windows native app to switch and search not only Chrome tabs but windows and tabs of any kind, e.g. Explorer, Notepad, Paint, Powerpoint, etc. This would greatly streamline digital work, by fast searching and switching between applications and their views/tabs, going seamlessly back & forth. I will advocate for this new way of navigation by contacting Windows support directly, or we could build such a tool ourselves. In this comment I gave a bit more detailed explanation of the idea.

infokiller commented 4 years ago

As an extra data point, I find the matching of this extension far better than others I tried. It's also very snappy. @MartinLichtblau try a few queries with many tabs open and see for yourself.

fwextensions commented 4 years ago

@MartinLichtblau I've pushed a new branch that adds a keyboard shortcut for rendering the UI in a separate popup window. If you press the Activate the extension shortcut, it opens in the menu that drops down from the toolbar. If you press the new Open menu in popup window shortcut, QuicKey will open in a popup window centered on the current window.

The first tab in the menu is selected by default, so if you press the shortcut and then just release the modifier, it will toggle between the two most recent tabs, like alttab. Unlike the default altQ shortcut, you can use the same base key to navigate the menu. So if you set the shortcut to, say, altE, you can hold down alt and then repeatedly press E to move the selection, then release alt to go to that tab.

You can make the popup shortcut global to bring up the window from any app, as you mention. However, I'm not sure what you mean by it having "zero delay". It's noticeably slower to open a whole new window than just rendering a browser action popup. The whole window is also painted black just before it closes (though you'll only notice if you close the window without picking a tab). I tried moving the window offscreen instead of hiding it, but Chrome doesn't allow that. There's no way to hide an open extension window, AFAIK.

There also doesn't seem to be any way to tell if a Chrome window is in focus when the shortcut is set to global. It would ideally behave slightly differently if it's being launched from some other app.

Anyway, let me know what you think of the new behavior in that branch.

image

MartinLichtblau commented 4 years ago

@fwextensions I didn't want to cause you troubles. I just wanted to start a discussion and advocate for a cooperation project and you already dive deep in and get things done. Both programming issues are solvable, by keeping extension open as pinned tab in some window and detecting chrome focus is buggy but is possible with document focus/blur and chrome.tabs.getCurrent (could extract the lines) and opening is without delay because you simply move the popup tab into a separate window in focus where you want it, so all event listeners and everything is already initialized.

fwextensions commented 4 years ago

AFAICT, chrome.tabs.getCurrent() doesn't work correctly, so I'm still not sure how to tell if Chrome is in focus.

I'd thought about moving the QuicKey popup into another window, but 1) it would be sort of annoying to add an extra tab when users are likely to already have too many, and 2) I don't think it's possible to move a popup window into a tab.

I did see that it's possible to minimize a window, so that might be one way to hide and show it quickly. I'm not sure what that would do on Mac.

MartinLichtblau commented 4 years ago
fwextensions commented 4 years ago

I pushed some changes to the branch that minimize the QuicKey window after a tab is selected in it, instead of closing it and reopening it every time. On Windows, it's much faster now, though it took a lot of effort to work around a Chrome bug where the focus wasn't getting set correctly after unminimizing the window. On Mac, the minimize animation is very slow, so I'm not sure it's a good approach there.

I just realized that the chrome.windows.update() method can move the window off screen, even if window.open() can't. So that might be a faster and simpler way to hide the window in between invocations without having to add it as a tab to the user's window.

Curious what the workarounds for determining whether Chrome is in focus or not are.

MartinLichtblau commented 4 years ago
MartinLichtblau commented 4 years ago

You need three separate shortcuts to open popup (i) to search (ii) to select previous (iii) to select next. Found out that this works best.

fwextensions commented 4 years ago

Sometimes the window borders stop rendering for some reason. Have you ever seen that?

image

I'm also not able to position the window off-screen 100% reliably. Sometimes it gets into a state where Chrome doesn't allow it to move off-screen, so it's left at 0,0. Any ideas?

MartinLichtblau commented 4 years ago

Never seen a windows without border, didn't think that's possible since it's an integral part of any window. But I wouldn't care.

Since I move the tab and not the window I don't have any idea how to solve your issue. IMO pin tab and programatically moving it out/into an existing window is better; no rerendering, faster, no additional window but hiding within already existing one.

fwextensions commented 4 years ago

In the video you posted, I didn't see the window get added as a tab to the window, so I assume there was another one in the background. But if the user only has one window, there'd be some visible shifting of tabs as the popup moves in and out of that window. One advantage, though, is that it wouldn't show up in the alt-tab list as a separate window.

MartinLichtblau commented 4 years ago

Yes, I have multiple windows open. But even if it moves in/out of current window, it's not causing much shifting, since only the favicon is visualized in pin state. If this 5mm shift is still too much, you could keep the/a pinned tab in place as a placeholder. image

fwextensions commented 4 years ago

@MartinLichtblau I've been trying to hide the popup window by moving it to another window, but if I open it with type: "popup", moving that tab to another window gives a "Tabs can only be moved to and from normal windows." error. I can create it as a regular tab and move it to another window, but then it has all the location bar chrome.

It's also not clear how to move a tab from a regular window into a popup. There's no obvious API call to do that. I see that you can pass a tabId into chrome.windows.create(), which seems like it maybe loads that tab into a new window, but it feels slower than moving the window from offscreen into view.

MartinLichtblau commented 4 years ago

My mistake. I don't use tabs.move() but windows.create() with the tab-id of the hidden popup. Create popup tab in pinned state:

 chrome.tabs.create({  // keeps state when opened via url in window
      url: popupUrl,
      active: false,
      pinned: true,
      index: 1,
      windowId: tabs[tabs.length -1].windowId
    }, function(tab) {
      popupTabId = tab.id;
      chrome.history.deleteUrl({ url: popupUrl });
    });
  1. Create Window to show popup.
        chrome.windows.create(
            {
                // 'url': popupUrl,
                'tabId': popupTabId,
                'type': 'popup', // use popup instead of panel, so it's not included in browsing history and undo close tab function
                'width': width,
                'height': height,
                'left': left,
                'top': top,
                'focused': true
            }, function (window) {
                //console.log("popup window created: "+window.tabs[0].id);
            }
        );

Here is the crude code.

fwextensions commented 4 years ago

I see, you have to create the window as a tab first, then create the popup with that tab ID. I'm not creating it in a pinned state, so when hiding the popup, I move the tab back to a window. So that seems to work now.

Having tried both methods now, leaving the popup open and moving it offscreen to hide it still seems snappier, since you're not creating a window each time it's shown. A downside is that the popup is left in the alt-tab window stack, so if you use the popup to switch from a tab in one window to that in another, and then use alt-tab to go back, you'll get the popup. I'm not sure if there's a way to send a window all the way to the bottom of the stack.

On one Windows 10 machine, I'm also seeing an issue where the window borders are sometimes lost when it's hidden, and the window size can get changed each time it's shown. It's very strange. Just now realized that machine has a second virtual desktop set up, so possibly that's related.

Hmm, nope, both machines have a second virtual desktop, so that can't be it.

fwextensions commented 4 years ago

I've pushed some changes to the branch that lets you choose between hiding the popup window either off-screen or as a tab on the bottom-most window. The off-screen option still seems faster, as the popup window doesn't have to get created and torn down each time (even if the tab doesn't get reloaded, the containing window gets recreated).

I'm still seeing the off-screen window lose its borders periodically. Something on my work laptop seems to be resizing it every 30 minutes on the half-hour, and sometimes more often. I can't figure out what it is, though I think I can work around it by detecting the resize and fixing it.

MartinLichtblau commented 2 years ago

I'm happy to see you are working on this feature and that it will become public in version 2.0!? However, it has some bugs like, not responding to keys and appearing in odd places or multiple times. I remember facing very similar issues with my fork of Quicktabs.

So I don't know for sure how you intend to use the shortcut keys to search and switch. I improved my input approach for some time now and found a very ergonomic way to do so, just with three keys:

fwextensions commented 2 years ago

These are the current shortcuts. The "open in popup" shortcut works like your mod+previous example, and adding shift moves back up the list. The "search in popup" shortcut also navigates down the list, so if you change your mind and don't want to search, you can press the same key to start

The "switch to previous/next" shortcuts work like they currently do, by default. But there's an option to also show the popup while navigating. So you can see each tab as you navigate back into the stack, but with no cooldown period. Just release the modifier when you get to the tab you want. You can then press it again to jump back to where you started.

This branch has the latest popup window code if you want to try it out: https://github.com/fwextensions/QuicKey/tree/feature/2022/popup-window-ui

image

MartinLichtblau commented 1 year ago

Hey @fwextensions , glad to see you continue to improve QuicKey! The feature/2023/version-2 branch looks promising. The popup is very snappy now and looks great. But I still try to get used to the way the shortcuts work, plus I found some bugs.

I would change the shortcut behavior of the Search in alt-tab-style popup-shortcut like I described in my comment before.

More feedback: