[haiku-commits] Re: r37800 - haiku/trunk/src/servers/app

  • From: "Clemens Zeidler" <clemens.zeidler@xxxxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 29 Jul 2010 14:33:09 +1200

Hi,

the idea for SAT is to put everything into a Decorator add-on, in this way SAT can be enabled by just switching the decorator add-on and no code have to be added to the app server. At the moment SAT needs a special decorator, e.g. to highlight border and tabs. Additional SAT needs to know a lot about whats happening in the app server. Therefore the DesktopListener interface should be used. I like to extent the decorator add-on in such a way that it is possible to load the decorator to draw the actually decorator, register one or more DesktopListener and later also a WindowBehaviour class.

As a next step I like to rework the DecorManager to manage all this stuff.

Any objections, suggestions?

Cheers,
        Clemens


Am 29.07.2010, 14:10 Uhr, schrieb <clemens.zeidler@xxxxxxxxxxxxxx>:

Author: czeidler
Date: 2010-07-29 04:10:29 +0200 (Thu, 29 Jul 2010)
New Revision: 37800
Changeset: http://dev.haiku-os.org/changeset/37800

Added:
   haiku/trunk/src/servers/app/DesktopListener.cpp
   haiku/trunk/src/servers/app/DesktopListener.h
Modified:
   haiku/trunk/src/servers/app/Desktop.cpp
   haiku/trunk/src/servers/app/Desktop.h
   haiku/trunk/src/servers/app/Jamfile
   haiku/trunk/src/servers/app/ServerWindow.cpp
Log:
- Introduce a DesktopListener interface to the Desktop class (needed for SAT).
- Add a minimize method to desktop.
- Make _CurrentWindows public.



Modified: haiku/trunk/src/servers/app/Desktop.cpp
===================================================================
--- haiku/trunk/src/servers/app/Desktop.cpp 2010-07-29 00:25:12 UTC (rev 37799) +++ haiku/trunk/src/servers/app/Desktop.cpp 2010-07-29 02:10:29 UTC (rev 37800)
@@ -155,11 +155,12 @@
        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 @@
                || message->what == B_INPUT_METHOD_EVENT)
                _UpdateFocus(key, modifiers, _target);
+       fDesktop->KeyEvent(message->what, key, modifiers);
+
        return B_DISPATCH_MESSAGE;
 }
@@ -246,18 +249,21 @@
                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 @@
        fDesktop->SetLastMouseState(where, buttons, window);
+       fDesktop->InvokeMouseEvent(message);
+
        fDesktop->UnlockAllWindows();
        return B_DISPATCH_MESSAGE;
@@ -466,6 +474,13 @@
 }
+void
+Desktop::KeyEvent(uint32 what, int32 key, int32 modifiers)
+{
+       InvokeKeyEvent(what, key, modifiers);
+}
+
+
 // #pragma mark - Mouse and cursor methods
@@ -891,6 +906,8 @@
        AutoWriteLocker _(fWindowLock);
+       InvokeActivateWindow(window);
+
        bool windowOnOtherWorkspace = !window->InWorkspace(fCurrentWorkspace);
        if (windowOnOtherWorkspace
                && (window->Flags() & B_NOT_ANCHORED_ON_ACTIVATE) == 0) {
@@ -964,7 +981,7 @@
        Window* frontmost = window->Frontmost();
-       _CurrentWindows().RemoveWindow(window);
+       CurrentWindows().RemoveWindow(window);
        windows.AddWindow(window);
        if (frontmost != NULL && frontmost->IsModal()) {
@@ -982,7 +999,7 @@
                        if (nextModal != NULL && 
!nextModal->HasInSubset(window))
                                nextModal = NULL;
-                       _CurrentWindows().RemoveWindow(modal);
+                       CurrentWindows().RemoveWindow(modal);
                        windows.AddWindow(modal);
                }
        }
@@ -1016,8 +1033,8 @@
        // 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 @@
        _WindowChanged(window);
+       InvokeSendWindowBehind(window, behindOf);
+
        UnlockAllWindows();
        if (sendFakeMouseMoved)
@@ -1083,6 +1102,8 @@
        // it knows the mouse is over it.
        _SendFakeMouseMoved(window);
+
+       InvokeShowWindow(window);
 }
@@ -1136,6 +1157,8 @@
                }
        }
+       InvokeHideWindow(window);
+
        UnlockAllWindows();
        if (window == fWindowUnderMouse)
@@ -1144,6 +1167,26 @@
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)
 {
        if (x == 0 && y == 0)
@@ -1154,7 +1197,6 @@
        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 @@
                                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 @@
                        B_DIRECT_START | B_BUFFER_MOVED | B_CLIPPING_MODIFIED);
        }
+       InvokeMoveWindow(window);
+
        UnlockAllWindows();
 }
@@ -1236,6 +1282,7 @@
        if (!window->IsVisible()) {
                window->ResizeBy((int32)x, (int32)y, NULL);
+               InvokeResizeWindow(window);
                UnlockAllWindows();
                return;
        }
@@ -1278,6 +1325,8 @@
                        B_DIRECT_START | B_BUFFER_RESIZED | 
