I have an app that is basically just a wrapper for an internal company website. The idea is to easily load the website in its own window on my Chromebook, that way it won't unload when RAM gets low.
I have a very simple app with a single WebView that consumes an entire app window. The problem is, whenever I switch away from the window and come back, the webview has lost focus. This is particularly annoying because it's a chat app, and I'd like to start talking immediately upon alt-tabbing back to the window.
I've looked into focusing the webview each time the window receives focus, but the disconnect between Window (from chrome.windows) and AppWindow (from chrome.app.window) makes this nontrivial. The event that I need only exists for Window objects, but I can only definitively obtain the current AppWindow. I could theoretically get the currently active Window when the app first launches, but that seems hackish and unreliable.
<!DOCTYPE html>
<html>
<head>
<title>Chat App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<webview src="https://example.com/" id="chat"></webview>
</body>
</html>
chrome.app.runtime.onLaunched.addListener(function(launchData) {
chrome.app.window.create(
'index.html',
{
id: 'chat'
}
);
});
Making the webview consume the entire window was a bit tricky; I had to use some redundant CSS properties to get it to work properly.
html, body {
margin: 0;
padding: 0;
overflow: hidden;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
#chat {
border: 0 none;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
You can achieve this simply with the Page Visibility API. You can use it to add an event listener and check the document.hidden
state to return focus to the chat box. You can also do other things, like play an audio alert when you receive chat messages when the tab is not visible.
In this example, I've also added an event listener to the first chat box so if focus is lost, it tries to get it again. This is a rather heavy-handed approach, but you can adjust your logic to suit requirements.
JSFiddle
function handleVisibilityChange() {
console.log(document.hidden);
if (!document.hidden) {
chatFocus();
}
}
function chatFocus() {
document.getElementById("ChatBox1").focus();
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);
document.getElementById("ChatBox1").addEventListener("blur", chatFocus, true);
<input type="text" id="ChatBox1" placeholder="ChatBox1">
<input type="text" id="ChatBox2" placeholder="ChatBox2">
Testing this on Chrome, you'll find that if you switch to another tab, or minimize the window, the visibilitychange
event will be fired. If you just switch to another window, though, it won't consider the page to be hidden. You can also make use of window.onblur
to listen for when the page loses focus in general.
PS. About your 'tricky' redundant CSS: specifying left: 0
and width: 100%
should be all you need (right: 0
shouldn't be necessary), but in addition to that, text fields tend to have border and padding etc. so in order to ensure the field doesn't end up wider than its container, you need to set box-sizing: border-box
so that padding and borders are included when determining its size. It's a trick that solves many problems in CSS.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With