* Added a method Desktop::_LastFocusSubsetWindow() which returns the last

window being the focus window that is a subset of the specified window.
* This is now used to bring the window to front belonging to a floating
  or modal window (if on another workspace), ie. Desktop::ActivateWindow()
  should now work with modal and floating windows.
* Fixed typo (in Window.cpp).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28649 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-11-14 13:37:27 +00:00
parent 55ddbd7bca
commit d02835660f
3 changed files with 47 additions and 25 deletions

View File

@ -1532,8 +1532,26 @@ Desktop::_BringWindowsToFront(WindowList& windows, int32 list,
} }
/*! /*! Returns the last focussed non-hidden subset window belonging to the
\brief Tries to move the specified window to the front of the screen, specified \a window.
*/
Window*
Desktop::_LastFocusSubsetWindow(Window* window)
{
if (window == NULL)
return NULL;
for (Window* front = fFocusList.LastWindow(); front != NULL;
front = front->PreviousWindow(kFocusList)) {
if (front != window && !front->IsHidden() && window->HasInSubset(front))
return front;
}
return NULL;
}
/*! \brief Tries to move the specified window to the front of the screen,
and make it the focus window. and make it the focus window.
If there are any modal windows on this screen, it might not actually If there are any modal windows on this screen, it might not actually
@ -1550,13 +1568,11 @@ Desktop::ActivateWindow(Window* window)
fFront = NULL; fFront = NULL;
return; return;
} }
if (window->Workspaces() == 0) if (window->Workspaces() == 0
&& !window->IsFloating() && !window->IsModal())
return; return;
// TODO: take care about floating windows AutoWriteLocker _(fWindowLock);
if (!LockAllWindows())
return;
bool windowOnOtherWorkspace = !window->InWorkspace(fCurrentWorkspace); bool windowOnOtherWorkspace = !window->InWorkspace(fCurrentWorkspace);
if (windowOnOtherWorkspace if (windowOnOtherWorkspace
@ -1573,18 +1589,27 @@ Desktop::ActivateWindow(Window* window)
break; break;
} }
} }
} else { } else
UnlockAllWindows();
return; return;
} }
}
if (windowOnOtherWorkspace) { if (windowOnOtherWorkspace) {
if (window->IsFloating() || window->IsModal()) {
// Bring a window to front that this floating window belongs to
Window* front = _LastFocusSubsetWindow(window);
if (front == NULL) {
// We can't do anything about those.
return;
}
ActivateWindow(front);
} else {
// Bring the window to the current workspace // Bring the window to the current workspace
// TODO: what if this window is on multiple workspaces?!? // TODO: what if this window is on multiple workspaces?!?
uint32 workspaces = workspace_to_workspaces(fCurrentWorkspace); uint32 workspaces = workspace_to_workspaces(fCurrentWorkspace);
SetWindowWorkspaces(window, workspaces); SetWindowWorkspaces(window, workspaces);
} }
}
if (window->IsMinimized()) { if (window->IsMinimized()) {
// Unlike WindowAction(), this is called from the application itself, // Unlike WindowAction(), this is called from the application itself,
@ -1602,11 +1627,10 @@ Desktop::ActivateWindow(Window* window)
} }
if (avoidsFront == NULL) { if (avoidsFront == NULL) {
// we're already the frontmost window, we might just not have focus yet // we're already the frontmost window, we might just not have focus
// yet
if ((window->Flags() & B_AVOID_FOCUS) == 0) if ((window->Flags() & B_AVOID_FOCUS) == 0)
SetFocusWindow(window); SetFocusWindow(window);
UnlockAllWindows();
return; return;
} }
} }
@ -1642,10 +1666,9 @@ Desktop::ActivateWindow(Window* window)
} }
_BringWindowsToFront(windows, kWorkingList, true); _BringWindowsToFront(windows, kWorkingList, true);
if ((window->Flags() & B_AVOID_FOCUS) == 0) if ((window->Flags() & B_AVOID_FOCUS) == 0)
SetFocusWindow(window); SetFocusWindow(window);
UnlockAllWindows();
} }
@ -1706,19 +1729,19 @@ Desktop::ShowWindow(Window* window)
if (!window->IsHidden()) if (!window->IsHidden())
return; return;
LockAllWindows(); AutoWriteLocker locker(fWindowLock);
window->SetHidden(false); window->SetHidden(false);
fFocusList.AddWindow(window); fFocusList.AddWindow(window);
if (window->InWorkspace(fCurrentWorkspace)) { if (window->InWorkspace(fCurrentWorkspace)
|| (window->IsFloating() && _LastFocusSubsetWindow(window) != NULL)) {
_ShowWindow(window, true); _ShowWindow(window, true);
_UpdateSubsetWorkspaces(window); _UpdateSubsetWorkspaces(window);
ActivateWindow(window); ActivateWindow(window);
} else { } else {
// then we don't need to send the fake mouse event either // then we don't need to send the fake mouse event either
_WindowChanged(window); _WindowChanged(window);
UnlockAllWindows();
return; return;
} }
@ -1728,8 +1751,6 @@ Desktop::ShowWindow(Window* window)
window->FindWorkspacesViews(fWorkspacesViews); window->FindWorkspacesViews(fWorkspacesViews);
} }
UnlockAllWindows();
// If the mouse cursor is directly over the newly visible window, // If the mouse cursor is directly over the newly visible window,
// we'll send a fake mouse moved message to the window, so that // we'll send a fake mouse moved message to the window, so that
// it knows the mouse is over it. // it knows the mouse is over it.

View File

@ -231,6 +231,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
uint32 oldWorkspaces, uint32 newWorkspaces); uint32 oldWorkspaces, uint32 newWorkspaces);
void _BringWindowsToFront(WindowList& windows, void _BringWindowsToFront(WindowList& windows,
int32 list, bool wereVisible); int32 list, bool wereVisible);
Window* _LastFocusSubsetWindow(Window* window);
status_t _ActivateApp(team_id team); status_t _ActivateApp(team_id team);
void _SendFakeMouseMoved(Window* window = NULL); void _SendFakeMouseMoved(Window* window = NULL);

View File

@ -1571,7 +1571,7 @@ Window::FindWorkspacesViews(BObjectList<WorkspacesView>& list) const
/*! \brief Returns on which workspaces the window should be visible. /*! \brief Returns on which workspaces the window should be visible.
A modal or floating window may be visible on a workscreen if one A modal or floating window may be visible on a workspace if one
of its subset windows is visible there. Floating windows also need of its subset windows is visible there. Floating windows also need
to have a subset as front window to be visible. to have a subset as front window to be visible.
*/ */