B_CLIPPING_MODIFIED);
        }
+       InvokeResizeWindow(window);
+
        UnlockAllWindows();
 }
@@ -1303,7 +1352,8 @@
        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 @@
        }
        _ChangeWindowWorkspaces(window, 0, window->Workspaces());
+       
+       InvokeAddWindow(window);
+
        UnlockAllWindows();
 }
@@ -1366,6 +1419,9 @@
                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 @@
 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 @@
 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 @@
        if (focus == NULL || hasModal || hasWindowScreen) {
                if (!fSettings->FocusFollowsMouse())
-                       focus = _CurrentWindows().LastWindow();
+                       focus = CurrentWindows().LastWindow();
                else
                        focus = fFocusList.LastWindow();
        }
@@ -1811,7 +1867,7 @@
        BRegion redraw;
-       Window* window = _CurrentWindows().FirstWindow();
+       Window* window = CurrentWindows().FirstWindow();
        if (window->Feel() == kDesktopWindowFeel) {
                redraw = window->VisibleContentRegion();
@@ -1928,7 +1984,7 @@
        sender.Attach<int32>(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 @@
        ::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 @@
WindowList&
-Desktop::_CurrentWindows()
+Desktop::CurrentWindows()
 {
        return fWorkspaces[fCurrentWorkspace].Windows();
 }
@@ -2438,7 +2495,7 @@
 {
        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 @@
 {
        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 @@
        // take care about modals and floating windows
        _UpdateSubsetWorkspaces(window);
+       InvokeSetWindowWorkspaces(window, newWorkspaces);
+
        UnlockAllWindows();
 }
@@ -2722,8 +2781,8 @@
                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 @@
        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 @@
 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 @@
        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 @@
        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 @@
                                // 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 @@
        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();

Modified: haiku/trunk/src/servers/app/Desktop.h
===================================================================
--- haiku/trunk/src/servers/app/Desktop.h 2010-07-29 00:25:12 UTC (rev 37799) +++ haiku/trunk/src/servers/app/Desktop.h 2010-07-29 02:10:29 UTC (rev 37800)
@@ -14,6 +14,7 @@
#include "CursorManager.h"
+#include "DesktopListener.h"
 #include "DesktopSettings.h"
 #include "EventDispatcher.h"
 #include "MessageLooper.h"
@@ -58,7 +59,8 @@
 };
-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 @@
                        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 @@
                        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 @@
                        void                            WriteWindowOrder(int32 
workspace,
                                                                        
BPrivate::LinkSender& sender);
+                       WindowList&                 CurrentWindows();
+
 private:
                        void                            _LaunchInputServer();
                        void                            _GetLooperName(char* 
name, size_t size);
@@ -250,7 +257,6 @@
                        void                            _DispatchMessage(int32 
code,
                                                                        
BPrivate::LinkReceiver &link);
-                       WindowList&                 _CurrentWindows();
                        WindowList&                 _Windows(int32 index);
                        void                            _UpdateFloating(int32 
previousWorkspace = -1,

Added: haiku/trunk/src/servers/app/DesktopListener.cpp
===================================================================
--- haiku/trunk/src/servers/app/DesktopListener.cpp (rev 0) +++ haiku/trunk/src/servers/app/DesktopListener.cpp 2010-07-29 02:10:29 UTC (rev 37800)
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2010, Haiku.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
+ */
+
+#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;
+}

Added: haiku/trunk/src/servers/app/DesktopListener.h
===================================================================
--- haiku/trunk/src/servers/app/DesktopListener.h (rev 0) +++ haiku/trunk/src/servers/app/DesktopListener.h 2010-07-29 02:10:29 UTC (rev 37800)
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2010, Haiku.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
+ */
+
+#ifndef DESKTOP_LISTENER_H
+#define DESKTOP_LISTENER_H
+
+#include <util/DoublyLinkedList.h>
+
+#include <Point.h>
+
+
+class BMessage;
+class Window;
+
+
+class DesktopListener : public DoublyLinkedListLinkImpl<DesktopListener>
+{
+       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<DesktopListener> 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

Modified: haiku/trunk/src/servers/app/Jamfile
===================================================================
--- haiku/trunk/src/servers/app/Jamfile 2010-07-29 00:25:12 UTC (rev 37799) +++ haiku/trunk/src/servers/app/Jamfile 2010-07-29 02:10:29 UTC (rev 37800)
@@ -23,6 +23,7 @@
        DefaultDecorator.cpp
        DefaultWindowBehaviour.cpp
        Desktop.cpp
+       DesktopListener.cpp
        DesktopSettings.cpp
        DirectWindowInfo.cpp
        DrawState.cpp

Modified: haiku/trunk/src/servers/app/ServerWindow.cpp
===================================================================
--- haiku/trunk/src/servers/app/ServerWindow.cpp 2010-07-29 00:25:12 UTC (rev 37799) +++ haiku/trunk/src/servers/app/ServerWindow.cpp 2010-07-29 02:10:29 UTC (rev 37800)
@@ -625,16 +625,9 @@
                                        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;
                }


Other related posts: