Browse Source

Fixed focus problem when opening workbench window containing multiple view contents.

pull/14/head
Daniel Grunwald 15 years ago
parent
commit
93cd842df3
  1. 10
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs
  2. 5
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs
  3. 48
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs
  4. 32
      src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

10
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonDockLayout.cs

@ -58,18 +58,12 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -58,18 +58,12 @@ namespace ICSharpCode.SharpDevelop.Gui
void dockingManager_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "ActiveContent") {
#if DEBUG
if (WpfWorkbench.enableFocusDebugOutput)
LoggingService.Debug("AvalonDock: ActiveContent changed to " + WpfWorkbench.GetElementName(dockingManager.ActiveContent));
#endif
WpfWorkbench.FocusDebug("AvalonDock: ActiveContent changed to {0}", WpfWorkbench.GetElementName(dockingManager.ActiveContent));
if (ActiveContentChanged != null)
ActiveContentChanged(this, e);
CommandManager.InvalidateRequerySuggested();
} else if (e.PropertyName == "ActiveDocument") {
#if DEBUG
if (WpfWorkbench.enableFocusDebugOutput)
LoggingService.Debug("AvalonDock: ActiveDocument changed to " + WpfWorkbench.GetElementName(dockingManager.ActiveDocument));
#endif
WpfWorkbench.FocusDebug("AvalonDock: ActiveDocument changed to {0}", WpfWorkbench.GetElementName(dockingManager.ActiveDocument));
if (ActiveWorkbenchWindowChanged != null)
ActiveWorkbenchWindowChanged(this, e);

5
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonPadContent.cs

@ -43,10 +43,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -43,10 +43,7 @@ namespace ICSharpCode.SharpDevelop.Gui
if (!(IsActiveContent && !IsKeyboardFocusWithin))
return;
IInputElement activeChild = CustomFocusManager.GetFocusedChild(this);
if (activeChild == null && padInstance != null) {
activeChild = padInstance.InitiallyFocusedControl as IInputElement;
}
AvalonWorkbenchWindow.SetFocus(this, activeChild);
AvalonWorkbenchWindow.SetFocus(this, () => activeChild ?? (padInstance != null ? padInstance.InitiallyFocusedControl as IInputElement : null));
}
public void ShowInDefaultPosition()

48
src/Main/Base/Project/Src/Gui/Workbench/Layouts/AvalonWorkbenchWindow.cs

@ -38,33 +38,37 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -38,33 +38,37 @@ namespace ICSharpCode.SharpDevelop.Gui
protected override void FocusContent()
{
if (!(IsActiveContent && !IsKeyboardFocusWithin))
WpfWorkbench.FocusDebug("{0}.FocusContent() IsActiveContent={1} IsKeyboardFocusWithin={2} Keyboard.FocusedElement={3}",
Title, IsActiveContent, IsKeyboardFocusWithin, Keyboard.FocusedElement);
if (!(IsActiveContent && !IsKeyboardFocusWithin)) {
return;
IInputElement activeChild = CustomFocusManager.GetFocusedChild(this);
if (activeChild == null && ActiveViewContent != null) {
activeChild = ActiveViewContent.InitiallyFocusedControl as IInputElement;
}
AvalonWorkbenchWindow.SetFocus(this, activeChild);
IInputElement activeChild = CustomFocusManager.GetFocusedChild(this);
WpfWorkbench.FocusDebug("{0}.FocusContent() - Will move focus (activeChild={1})", this.Title, activeChild);
// use lambda for fetching the active child - this is necessary because the ActiveViewContent might change until the background
// action is called
AvalonWorkbenchWindow.SetFocus(this, () => activeChild ?? (ActiveViewContent != null ? ActiveViewContent.InitiallyFocusedControl as IInputElement : null));
}
internal static void SetFocus(ManagedContent m, IInputElement activeChild, bool forceSetFocus = false)
internal static void SetFocus(ManagedContent m, Func<IInputElement> activeChildFunc, bool forceSetFocus = false)
{
if (activeChild != null) {
LoggingService.Debug(m.Title + " - Will move focus to: " + activeChild);
m.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(
delegate {
// ensure that condition for FocusContent() is still fulfilled
// (necessary to avoid focus switching loops when changing layouts)
if (!forceSetFocus && !(m.IsActiveContent && !m.IsKeyboardFocusWithin)) {
LoggingService.Debug(m.Title + " - not moving focus (IsActiveContent=" + m.IsActiveContent + ", IsKeyboardFocusWithin=" + m.IsKeyboardFocusWithin + ")");
return;
}
LoggingService.Debug(m.Title + " - moving focus to: " + activeChild);
m.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(
delegate {
// ensure that condition for FocusContent() is still fulfilled
// (necessary to avoid focus switching loops when changing layouts)
if (!forceSetFocus && !(m.IsActiveContent && !m.IsKeyboardFocusWithin)) {
WpfWorkbench.FocusDebug("{0} - not moving focus (IsActiveContent={1}, IsKeyboardFocusWithin={2})",
m.Title, m.IsActiveContent, m.IsKeyboardFocusWithin);
return;
}
IInputElement activeChild = activeChildFunc();
WpfWorkbench.FocusDebug("{0} - moving focus to: {1}", m.Title, activeChild != null ? activeChild.ToString() : "<null>");
if (activeChild != null) {
Keyboard.Focus(activeChild);
}));
}
}
}));
}
public bool IsDisposed { get { return false; } }
@ -314,7 +318,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -314,7 +318,7 @@ namespace ICSharpCode.SharpDevelop.Gui
IViewContent vc = parentWindow.ActiveViewContent;
if (vc != null)
SetFocus(parentWindow, vc.InitiallyFocusedControl as IInputElement, true);
SetFocus(parentWindow, () => vc.InitiallyFocusedControl as IInputElement, true);
e.Handled = true;
}

