Focus is not set to main form when floating document is closed #71

Closed
lextm opened this Issue Oct 25, 2012 · 5 comments

Comments

Projects
None yet
2 participants
Member

lextm commented Oct 25, 2012

By following #70's steps, we can see when the floating document is closed, main form does not receive focus. On my machine, another window such as Windows Explorer is focused instead.

This does not match how Visual Studio behaves in the same case.

tab09 commented May 12, 2013

I realize this has been open for a while and might not be up to date. However i thought i still share what i found.

The loss of focus dose also appear if the float document is docked to any other window as this results in closing the float. There can also be a very subtle loss of focus when dragging around documents that are docked from one docking position to another. However this is difficult to reproduce. I think it always happens if a pane is no longer used. Here is a setup were i see the loss of focus.

  1. Run DockSample and one document
  2. Put it into the middle and focus it
  3. drag it to the left - focus should remain within the document
  4. drag it to the bottom - focus is lost and given to the main form

I think i found a simple way to fix both. It is just a pair of missing parenthesis.

After digging a bit i ended up in the DockContentHandle.SetParent function. There is already a section marked as a workaround for a .net focusing issue. I think most the focus related problems that i see originate here.
I made two small modifications to the code.

So the important part of the original code is

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Workaround of .Net Framework bug:
// Change the parent of a control with focus may result in the first
// MDI child form get activated. 
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
bool bRestoreFocus = false;
if (Form.ContainsFocus)
{
    //Suggested as a fix for a memory leak by bugreports
    if (value == null && !IsFloat)
        if (!Win32Helper.IsRunningOnMono)
            DockPanel.ContentFocusManager.GiveUpFocus(this.Content);
    else
    {
        DockPanel.SaveFocus();
        bRestoreFocus = true;
    }
}         
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

most of the problem happens in the inner if clause. The way it is here on a windows pc DockPanel.SaveFocus() is never called. I changed it to

    //Suggested as a fix for a memory leak by bugreports
    if (value == null && !IsFloat)
    {
        if (!Win32Helper.IsRunningOnMono)
            DockPanel.ContentFocusManager.GiveUpFocus(this.Content);
    }
    else
    {
        DockPanel.SaveFocus();
        bRestoreFocus = true;
    }

this solves the problem in most cases. However when i dock a float that did not have the focus prior to dragging i will still lose focus. This is because the float window surrounding the form/Pane will have the focus (from clicking/draging it) and Form.ContainsFocus is false. To also properly save/restore the focus in this case i changed the first if clause to

if (Form.ContainsFocus || (IsFloat && FloatPane.FloatWindow.Focused))

this will however give the focus to the window that i draged (like VS dose).

All in all the code now looks like this

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Workaround of .Net Framework bug:
// Change the parent of a control with focus may result in the first
// MDI child form get activated. 
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
bool bRestoreFocus = false;
if (Form.ContainsFocus || (IsFloat && FloatPane.FloatWindow.Focused))
{
    //Suggested as a fix for a memory leak by bugreports
    if (value == null && !IsFloat)
    {
        if (!Win32Helper.IsRunningOnMono)
            DockPanel.ContentFocusManager.GiveUpFocus(this.Content);
    }
    else
    {
        DockPanel.SaveFocus();
        bRestoreFocus = true;
    }
}         
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

As far as i can tell this fixed all my problems with loosing focus to another application.

However there still is an issue with focusing that i see. Sometimes when i drag a document (that has focus) to become a float not the new float window but the last window that had focus before it is selected. This is however not always the case. I guess it is connected to the GiveUpFocus() and SuspendFocusTracking but i havened really looked into it.

lextm was assigned May 13, 2013

Member

lextm commented May 13, 2013

I will later review your proposed changes.

@lextm lextm added a commit that referenced this issue May 25, 2013

@lextm lextm Added brackets to fix #71. 9189f42

@lextm lextm added a commit that referenced this issue May 25, 2013

@lextm lextm Added brackets to fix #71. 79ebb75

lextm closed this in 844262e May 25, 2013

Member

lextm commented May 25, 2013

Please test the latest changes I committed. The focus issues should have been resolved.

tab09 commented Jun 11, 2013

Thanks for adding the fix. Seems to work fine for me.

However there is still a small issue. This might be a bit constructed but loss of focus can still occur.
This is what i did:

Run docksmaple
create two new documents (d1 and d2)
undock the first (d1)
then undock the second (d2) and dock it again
undock d2 again (now you should see d1 getting the focus)
now dock d2 again. do this by clicking on the top of the frame and directly drag it to the dock
this should cause the docksample program to lose focus to the last program that had it.

I think this happens because in the last step the Form dose not get the focus. Instead the FloatWindow containing the Forms (that is its FloatPane) has the focus. Thus if (Form.ContainsFocus) (in the DockContentHandle.SetParent function) returns false and the focus is not saved. I would propose changing it to if (Form.ContainsFocus || (IsFloat && FloatPane.FloatWindow.Focused)) . This should take care of this problem.
However it dose not seem like a real cure to me. The problem with the focus seems to arise from changing the Form.Parent and/or Form.MdiParent properties. This can causes a loss of focus even in standard Mdi applications. Which is why the whole DockContentHandle.SetParent function exists in the first place i guess?

Member

lextm commented Jun 18, 2013

If "this can causes a loss of focus even in standard Mdi applications", then I don't think there is much we can do in DPS (at this time, as we lack of resources to cover all).

We welcome patches from the user community.

@fxbit fxbit added a commit to fxbit/dockpanelsuite that referenced this issue Feb 14, 2014

@lextm @fxbit lextm + fxbit Added brackets to fix #71. 4f6d003

@lextm lextm modified the milestone: 2.10.0, 3.0.0 Jul 6, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment