Introduction
Mac OS X Lion has a full screen feature that allows use of a single application window in full screen, i.e. without window title bar and constantly visible menu bar, on its own virtual desktop.
There's a problem however. If you press Escape while in full screen, and the application does not consume the event, you leave full screen. If we dismiss accidental key presses, this leaves programs that react to keyUp
, but neither of keyDown
and keyPress
.
It did take some time to determine the details in this question. Only @dpk figured it out in the last few comments to the question, the other comments and answers are mostly useless or just plain wrong.
Request
The behavior described above appears with the "dialogs" on the Stack Exchange sites. They can be dismissed by pressing Escape. Since they only react to keyUp
, the key press itself is not consumed by the browser.
Please change, at least on OS X, the behavior of these dialog boxes: They should response to a different event. Alternatively, consume any Esc keyDown
in browser on Mac OS X, just to keep use of Esc from closing the dialog, while the dialog is visible.
IMO, it makes sense for a web site UI to prevent a web browser's default action on keyDown
/keyPress
(whatever that action is) if the keyUp
event on the web page is responded to. If limited to when such a dialog is visible, this shouldn't hurt any default functionality, especially since a repeated key press will perform the default action. But allowing the program to perform two unrelated actions when a key is pressed doesn't make any sense at all. So either remove the Escape functionality for dialog boxes, or also intercept the other events.
Early proof of concept
The following bookmarklet achieves the desired effect for the close dialog:
javascript:(function(){document.onkeydown=function(evt){if(evt.keyCode==27&&document.getElementById('close-question-popup').style.display!='none')return false;};})();
It'd be no sane one-liner if I'd include the flag popups, as their element IDs contain the related post's ID, and there is one for each answer.
Bug classification
Apparently, the proper way to handle this is preventDefault
. It appears to be something that is expected on anyone doing event handling: Handle all events that are triggered when a particular key is pressed so no unexpected side effects (such as the one presented here) occur. Therefore retagging to a bug.
User script fix
Here's a user script (4 lines of boiler plate code from here) that will fix this behavior:
// ==UserScript==
// @name SE Lion Full Screen Compatibility
// @namespace http://meta.stackexchange.com/q/113212
// @description Makes SE sites behave in Mac OS X Lion's full screen mode
// @include http://stackoverflow.com/*
// @include http://meta.stackoverflow.com/*
// @include https://superuser.com/*
// @include http://meta.superuser.com/*
// @include http://serverfault.com/*
// @include http://meta.serverfault.com/*
// @include http://askubuntu.com/*
// @include http://meta.askubuntu.com/*
// @include http://answers.onstartups.com/*
// @include http://meta.answers.onstartups.com/*
// @include http://nothingtoinstall.com/*
// @include http://meta.nothingtoinstall.com/*
// @include http://seasonedadvice.com/*
// @include http://meta.seasonedadvice.com/*
// @include https://stackapps.com/*
// @include http://*.stackexchange.com/*
// @exclude http://chat.stackexchange.com/*
// @exclude http://chat.*.stackexchange.com/*
// @exclude http://api.*.stackexchange.com/*
// @exclude http://data.stackexchange.com/*
// ==/UserScript==
function with_jquery(f) {
var script = document.createElement("script");
script.type = "text/javascript";
script.textContent = "(" + f.toString() + ")(jQuery)";
document.body.appendChild(script);
}
with_jquery(function ($) {
$('body').keydown(function (e) {
if (e.keyCode === 27) {
if ($('#close-question-popup').is(":visible") || $("*[id*='flag-popup-']").is(":visible")) {
e.preventDefault();
}
}
});
});
It currently supports the following dialogs:
- Close question dialog
- Flag question and flag answer dialogs
Tested on Safari using NinjaKit only, but should be simple enough to work in other browsers. I'm not an experienced jQuery/user script programmer (as should be obvious), so feel free to fix bugs or suggest improvements. Please also provide the IDs of other dialogs that can be closed with Escape so they can be added to the script.
This post on Super User links to a few user script plugins, and contains another user script that will prevent Escape from leaving full screen mode in browsers on all sites.
Radar issue
I submitted a bug report to Apple against Safari 5 on February 24. It is tracked as Bug ID# 10926183 (rdar://10926183
). If you want to support this issue, please file bugs yourself and mention that they're duplicates of this issue. I don't think anything will come from this, since it's a bug resulting from carelessness by the web developers who implemented the event handling, but it's worth a try. In any case, this will only help with Safari. Consider submitting a similar issue to your favorite browser vendor.
Below is the description I submitted to Apple, Markdown formatted for MSO.
Safari leaves full screen mode in Lion even if some key events are handled
Summary:
Safari leaves OS X Lion full screen mode on web pages handling only the keyUp event for the Escape key, which is often used by web page authors to provide some kind of keyboard navigation.
Safari, as a web browser, is highly dependent on content and scripts provided by web pages. JavaScript can handle events like keyDown and keyUp, and many web sites use these to implement keyboard navigation. Unfortunately, leaving full screen mode only requires the keyDown event being unhandled.
Steps to Reproduce:
- Create a web page document with the following JavaScript code:
<script type="text/javascript">document.onkeyup = function (evt) { if (evt.keyCode == 27) alert("keyUp"); e.preventDefault(); return false; }</script>
- Open that web page document
- Go into full screen mode
- Press Escape
Expected Results:
Safari does not leave full screen mode.
Actual Results:
Safari does leave full screen mode.
Regression:
-
Notes:
Full screen mode is not left when the web page responds to keyDown instead. Full screen mode is only left upon releasing the key, even though this functionality seems to be triggered from the keyDown event.
Safari, as a web browser, is highly dependent on content and scripts provided by web pages. JavaScript can handle events like keyDown and keyUp, and many web sites use this to implement keyboard navigation.
Many web sites implement non-character key handling by registering a keyUp event handler. Pressing Escape to invoke some web site functionality will therefore both invoke the functionality and leave full screen mode, since no keyUp event can be triggered without keyDown.
Given the provided script code, the web page author intended for no default browser functionality to be invoked when the user presses the Escape key. Safari should not leave full screen mode in this situation even though technically it's an issue with the web page script programming not prevent default functionality of all events invoked when a key is pressed.