Skip to content

Instantly share code, notes, and snippets.

@jviereck
Created March 12, 2010 21:46
Show Gist options
  • Select an option

  • Save jviereck/330824 to your computer and use it in GitHub Desktop.

Select an option

Save jviereck/330824 to your computer and use it in GitHub Desktop.
From: Julian Viereck <julian.viereck@gmail.com>
Make sure that SC.Responder get refocused after the user reenters the page.
diff --git a/frameworks/desktop/system/root_responder.js b/frameworks/desktop/system/root_responder.js
index 497b615..d81c036 100644
--- a/frameworks/desktop/system/root_responder.js
+++ b/frameworks/desktop/system/root_responder.js
@@ -34,6 +34,12 @@ SC.RootResponder = SC.RootResponder.extend(
platform: 'desktop',
+ /** @property
+ A object that uses the SC.Responder mixin which should be refocused after the page
+ got the focus back again.
+ */
+ refocusView: null,
+
// ..........................................................
// ORDERED PANES
//
@@ -323,6 +329,33 @@ SC.RootResponder = SC.RootResponder.extend(
SC.RunLoop.begin();
this.set('hasFocus', YES);
SC.RunLoop.end();
+
+ // If there is a SC.Responder that lost focus because the entire page lost
+ // focus, then refocus this one.
+ var refocusView = this.get('refocusView');
+ var self = this;
+ if(!SC.none(refocusView)) {
+ // Delay the refocus process by a few ms. This is neccesary as the
+ // following can happen:
+ //
+ // 1) user clicks on the URL bar
+ // 2) hasFocus changes to "true"!
+ // 3) focus the SC.View (withouthDelay!)
+ // 4) hasFocus changes to "false"
+ // 5) URL bar has the focus now
+ //
+ // The delay prevents step 3 and make sure that the SC.View only gets
+ // the focus if it really should.
+ setTimeout(function() {
+ if (SC.none(self.getPath('keyPane.firstResponder')) &&
+ self.get('hasFocus')) {
+ // Refocus the last selcted SC.View.
+ SC.RunLoop.begin();
+ refocusView.becomeFirstResponder();
+ SC.RunLoop.end();
+ }
+ }, 50);
+ }
}
return YES ; // allow default
},
@@ -338,6 +371,15 @@ SC.RootResponder = SC.RootResponder.extend(
SC.RunLoop.begin();
this.set('hasFocus', NO);
SC.RunLoop.end();
+
+ // Safari doesn't call the resignFirstResponder by default. As this, we
+ // have to call this manually on the current firstResponder if there is any.
+ var firstResponder = SC.RootResponder.responder.keyPane.firstResponder;
+ if (SC.browser.current == 'safari' && !SC.none(firstResponder)) {
+ SC.RunLoop.begin();
+ firstResponder.resignFirstResponder();
+ SC.RunLoop.end();
+ }
}
return YES ; // allow default
},
@@ -447,7 +489,7 @@ SC.RootResponder = SC.RootResponder.extend(
trigger a keyDown.
*/
keypress: function(evt) {
- var ret ;
+ var ret;
// delete is handled in keydown() for most browsers
if (SC.browser.mozilla && (evt.which === 8)) {
@@ -623,9 +665,6 @@ SC.RootResponder = SC.RootResponder.extend(
SC.RunLoop.begin();
try {
- // make sure the view gets focus no matter what. FF is inconsistant
- // about this.
- this.focus();
// only do mouse[Moved|Entered|Exited|Dragged] if not in a drag session
// drags send their own events, e.g. drag[Moved|Entered|Exited]
if (this._drag) {
diff --git a/frameworks/foundation/system/responder.js b/frameworks/foundation/system/responder.js
index 97478e6..49c8183 100644
--- a/frameworks/foundation/system/responder.js
+++ b/frameworks/foundation/system/responder.js
@@ -87,8 +87,19 @@ SC.Responder = SC.Object.extend( /** SC.Responder.prototype */ {
*/
resignFirstResponder: function() {
var pane = this.get('pane') || this.get('responderContext');
+ console.log('resignFirstResponder');
if (pane && (pane.get('firstResponder') === this)) {
pane.makeFirstResponder(null);
+
+ var view = this;
+ var responder = SC.RootResponder.responder;
+ responder.set('refocusView', null);
+ setTimeout(function() {
+ if (!responder.hasFocus) {
+ console.log('resignFirstResponder == store the view', view);
+ responder.set('refocusView', view);
+ }
+ }, 0);
}
return YES;
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment