When using the FocusManager, focus is moved away from the currently focused component whenever any component on the page is hidden. I believe this is just a simple logic error in FocusManager.js.

To reproduce:
  1. Load up the test page below
  2. Begin typing in the text field
  3. When the flashing component is hidden, focus will be stolen from the text field
The error is in FocusManager.onComponentHide, in this block:
Code:
                        if (cmpHadFocus && parent = cmp.up(':focusable')) {
                            parent.focus();
                        } else {
                            me.focusEl.focus();
                        }
This will always change focus, even if cmpHadFocus = false. I think this block should be:
Code:
                    if (cmpHadFocus) {
                        if (parent = cmp.up(':focusable')) {
                            parent.focus();
                        } else {
                            me.focusEl.focus();
                        }
                    }
To see patched behavior, change "withPatch = false" to TRUE in the example page.


Example page:

HTML Code:
<!DOCTYPE html>
<html>
<head>
    <title>Ext Test</title>
    
    <!-- Ext -->
    <script type="text/javascript" src="extjs-4.1.0/ext-all.js"></script>

    <script type="text/javascript">
    
        // CHANGE THIS TO SEE BROKEN OR FIXED BEHAVIOR
        var withPath = false;
        
        Ext.onReady(function() {
            
            Ext.FocusManager.enable();
            if (withPath) {
                Ext.FocusManager.onComponentHide = function(cmp) {
                        var me = this,
                        cmpHadFocus = false,
                        focusedCmp = me.focusedCmp,
                        parent;
    
                    if (focusedCmp) {
                        // See if the Component being hidden was the focused Component, or owns the focused Component
                        // In these cases, focus needs to be removed from the focused Component to the nearest focusable ancestor
                        cmpHadFocus = cmp.hasFocus || (cmp.isContainer && cmp.isAncestor(me.focusedCmp));
                    }
    
                    me.clearComponent(cmp);
    
                    // Move focus onto the nearest focusable ancestor, or this is there is none
                    if (cmpHadFocus) {
                        if (parent = cmp.up(':focusable')) {
                            parent.focus();
                        } else {
                            me.focusEl.focus();
                        }
                    }
                };
            }
            
            Ext.create('Ext.form.field.Text', {
                renderTo: Ext.getBody(),
                fieldLabel: 'Type here and lose focus when the view hides',
                width: 500
            });
            var view = Ext.create('Ext.Component', {
                style: 'background-color: blue; color: white; padding: 10px;',
                html: 'This is flashy',
                floating: true,
                focusOnToFront: false,
                shadow: false,
                width: 100,
                height: 100,
                x: 300,
                y: 300
            })
            Ext.TaskManager.start({
                run: function(){
                    if (view.isVisible()) {
                        view.hide();
                    }
                    else {
                        view.show();
                    }
                },
                interval: 3000 //1 second
            });
        });
    </script>
    
</head>
<body>
    
</body>
</html>