Index: _source/core/dom/domobject.js
===================================================================
--- _source/core/dom/domobject.js	(revision 3660)
+++ _source/core/dom/domobject.js	(working copy)
@@ -85,7 +85,7 @@
 				var listener = nativeListeners[ eventName ] = getNativeListener( this, eventName );
 
 				if ( this.$.addEventListener )
-					this.$.addEventListener( eventName, listener, false );
+					this.$.addEventListener( eventName, listener, !!CKEDITOR.event.useCapture );
 				else if ( this.$.attachEvent )
 					this.$.attachEvent( 'on' + eventName, listener );
 			}
Index: _source/plugins/floatpanel/plugin.js
===================================================================
--- _source/plugins/floatpanel/plugin.js	(revision 3660)
+++ _source/plugins/floatpanel/plugin.js	(working copy)
@@ -102,6 +102,7 @@
 				var panel = this._.panel,
 					block = panel.showBlock( name );
 
+				this.allowBlur( false );
 				isShowing = true;
 
 				var element = this.element,
@@ -134,8 +135,26 @@
 					// Non IE prefer the event into a window object.
 					var focused = CKEDITOR.env.ie ? iframe : new CKEDITOR.dom.window( iframe.$.contentWindow );
 
-					focused.on( 'blur', function()
+					// With addEventListener compatible browsers, we must
+					// useCapture when registering the focus/blur events to
+					// guarantee they will be firing in all situations. (#3068, #3222 )
+					CKEDITOR.event.useCapture = true;
+
+					focused.on( 'blur', function( ev )
 						{
+							if ( CKEDITOR.env.ie && !this.allowBlur() )
+								return;
+
+							// As we are using capture to register the listener,
+							// the blur event may get fired even when focusing
+							// inside the window itself, so we must ensure the
+							// target is out of it.
+							var target = ev.data.getTarget(),
+								targetWindow = target.getWindow && target.getWindow();
+
+							if ( targetWindow && targetWindow.equals( focused ) )
+								return;
+
 							if ( !this._.activeChild && !isShowing )
 								this.hide();
 						},
@@ -145,9 +164,12 @@
 						{
 							this._.focused = true;
 							this.hideChild();
+							this.allowBlur( true );
 						},
 						this );
 
+					CKEDITOR.event.useCapture = false;
+
 					this._.blurSet = 1;
 				}
 
@@ -239,6 +261,15 @@
 				}
 			},
 
+			allowBlur : function( allow )	// Prevent editor from hiding the panel. #3222.
+			{
+				var panel = this._.panel;
+				if ( allow != undefined )
+					panel.allowBlur = allow;
+
+				return panel.allowBlur;
+			},
+
 			showAsChild : function( panel, blockName, offsetParent, corner, offsetX, offsetY )
 			{
 				this.hideChild();
