Author: czeidler Date: 2010-12-07 00:15:15 +0100 (Tue, 07 Dec 2010) New Revision: 39751 Changeset: http://dev.haiku-os.org/changeset/39751 Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.cpp haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.h haiku/trunk/src/servers/app/Desktop.cpp haiku/trunk/src/servers/app/Desktop.h haiku/trunk/src/servers/app/DesktopListener.cpp haiku/trunk/src/servers/app/DesktopListener.h Log: - Give the option for the desktop listener to "absorb" key events. - Make the S&T groups navigateable by pressing the S&T key + arrow down/up. Arrow down means to send the active S&T group to the bottom. Arrow up means to rise the bottom S&T group to the front. If no S&T group is selected, in both cases the front-most S&T group is activated. Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.cpp =================================================================== --- haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.cpp 2010-12-06 19:31:11 UTC (rev 39750) +++ haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.cpp 2010-12-06 23:15:15 UTC (rev 39751) @@ -113,7 +113,7 @@ } -void +bool StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers) { // switch to and from stacking and snapping mode @@ -126,7 +126,83 @@ _StartSAT(); } - return; + if (!SATKeyPressed() || what != B_KEY_DOWN) + return false; + + const int kArrowKeyUp = 87; + const int kArrowKeyDown = 98; + + switch (key) { + case kArrowKeyDown: + { + SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); + SATGroup* currentGroup = NULL; + if (frontWindow) + currentGroup = frontWindow->GetGroup(); + if (currentGroup && currentGroup->CountItems() <= 1) + currentGroup = NULL; + + GroupIterator groups(this, fDesktop); + bool currentFound = false; + while (true) { + SATGroup* group = groups.NextGroup(); + if (group == NULL) + break; + if (group->CountItems() <= 1) + continue; + + if (currentGroup == NULL) + currentFound = true; + // if no group is selected just activate the first one + else if (currentGroup == group) { + currentFound = true; + continue; + } + if (currentFound) { + _ActivateWindow(group->WindowAt(0)); + if (currentGroup) { + Window* window = currentGroup->WindowAt(0)->GetWindow(); + fDesktop->SendWindowBehind(window); + WindowSentBehind(window, NULL); + } + return true; + } + } + break; + } + + case kArrowKeyUp: + { + SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); + SATGroup* currentGroup = NULL; + if (frontWindow) + currentGroup = frontWindow->GetGroup(); + if (currentGroup && currentGroup->CountItems() <= 1) + currentGroup = NULL; + + SATGroup* backmostGroup = NULL; + GroupIterator groups(this, fDesktop); + while (true) { + SATGroup* group = groups.NextGroup(); + if (group == NULL) + break; + if (group->CountItems() <= 1) + continue; + // if no group is selected just activate the first one + if (currentGroup == NULL) { + _ActivateWindow(group->WindowAt(0)); + return true; + } + backmostGroup = group; + } + if (backmostGroup && backmostGroup != currentGroup) { + _ActivateWindow(backmostGroup->WindowAt(0)); + return true; + } + break; + } + } + return false; } @@ -369,6 +445,9 @@ SATWindow* StackAndTile::GetSATWindow(Window* window) { + if (window == NULL) + return NULL; + SATWindowMap::const_iterator it = fSATWindowMap.find( window); if (it != fSATWindowMap.end()) Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.h =================================================================== --- haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.h 2010-12-06 19:31:11 UTC (rev 39750) +++ haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.h 2010-12-06 23:15:15 UTC (rev 39751) @@ -54,7 +54,7 @@ virtual void WindowAdded(Window* window); virtual void WindowRemoved(Window* window); - virtual void KeyPressed(uint32 what, int32 key, + virtual bool KeyPressed(uint32 what, int32 key, int32 modifiers); virtual void MouseEvent(BMessage* message) {} virtual void MouseDown(Window* window, BMessage* message, Modified: haiku/trunk/src/servers/app/Desktop.cpp =================================================================== --- haiku/trunk/src/servers/app/Desktop.cpp 2010-12-06 19:31:11 UTC (rev 39750) +++ haiku/trunk/src/servers/app/Desktop.cpp 2010-12-06 23:15:15 UTC (rev 39751) @@ -221,9 +221,7 @@ || message->what == B_INPUT_METHOD_EVENT) _UpdateFocus(key, modifiers, _target); - fDesktop->KeyEvent(message->what, key, modifiers); - - return B_DISPATCH_MESSAGE; + return fDesktop->KeyEvent(message->what, key, modifiers); } @@ -578,7 +576,7 @@ } -void +filter_result Desktop::KeyEvent(uint32 what, int32 key, int32 modifiers) { if (LockAllWindows()) { @@ -594,7 +592,10 @@ UnlockAllWindows(); } - NotifyKeyPressed(what, key, modifiers); + if (NotifyKeyPressed(what, key, modifiers)) + return B_SKIP_MESSAGE; + + return B_DISPATCH_MESSAGE; } Modified: haiku/trunk/src/servers/app/Desktop.h =================================================================== --- haiku/trunk/src/servers/app/Desktop.h 2010-12-06 19:31:11 UTC (rev 39750) +++ haiku/trunk/src/servers/app/Desktop.h 2010-12-06 23:15:15 UTC (rev 39751) @@ -72,7 +72,7 @@ void BroadcastToAllApps(int32 code); void BroadcastToAllWindows(int32 code); - void KeyEvent(uint32 what, int32 key, + filter_result KeyEvent(uint32 what, int32 key, int32 modifiers); // Locking bool LockSingleWindow() Modified: haiku/trunk/src/servers/app/DesktopListener.cpp =================================================================== --- haiku/trunk/src/servers/app/DesktopListener.cpp 2010-12-06 19:31:11 UTC (rev 39750) +++ haiku/trunk/src/servers/app/DesktopListener.cpp 2010-12-06 23:15:15 UTC (rev 39751) @@ -91,16 +91,20 @@ } -void +bool DesktopObservable::NotifyKeyPressed(uint32 what, int32 key, int32 modifiers) { if (fWeAreInvoking) - return; + return false; InvokeGuard invokeGuard(fWeAreInvoking); + bool skipEvent = false; for (DesktopListener* listener = fDesktopListenerList.First(); - listener != NULL; listener = fDesktopListenerList.GetNext(listener)) - listener->KeyPressed(what, key, modifiers); + listener != NULL; listener = fDesktopListenerList.GetNext(listener)) { + if (listener->KeyPressed(what, key, modifiers)) + skipEvent = true; + } + return skipEvent; } Modified: haiku/trunk/src/servers/app/DesktopListener.h =================================================================== --- haiku/trunk/src/servers/app/DesktopListener.h 2010-12-06 19:31:11 UTC (rev 39750) +++ haiku/trunk/src/servers/app/DesktopListener.h 2010-12-06 23:15:15 UTC (rev 39751) @@ -38,7 +38,7 @@ virtual void WindowAdded(Window* window) = 0; virtual void WindowRemoved(Window* window) = 0; - virtual void KeyPressed(uint32 what, int32 key, + virtual bool KeyPressed(uint32 what, int32 key, int32 modifiers) = 0; virtual void MouseEvent(BMessage* message) = 0; virtual void MouseDown(Window* window, BMessage* message, @@ -92,7 +92,7 @@ void NotifyWindowAdded(Window* window); void NotifyWindowRemoved(Window* window); - void NotifyKeyPressed(uint32 what, int32 key, + bool NotifyKeyPressed(uint32 what, int32 key, int32 modifiers); void NotifyMouseEvent(BMessage* message); void NotifyMouseDown(Window* window,