32
src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs

@ -657,27 +657,26 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -657,27 +657,26 @@ namespace ICSharpCode.SharpDevelop.Gui
#endif
}
[Conditional("DEBUG")]
internal static void FocusDebug(string format, params object[] args)
{
#if DEBUG
if (enableFocusDebugOutput)
LoggingService.DebugFormatted(format, args);
#endif
}
#if DEBUG
internal static bool enableFocusDebugOutput;
static bool enableFocusDebugOutput;
void WpfWorkbench_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if (enableFocusDebugOutput) {
LoggingService.Debug("GotKeyboardFocus: oldFocus=" + e.OldFocus + ", newFocus=" + e.NewFocus);
if (e.NewFocus is IWorkbenchWindow)
{
}
}
FocusDebug("GotKeyboardFocus: oldFocus={0}, newFocus={1}", e.OldFocus, e.NewFocus);
}
void WpfWorkbench_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
if (enableFocusDebugOutput) {
LoggingService.Debug("LostKeyboardFocus: oldFocus=" + e.OldFocus + ", newFocus=" + e.NewFocus);
if (e.NewFocus is IWorkbenchWindow)
{
}
}
FocusDebug("LostKeyboardFocus: oldFocus={0}, newFocus={1}", e.OldFocus, e.NewFocus);
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
@ -693,10 +692,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -693,10 +692,7 @@ namespace ICSharpCode.SharpDevelop.Gui
output.WriteLine("ActiveWorkbenchWindow = " + GetElementName(this.ActiveWorkbenchWindow));
((AvalonDockLayout)workbenchLayout).WriteState(output);
LoggingService.Debug(output.ToString());
}
if (!e.Handled && e.Key == Key.L && e.KeyboardDevice.Modifiers == (ModifierKeys.Control | ModifierKeys.Shift | ModifierKeys.Alt)) {
this.UseLayoutRounding = !this.UseLayoutRounding;
this.StatusBar.SetMessage("UseLayoutRounding=" + this.UseLayoutRounding);
e.Handled = true;
}
if (!e.Handled && e.Key == Key.F && e.KeyboardDevice.Modifiers == (ModifierKeys.Control | ModifierKeys.Shift | ModifierKeys.Alt)) {
if (TextOptions.GetTextFormattingMode(this) == TextFormattingMode.Display)
@ -721,6 +717,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -721,6 +717,7 @@ namespace ICSharpCode.SharpDevelop.Gui
this.StatusBar.SetMessage("TextRenderingMode=" + TextOptions.GetTextRenderingMode(this));
}
}
#endif
internal static string GetElementName(object element)
{
@ -729,6 +726,5 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -729,6 +726,5 @@ namespace ICSharpCode.SharpDevelop.Gui
else
return element.GetType().FullName + ": " + element.ToString();
}
#endif
}
}

Loading…
Cancel
Save