Open panels on mouse-over.
-
For the CSS version, mine is not perfect, but it gets the icons to appear again on the side.
Change this part from#panels-container.overlay {width:0 !important;}
to
#panels-container.overlay.icons:not(:hover) {width:0 !important;}
-
@nafumofu thank you very much, I really missed this mod!
But how did you know it was
pointerdown
andpointerup
? I've tried a lot of combinations ofdispatchEvent
withclick
,mousedown
andmouseup
, but I missed thepointer
. -
@oudstand I use DeepL to read and write English, so my explanation may not come across well.
I removed the mouse events from the
#app
element one by one from the developer tools and verified that the panel button clicks worked.
-
@nafumofu ah nice idea, thanks for that!
-
Fixed to work with 6.0, auto open with a mouse gesture
#panels-container.left, #panels-container.right { position: absolute; z-index: 1; height: 100%; transition: transform 0.15s 0s !important; } #panels-container.right { right: 0; } #panels-container.left:not(:hover) { transform: translateX(-100%); transition: transform 0.8s 0s !important; contain: unset !important; } #panels-container.right:not(:hover) { transform: translateX(100%); transition: transform 0.8s 0s !important; contain: unset !important; }
-
@nafumofu hello. i've been using your code since april this year, & it's great. it still works in
6.3.3120.3
. there is one unfortunate side-effect though, which interferes with a basic function of vivaldi i've used since 2015.if i am adding an active tab to my bookmarks, rather than use the bookmark dropdown menu in the address bar, i often find it more convenient to open the bookmark panel then drag the tab via its address bar padlock icon into the bookmark panel & therein position it in the desired place in the hierarchy.
at least, that's what i used to do, & which used to work fine, before i began using this mod. with this mod active, however, i find it hard or impossible to still do that. dragging the tab down & across to the bm panel icon opens the panel [per the mod] but it instantly closes again too fast for me to actually place the tab in the hierarchy.
the only way i have found that does work, but which is so inconvenient as to be impractical, is that before i begin trying to create a new bm by this dragging & dropping, i need to go to Settings, & temporarily disable the
floating panel
option... then afterwards, re-enable it.do you, or does anyone else, have a more elegant solution pls?
Ha, this; me too! https://forum.vivaldi.net/post/241057
UPDATE:
this seems like it might help a bit:
https://forum.vivaldi.net/post/696112 -
The code has been cleaned up and corrected.
Some bugs have also been fixed.// https://forum.vivaldi.net/topic/28413/open-panels-on-mouse-over/22?_=1593504963587 (function() { 'use strict'; function panelMouseOver(autoHide, delay_show, delay_change, delay_hide) { function simulateClick(element) { element.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, pointerId: 1 })); element.dispatchEvent(new PointerEvent('mousedown', { bubbles: true, detail: 1 })); element.dispatchEvent(new PointerEvent('pointerup', { bubbles: true, pointerId: 1 })); element.dispatchEvent(new PointerEvent('mouseup', { bubbles: true, detail: 1 })); element.dispatchEvent(new PointerEvent('click', { bubbles: true })); } function getActiveButton() { return document.querySelector('#switch .active > button'); } function setActive(button, doDelay) { clearTimeout(show_token); const delay = doDelay ? (!getActiveButton() ? delay_show : delay_change) : 0; show_token = setTimeout(function() { simulateClick(button); }, delay); } function hidePanel() { if (document.querySelector('#panels-container.overlay:not(.icons)')) { setTimeout(function() { const activeButton = getActiveButton(); if (activeButton) { simulateClick(activeButton); } }, delay_hide); } } function isPanelButton(element) { return element.matches('button:is([name^="Panel"], [name^="WEBPANEL_"]):not([name="PanelWeb"])'); } function setListeners() { function eventHandler(event) { if (isPanelButton(event.target) && !event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) { switch(event.type) { case 'mouseenter': setActive(event.target, true); break; case 'mouseleave': clearTimeout(show_token); break; case 'dragenter': setActive(event.target, false); break; } } } if (autoHide) { document.querySelector('#webview-container').addEventListener('mouseenter', hidePanel); } const panelSwitch = document.querySelector('#switch'); panelSwitch.addEventListener('mouseenter', eventHandler, { capture: true }); panelSwitch.addEventListener('mouseleave', eventHandler, { capture: true }); panelSwitch.addEventListener('dragenter', eventHandler, { capture: true }); } let show_token = null; setListeners(); } setTimeout(function waitMouseOver() { const browser = document.querySelector('#browser'); if (browser) { panelMouseOver(true, 100, 50, 250); } else { setTimeout(waitMouseOver, 300); } }, 300); })();
Edit: Disable while modifier key is pressed.
-
@nafumofu oh this is so lovely thanks; it now works beautifully again, thus making manual bookmarking as i'd described simple & reliable once again ... no more frustrating "slamming shut", or even worse, high frequency open close open close open close like before. i wonder how long before the v devs will damage or break it again, heehee
-
@nafumofu Doesn't work for me,what would be the reason?
-
Basic question... where do I put the js file? I'm on Vivaldi 6.2 for Mac.
Another post I read said to look in the App's package contents/resources. but I don't see any folders that look like they're for js.
Anyone know?
-
@rrsch said in Open panels on mouse-over.:
where do I put the js file?
See this (long) thread
https://forum.vivaldi.net/topic/10549/modding-vivaldi -
This post is deleted! -
@Darthagnon Works like a charm, pretty incredible, thank you so much! Now the utility of Arc Browser is more questionable.
-
@nafumofu
Great. But the focus stays on the hidden panel, after you press a shortcut to show/hide a panel.
How can we focus the page back after without an additional shortcut? -
@nafumofu is there a way to modify this so that the panel closes whenever the mouse in not on the panel, rather than clicking the corresponding panel button?
-
@n8chavez
Are you saying that you want to close a panel with a mouse out, even if the panel's overlay mode is disabled? -
@nafumofu said in Open panels on mouse-over.:
@n8chavez
Are you saying that you want to close a panel with a mouse out, even if the panel's overlay mode is disabled?Well, yes. The way it works now the mouse needs be be hovered over the activate panel again in order for it to close. Except that the panel switching is very sensitive and the panel switches quite easily and unintentionally. That makes closing the panel not so easy. Having the panels close with a mouse-out would be easier.
-
Refactoring of code.
Added ability to automatically close panels in fixed view mode.// https://forum.vivaldi.net/topic/28413/open-panels-on-mouse-over/22?_=1593504963587 (async () => { 'use strict'; const config = { // WebView にマウスポインターが入るか、WebView にフォーカスが移ると自動的にパネルを閉じる (true: 有効, false: 無効) // Automatically close the panel when the mouse pointer enters the WebView or when the focus moves to the WebView (true: enabled, false: disabled) auto_close: true, // 固定表示モードで自動的にパネルを閉じる (true: 有効, false: 無効) // Automatically close the panel in fixed display mode (true: enabled, false: disabled) close_fixed: false, // パネルを開くまでの遅延時間 (ミリ秒) // Delay time before opening the panel (milliseconds) open_delay: 100, // パネルを切り替えるまでの遅延時間 (ミリ秒) // Delay time before switching the panel (milliseconds) switch_delay: 50, // パネルを閉じるまでの遅延時間 (ミリ秒) // Delay time before closing the panel (milliseconds) close_delay: 250, }; const addStyleSheet = (css) => { const styleSheet = new CSSStyleSheet(); styleSheet.replaceSync(css); document.adoptedStyleSheets = [...document.adoptedStyleSheets, styleSheet]; }; const fixWebViewMouseEvent = () => { addStyleSheet(` #main:has(#panels-container:hover) #webview-container { pointer-events: none !important; } `); }; const waitForElement = (selector, startNode=document) => { return new Promise((resolve) => { const timerId = setInterval(() => { const elem = startNode.querySelector(selector); if (elem) { clearInterval(timerId); resolve(elem); } }, 100); }); }; const simulateClick = (element) => { element.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true, pointerId: 1 })); element.dispatchEvent(new PointerEvent('mousedown', { bubbles: true, detail: 1 })); element.dispatchEvent(new PointerEvent('pointerup', { bubbles: true, pointerId: 1 })); element.dispatchEvent(new PointerEvent('mouseup', { bubbles: true, detail: 1 })); element.dispatchEvent(new PointerEvent('click', { bubbles: true })); }; const getActiveButton = () => document.querySelector('#panels .active > button'); const togglePanel = (button, doDelay) => { const delay = doDelay ? (getActiveButton() ? config.switch_delay : config.open_delay) : 0; clearTimeout(showToken); showToken = setTimeout(() => { simulateClick(button); }, delay); }; const closePanel = () => { if (!config.close_fixed && !document.querySelector('#panels-container.overlay')) return; setTimeout(() => { const activeButton = getActiveButton(); if (activeButton) { simulateClick(activeButton); } }, config.close_delay); }; const isPanelButton = (element) => element.matches('button:is([name^="Panel"], [name^="WEBPANEL_"]):not([name="PanelWeb"])'); let showToken; const panelMouseOver = () => { const eventHandler = (event) => { if (isPanelButton(event.target) && !event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) { switch(event.type) { case 'mouseenter': togglePanel(event.target, true); break; case 'mouseleave': clearTimeout(showToken); break; case 'dragenter': togglePanel(event.target, false); break; } } }; if (config.auto_close) { document.querySelector('#webview-container').addEventListener('mouseenter', closePanel); document.querySelector('#webview-container').addEventListener('animationstart', event => { if (event.target.matches('webview') && event.animationName === 'delay_visibility') { closePanel(); } }); } const panels = document.querySelector('#panels'); panels.addEventListener('mouseenter', eventHandler, { capture: true }); panels.addEventListener('mouseleave', eventHandler, { capture: true }); panels.addEventListener('dragenter', eventHandler, { capture: true }); }; await waitForElement('#browser'); fixWebViewMouseEvent(); panelMouseOver(); })();
-
Hey there, first of all I'm a newbie when it comes to programming but I'm really looking after a way to implement some sort of "open panel on mouse over" functionality in Vivaldi. Can anyone kindly explain to me how to install or save this script?
-