From 860dfc9a77381099c8c9549e28865ed015886bf7 Mon Sep 17 00:00:00 2001 From: Clemens Zeidler Date: Thu, 29 Jul 2010 02:10:29 +0000 Subject: [PATCH] - Introduce a DesktopListener interface to the Desktop class (needed for SAT). - Add a minimize method to desktop. - Make _CurrentWindows public. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37800 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/Desktop.cpp | 110 +++++++++--- src/servers/app/Desktop.h | 10 +- src/servers/app/DesktopListener.cpp | 267 ++++++++++++++++++++++++++++ src/servers/app/DesktopListener.h | 113 ++++++++++++ src/servers/app/Jamfile | 1 + src/servers/app/ServerWindow.cpp | 13 +- 6 files changed, 477 insertions(+), 37 deletions(-) create mode 100644 src/servers/app/DesktopListener.cpp create mode 100644 src/servers/app/DesktopListener.h diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 9823a38939..de68bfd0bb 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -155,11 +155,12 @@ KeyboardFilter::Filter(BMessage* message, EventTarget** _target, int32* /*_viewToken*/, BMessage* /*latestMouseMoved*/) { int32 key = 0; - int32 modifiers; + int32 modifiers = 0; - if ((message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN) - && message->FindInt32("key", &key) == B_OK - && message->FindInt32("modifiers", &modifiers) == B_OK) { + message->FindInt32("key", &key); + message->FindInt32("modifiers", &modifiers); + + if ((message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN)) { // Check for safe video mode (cmd + ctrl + escape) if (key == 0x01 && (modifiers & B_COMMAND_KEY) != 0 && (modifiers & B_CONTROL_KEY) != 0) { @@ -198,6 +199,8 @@ KeyboardFilter::Filter(BMessage* message, EventTarget** _target, || message->what == B_INPUT_METHOD_EVENT) _UpdateFocus(key, modifiers, _target); + fDesktop->KeyEvent(message->what, key, modifiers); + return B_DISPATCH_MESSAGE; } @@ -246,18 +249,21 @@ MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken, switch (message->what) { case B_MOUSE_DOWN: window->MouseDown(message, where, &viewToken); + fDesktop->InvokeMouseDown(window, message, where); break; case B_MOUSE_UP: window->MouseUp(message, where, &viewToken); if (buttons == 0) fDesktop->SetMouseEventWindow(NULL); + fDesktop->InvokeMouseUp(window, message, where); break; case B_MOUSE_MOVED: window->MouseMoved(message, where, &viewToken, latestMouseMoved == NULL || latestMouseMoved == message, false); + fDesktop->InvokeMouseMoved(window, message, where); break; } @@ -279,6 +285,8 @@ MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken, fDesktop->SetLastMouseState(where, buttons, window); + fDesktop->InvokeMouseEvent(message); + fDesktop->UnlockAllWindows(); return B_DISPATCH_MESSAGE; @@ -466,6 +474,13 @@ Desktop::BroadcastToAllWindows(int32 code) } +void +Desktop::KeyEvent(uint32 what, int32 key, int32 modifiers) +{ + InvokeKeyEvent(what, key, modifiers); +} + + // #pragma mark - Mouse and cursor methods @@ -891,6 +906,8 @@ Desktop::ActivateWindow(Window* window) AutoWriteLocker _(fWindowLock); + InvokeActivateWindow(window); + bool windowOnOtherWorkspace = !window->InWorkspace(fCurrentWorkspace); if (windowOnOtherWorkspace && (window->Flags() & B_NOT_ANCHORED_ON_ACTIVATE) == 0) { @@ -964,7 +981,7 @@ Desktop::ActivateWindow(Window* window) Window* frontmost = window->Frontmost(); - _CurrentWindows().RemoveWindow(window); + CurrentWindows().RemoveWindow(window); windows.AddWindow(window); if (frontmost != NULL && frontmost->IsModal()) { @@ -982,7 +999,7 @@ Desktop::ActivateWindow(Window* window) if (nextModal != NULL && !nextModal->HasInSubset(window)) nextModal = NULL; - _CurrentWindows().RemoveWindow(modal); + CurrentWindows().RemoveWindow(modal); windows.AddWindow(modal); } } @@ -1016,8 +1033,8 @@ Desktop::SendWindowBehind(Window* window, Window* behindOf) // detach window and re-attach at desired position Window* backmost = window->Backmost(behindOf); - _CurrentWindows().RemoveWindow(window); - _CurrentWindows().AddWindow(window, backmost + CurrentWindows().RemoveWindow(window); + CurrentWindows().AddWindow(window, backmost ? backmost->NextWindow(fCurrentWorkspace) : BackWindow()); BRegion dummy; @@ -1040,6 +1057,8 @@ Desktop::SendWindowBehind(Window* window, Window* behindOf) _WindowChanged(window); + InvokeSendWindowBehind(window, behindOf); + UnlockAllWindows(); if (sendFakeMouseMoved) @@ -1083,6 +1102,8 @@ Desktop::ShowWindow(Window* window) // it knows the mouse is over it. _SendFakeMouseMoved(window); + + InvokeShowWindow(window); } @@ -1136,6 +1157,8 @@ Desktop::HideWindow(Window* window) } } + InvokeHideWindow(window); + UnlockAllWindows(); if (window == fWindowUnderMouse) @@ -1143,6 +1166,26 @@ Desktop::HideWindow(Window* window) } +void +Desktop::MinimizeWindow(Window* window, bool minimize) +{ + if (!LockAllWindows()) + return; + + if (minimize && !window->IsHidden()) { + HideWindow(window); + window->SetMinimized(minimize); + InvokeMinimizeWindow(window, minimize); + } else if (!minimize && window->IsHidden()) { + ActivateWindow(window); + // this will unminimize the window for us + InvokeMinimizeWindow(window, minimize); + } + + UnlockAllWindows(); +} + + void Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace) { @@ -1154,7 +1197,6 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace) if (workspace == -1) workspace = fCurrentWorkspace; - if (!window->IsVisible() || workspace != fCurrentWorkspace) { if (workspace != fCurrentWorkspace) { // move the window on another workspace - this doesn't change it's @@ -1163,10 +1205,12 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace) window->Anchor(workspace).position = window->Frame().LeftTop(); window->Anchor(workspace).position += BPoint(x, y); + window->SetCurrentWorkspace(workspace); _WindowChanged(window); } else window->MoveBy((int32)x, (int32)y); + InvokeMoveWindow(window); UnlockAllWindows(); return; } @@ -1221,6 +1265,8 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace) B_DIRECT_START | B_BUFFER_MOVED | B_CLIPPING_MODIFIED); } + InvokeMoveWindow(window); + UnlockAllWindows(); } @@ -1236,6 +1282,7 @@ Desktop::ResizeWindowBy(Window* window, float x, float y) if (!window->IsVisible()) { window->ResizeBy((int32)x, (int32)y, NULL); + InvokeResizeWindow(window); UnlockAllWindows(); return; } @@ -1278,6 +1325,8 @@ Desktop::ResizeWindowBy(Window* window, float x, float y) B_DIRECT_START | B_BUFFER_RESIZED | B_CLIPPING_MODIFIED); } + InvokeResizeWindow(window); + UnlockAllWindows(); } @@ -1303,7 +1352,8 @@ Desktop::SetWindowDecoratorSettings(Window* window, const BMessage& settings) BRegion dirty; bool changed = window->SetDecoratorSettings(settings, dirty); - if (changed) + bool listenerChanged = InvokeSetDecoratorSettings(window, settings); + if (changed || listenerChanged) _RebuildAndRedrawAfterWindowChange(window, dirty); return changed; @@ -1349,6 +1399,9 @@ Desktop::AddWindow(Window *window) } _ChangeWindowWorkspaces(window, 0, window->Workspaces()); + + InvokeAddWindow(window); + UnlockAllWindows(); } @@ -1366,6 +1419,9 @@ Desktop::RemoveWindow(Window *window) fSubsetWindows.RemoveWindow(window); _ChangeWindowWorkspaces(window, window->Workspaces(), 0); + + InvokeRemoveWindow(window); + UnlockAllWindows(); // make sure this window won't get any events anymore @@ -1560,7 +1616,7 @@ Desktop::SetWindowTitle(Window *window, const char* title) Window* Desktop::WindowAt(BPoint where) { - for (Window* window = _CurrentWindows().LastWindow(); window; + for (Window* window = CurrentWindows().LastWindow(); window; window = window->PreviousWindow(fCurrentWorkspace)) { if (window->IsVisible() && window->VisibleRegion().Contains(where)) return window; @@ -1604,7 +1660,7 @@ EventTarget* Desktop::KeyboardEventTarget() { // Get the top most non-hidden window - Window* window = _CurrentWindows().LastWindow(); + Window* window = CurrentWindows().LastWindow(); while (window != NULL && window->IsHidden()) { window = window->PreviousWindow(fCurrentWorkspace); } @@ -1671,7 +1727,7 @@ Desktop::SetFocusWindow(Window* focus) if (focus == NULL || hasModal || hasWindowScreen) { if (!fSettings->FocusFollowsMouse()) - focus = _CurrentWindows().LastWindow(); + focus = CurrentWindows().LastWindow(); else focus = fFocusList.LastWindow(); } @@ -1811,7 +1867,7 @@ Desktop::RedrawBackground() BRegion redraw; - Window* window = _CurrentWindows().FirstWindow(); + Window* window = CurrentWindows().FirstWindow(); if (window->Feel() == kDesktopWindowFeel) { redraw = window->VisibleContentRegion(); @@ -1928,7 +1984,7 @@ Desktop::WriteWindowList(team_id team, BPrivate::LinkSender& sender) sender.Attach(count); // first write the windows of the current workspace correctly ordered - for (Window *window = _CurrentWindows().LastWindow(); window != NULL; + for (Window *window = CurrentWindows().LastWindow(); window != NULL; window = window->PreviousWindow(fCurrentWorkspace)) { if (team >= B_OK && window->ServerWindow()->ClientTeam() != team) continue; @@ -1972,6 +2028,7 @@ Desktop::WriteWindowInfo(int32 serverToken, BPrivate::LinkSender& sender) ::Window* tmp = window->Window(); if (tmp) { BMessage message; + InvokeGetDecoratorSettings(tmp, message); if (tmp->GetDecoratorSettings(&message)) { BRect tabFrame; message.FindRect("tab frame", &tabFrame); @@ -2363,7 +2420,7 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) WindowList& -Desktop::_CurrentWindows() +Desktop::CurrentWindows() { return fWorkspaces[fCurrentWorkspace].Windows(); } @@ -2438,7 +2495,7 @@ Desktop::_UpdateBack() { fBack = NULL; - for (Window* window = _CurrentWindows().FirstWindow(); window != NULL; + for (Window* window = CurrentWindows().FirstWindow(); window != NULL; window = window->NextWindow(fCurrentWorkspace)) { if (window->IsHidden() || window->Feel() == kDesktopWindowFeel) continue; @@ -2461,7 +2518,7 @@ Desktop::_UpdateFront(bool updateFloating) { fFront = NULL; - for (Window* window = _CurrentWindows().LastWindow(); window != NULL; + for (Window* window = CurrentWindows().LastWindow(); window != NULL; window = window->PreviousWindow(fCurrentWorkspace)) { if (window->IsHidden() || window->IsFloating() || !window->SupportsFront()) @@ -2705,6 +2762,8 @@ Desktop::_ChangeWindowWorkspaces(Window* window, uint32 oldWorkspaces, // take care about modals and floating windows _UpdateSubsetWorkspaces(window); + InvokeSetWindowWorkspaces(window, newWorkspaces); + UnlockAllWindows(); } @@ -2722,8 +2781,8 @@ Desktop::_BringWindowsToFront(WindowList& windows, int32 list, if (wereVisible) clean.Include(&window->VisibleRegion()); - _CurrentWindows().AddWindow(window, - window->Frontmost(_CurrentWindows().FirstWindow(), + CurrentWindows().AddWindow(window, + window->Frontmost(CurrentWindows().FirstWindow(), fCurrentWorkspace)); _WindowChanged(window); @@ -2832,7 +2891,7 @@ Desktop::_RebuildClippingForAllWindows(BRegion& stillAvailableOnScreen) stillAvailableOnScreen = fScreenRegion; // set clipping of each window - for (Window* window = _CurrentWindows().LastWindow(); window != NULL; + for (Window* window = CurrentWindows().LastWindow(); window != NULL; window = window->PreviousWindow(fCurrentWorkspace)) { if (!window->IsHidden()) { window->SetClipping(&stillAvailableOnScreen); @@ -2854,7 +2913,7 @@ void Desktop::_TriggerWindowRedrawing(BRegion& newDirtyRegion) { // send redraw messages to all windows intersecting the dirty region - for (Window* window = _CurrentWindows().LastWindow(); window != NULL; + for (Window* window = CurrentWindows().LastWindow(); window != NULL; window = window->PreviousWindow(fCurrentWorkspace)) { if (!window->IsHidden() && newDirtyRegion.Intersects(window->VisibleRegion().Frame())) @@ -2904,7 +2963,7 @@ Desktop::_RebuildAndRedrawAfterWindowChange(Window* changedWindow, BRegion stillAvailableOnScreen(fScreenRegion); // set clipping of each window - for (Window* window = _CurrentWindows().LastWindow(); window != NULL; + for (Window* window = CurrentWindows().LastWindow(); window != NULL; window = window->PreviousWindow(fCurrentWorkspace)) { if (!window->IsHidden()) { if (window == changedWindow) @@ -3012,7 +3071,7 @@ Desktop::_ActivateApp(team_id team) AutoWriteLocker locker(fWindowLock); - for (Window* window = _CurrentWindows().LastWindow(); window != NULL; + for (Window* window = CurrentWindows().LastWindow(); window != NULL; window = window->PreviousWindow(fCurrentWorkspace)) { if (!window->IsHidden() && window->IsNormal() && window->ServerWindow()->ClientTeam() == team) { @@ -3108,6 +3167,7 @@ Desktop::_SetWorkspace(int32 index, bool moveFocusWindow) // send B_WORKSPACES_CHANGED message movedWindow->WorkspacesChanged(oldWorkspaces, movedWindow->Workspaces()); + InvokeSetWindowWorkspaces(movedWindow, movedWindow->Workspaces()); } else { // make sure it's frontmost _Windows(index).RemoveWindow(movedWindow); @@ -3129,7 +3189,7 @@ Desktop::_SetWorkspace(int32 index, bool moveFocusWindow) BRegion dirty; - for (Window* window = _CurrentWindows().FirstWindow(); + for (Window* window = CurrentWindows().FirstWindow(); window != NULL; window = window->NextWindow(previousIndex)) { // store current position in Workspace anchor window->Anchor(previousIndex).position = window->Frame().LeftTop(); diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index 10a000e7a2..ea40b84c76 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -14,6 +14,7 @@ #include "CursorManager.h" +#include "DesktopListener.h" #include "DesktopSettings.h" #include "EventDispatcher.h" #include "MessageLooper.h" @@ -58,7 +59,8 @@ namespace BPrivate { }; -class Desktop : public MessageLooper, public ScreenOwner { +class Desktop : public DesktopObservable, public MessageLooper, + public ScreenOwner { public: Desktop(uid_t userID, const char* targetScreen); virtual ~Desktop(); @@ -76,6 +78,8 @@ public: void BroadcastToAllApps(int32 code); void BroadcastToAllWindows(int32 code); + void KeyEvent(uint32 what, int32 key, + int32 modifiers); // Locking #if USE_MULTI_LOCKER bool LockSingleWindow() @@ -171,6 +175,7 @@ public: void ShowWindow(Window* window); void HideWindow(Window* window); + void MinimizeWindow(Window* window, bool minimize); void MoveWindowBy(Window* window, float x, float y, int32 workspace = -1); @@ -243,6 +248,8 @@ public: void WriteWindowOrder(int32 workspace, BPrivate::LinkSender& sender); + WindowList& CurrentWindows(); + private: void _LaunchInputServer(); void _GetLooperName(char* name, size_t size); @@ -250,7 +257,6 @@ private: void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); - WindowList& _CurrentWindows(); WindowList& _Windows(int32 index); void _UpdateFloating(int32 previousWorkspace = -1, diff --git a/src/servers/app/DesktopListener.cpp b/src/servers/app/DesktopListener.cpp new file mode 100644 index 0000000000..d40f5d91d1 --- /dev/null +++ b/src/servers/app/DesktopListener.cpp @@ -0,0 +1,267 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler + */ + +#include "DesktopListener.h" + + +DesktopListener::~DesktopListener() +{ + +} + + +DesktopObservable::DesktopObservable() + : + fWeAreInvoking(false) +{ + +} + + +void +DesktopObservable::RegisterListener(DesktopListener* listener) +{ + fDesktopListenerList.Add(listener); +} + + +void +DesktopObservable::UnregisterListener(DesktopListener* listener) +{ + fDesktopListenerList.Remove(listener); +} + + +#define FOR_ALL_DESKTOP_LISTENER \ + for (DesktopListener* listener = fDesktopListenerList.First(); \ + listener != NULL; listener = fDesktopListenerList.GetNext(listener)) + + +void +DesktopObservable::InvokeAddWindow(Window* window) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->AddWindow(window); +} + + +void +DesktopObservable::InvokeRemoveWindow(Window* window) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->RemoveWindow(window); +} + + +void +DesktopObservable::InvokeKeyEvent(uint32 what, int32 key, int32 modifiers) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->KeyEvent(what, key, modifiers); +} + + +void +DesktopObservable::InvokeMouseEvent(BMessage* message) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->MouseEvent(message); +} + + +void +DesktopObservable::InvokeMouseDown(Window* window, BMessage* message, + const BPoint& where) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->MouseDown(window, message, where); +} + + +void +DesktopObservable::InvokeMouseUp(Window* window, BMessage* message, + const BPoint& where) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->MouseUp(window, message, where); +} + + +void +DesktopObservable::InvokeMouseMoved(Window* window, BMessage* message, + const BPoint& where) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->MouseMoved(window, message, where); +} + + +void +DesktopObservable::InvokeMoveWindow(Window* window) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->MoveWindow(window); +} + + +void +DesktopObservable::InvokeResizeWindow(Window* window) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->ResizeWindow(window); +} + + +void +DesktopObservable::InvokeActivateWindow(Window* window) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->ActivateWindow(window); +} + + +void +DesktopObservable::InvokeSendWindowBehind(Window* window, Window* behindOf) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->SendWindowBehind(window, behindOf); +} + + +bool +DesktopObservable::InvokeSetDecoratorSettings(Window* window, + const BMessage& settings) +{ + if (fWeAreInvoking) + return false; + InvokeGuard invokeGuard(fWeAreInvoking); + + bool changed = false; + FOR_ALL_DESKTOP_LISTENER + changed = changed | listener->SetDecoratorSettings(window, settings); + + return changed; +} + + +void +DesktopObservable::InvokeGetDecoratorSettings(Window* window, BMessage& settings) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->GetDecoratorSettings(window, settings); +} + + +void +DesktopObservable::InvokeSetWindowWorkspaces(Window* window, uint32 workspaces) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->SetWindowWorkspaces(window, workspaces); +} + + +void +DesktopObservable::InvokeShowWindow(Window* window) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->ShowWindow(window); +} + + +void +DesktopObservable::InvokeHideWindow(Window* window) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->HideWindow(window); +} + + +void +DesktopObservable::InvokeMinimizeWindow(Window* window, bool minimize) +{ + if (fWeAreInvoking) + return; + InvokeGuard invokeGuard(fWeAreInvoking); + + FOR_ALL_DESKTOP_LISTENER + listener->MinimizeWindow(window, minimize); +} + + +DesktopObservable::InvokeGuard::InvokeGuard(bool& invoking) + : + fInvoking(invoking) +{ + fInvoking = true; +} + + +DesktopObservable::InvokeGuard::~InvokeGuard() +{ + fInvoking = false; +} diff --git a/src/servers/app/DesktopListener.h b/src/servers/app/DesktopListener.h new file mode 100644 index 0000000000..dafc18f92f --- /dev/null +++ b/src/servers/app/DesktopListener.h @@ -0,0 +1,113 @@ +/* + * Copyright 2010, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Clemens Zeidler + */ + +#ifndef DESKTOP_LISTENER_H +#define DESKTOP_LISTENER_H + +#include + +#include + + +class BMessage; +class Window; + + +class DesktopListener : public DoublyLinkedListLinkImpl +{ + public: + virtual ~DesktopListener(); + + virtual void AddWindow(Window* window) = 0; + virtual void RemoveWindow(Window* window) = 0; + + virtual void KeyEvent(uint32 what, int32 key, + int32 modifiers) = 0; + virtual void MouseEvent(BMessage* message) = 0; + virtual void MouseDown(Window* window, BMessage* message, + const BPoint& where) = 0; + virtual void MouseUp(Window* window, BMessage* message, + const BPoint& where) = 0; + virtual void MouseMoved(Window* window, BMessage* message, + const BPoint& where) = 0; + + virtual void MoveWindow(Window* window) = 0; + virtual void ResizeWindow(Window* window) = 0; + virtual void ActivateWindow(Window* window) = 0; + virtual void SendWindowBehind(Window* window, + Window* behindOf) = 0; + virtual void SetWindowWorkspaces(Window* window, + uint32 workspaces) = 0; + virtual void ShowWindow(Window* window) = 0; + virtual void HideWindow(Window* window) = 0; + virtual void MinimizeWindow(Window* window, + bool minimize) = 0; + + virtual bool SetDecoratorSettings(Window* window, + const BMessage& settings) = 0; + virtual void GetDecoratorSettings(Window* window, + BMessage& settings) = 0; +}; + + +typedef DoublyLinkedList DesktopListenerList; + + +class DesktopObservable +{ + public: + DesktopObservable(); + + void RegisterListener(DesktopListener* listener); + void UnregisterListener(DesktopListener* listener); + + void InvokeAddWindow(Window* window); + void InvokeRemoveWindow(Window* window); + + void InvokeKeyEvent(uint32 what, int32 key, + int32 modifiers); + void InvokeMouseEvent(BMessage* message); + void InvokeMouseDown(Window* window, BMessage* message, + const BPoint& where); + void InvokeMouseUp(Window* window, BMessage* message, + const BPoint& where); + void InvokeMouseMoved(Window* window, BMessage* message, + const BPoint& where); + + void InvokeMoveWindow(Window* window); + void InvokeResizeWindow(Window* window); + void InvokeActivateWindow(Window* window); + void InvokeSendWindowBehind(Window* window, + Window* behindOf); + void InvokeSetWindowWorkspaces(Window* window, + uint32 workspaces); + void InvokeShowWindow(Window* window); + void InvokeHideWindow(Window* window); + void InvokeMinimizeWindow(Window* window, bool minimize); + + bool InvokeSetDecoratorSettings(Window* window, + const BMessage& settings); + void InvokeGetDecoratorSettings(Window* window, + BMessage& settings); + + private: + class InvokeGuard{ + public: + InvokeGuard(bool& invoking); + ~InvokeGuard(); + private: + bool& fInvoking; + }; + + DesktopListenerList fDesktopListenerList; + + // prevent recursive invokes + bool fWeAreInvoking; +}; + +#endif diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 70d174946a..e7d1963085 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -23,6 +23,7 @@ Server app_server : DefaultDecorator.cpp DefaultWindowBehaviour.cpp Desktop.cpp + DesktopListener.cpp DesktopSettings.cpp DirectWindowInfo.cpp DrawState.cpp diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 5cbe655972..cb1f0a8e00 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -625,16 +625,9 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) break; } - if (minimize && !fWindow->IsHidden()) { - _Hide(); - fWindow->SetMinimized(minimize); - } else if (!minimize && fWindow->IsHidden()) { - fDesktop->UnlockSingleWindow(); - fDesktop->ActivateWindow(fWindow); - // this will unminimize the window for us - fDesktop->LockSingleWindow(); - } - + fDesktop->UnlockSingleWindow(); + fDesktop->MinimizeWindow(fWindow, minimize); + fDesktop->LockSingleWindow(); } break; }