From 87da7984dc830d44b9d611680d84d474726d861b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 19 Aug 2009 15:45:17 +0000 Subject: [PATCH] * Contrl-~ now switches between application windows. This is handier than the mechanism used in BeOS, that is to press Control+Option-Tab (which didn't work on Haiku, though). * Did not change the window switch logic, though, so it's still not really nice. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32524 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/Window.h | 3 + src/apps/deskbar/Switcher.cpp | 15 +++-- src/kits/interface/Window.cpp | 106 +++++++++++++++++++++++----------- 3 files changed, 85 insertions(+), 39 deletions(-) diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index a64e6f3444..49869faf46 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -330,7 +330,10 @@ private: BView* _FindNextNavigable(BView *focus, uint32 flags); BView* _FindPreviousNavigable(BView *focus, uint32 flags); + void _Switcher(int32 rawKey, uint32 modifiers, + bool repeat); bool _HandleKeyDown(BMessage* event); + bool _HandleUnmappedKeyDown(BMessage* event); void _KeyboardNavigation(); void _GetDecoratorSize(float* _borderWidth, diff --git a/src/apps/deskbar/Switcher.cpp b/src/apps/deskbar/Switcher.cpp index 288ccf0121..11c19d2750 100644 --- a/src/apps/deskbar/Switcher.cpp +++ b/src/apps/deskbar/Switcher.cpp @@ -598,10 +598,12 @@ TSwitchManager::MessageReceived(BMessage* message) // Want to skip TASK msgs posted before the window // was made visible. Better UI feel if we do this. if (time > fSkipUntil) { - uint32 modifiers; + uint32 modifiers = 0; message->FindInt32("modifiers", (int32*)&modifiers); - Process((modifiers & B_SHIFT_KEY) == 0, - (modifiers & B_OPTION_KEY) != 0); + int32 key = 0; + message->FindInt32("key", &key); + + Process((modifiers & B_SHIFT_KEY) == 0, key == 0x11); } } } else @@ -702,8 +704,7 @@ TSwitchManager::MainEntry(BMessage* message) // Must be a multiple of the delay used above } - Process((modifierKeys & B_SHIFT_KEY) == 0, - (modifierKeys & B_OPTION_KEY) != 0); + Process((modifierKeys & B_SHIFT_KEY) == 0, key == 0x11); } @@ -784,12 +785,14 @@ TSwitchManager::QuickSwitch(BMessage* message) { uint32 modifiers = 0; message->FindInt32("modifiers", (int32*)&modifiers); + int32 key = 0; + message->FindInt32("key", &key); team_id team; if (message->FindInt32("team", &team) == B_OK) { bool forward = (modifiers & B_SHIFT_KEY) == 0; - if ((modifiers & B_OPTION_KEY) != 0) { + if (key == 0x11) { // TODO: add the same switch logic we have for apps! SwitchWindow(team, forward, true); } else { diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index b3e9651e61..87f06df54c 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -1134,6 +1134,13 @@ FrameMoved(origin); break; } + case B_UNMAPPED_KEY_DOWN: + { + if (!_HandleUnmappedKeyDown(msg)) + target->MessageReceived(msg); + break; + } + case B_MOUSE_DOWN: { BView* view = dynamic_cast(target); @@ -3434,8 +3441,32 @@ BWindow::_TransitForMouseMoved(BView* view, BView* viewUnderMouse) const } -/*! - Handles keyboard input before it gets forwarded to the target handler. +/*! Forwards the key to the switcher +*/ +void +BWindow::_Switcher(int32 rawKey, uint32 modifiers, bool repeat) +{ + // only send the first key press, no repeats + if (repeat) + return; + + BMessenger deskbar(kDeskbarSignature); + if (!deskbar.IsValid()) { + // TODO: have some kind of fallback-handling in case the Deskbar is + // not available? + return; + } + + BMessage message('TASK'); + message.AddInt32("key", rawKey); + message.AddInt32("modifiers", modifiers); + message.AddInt64("when", system_time()); + message.AddInt32("team", Team()); + deskbar.SendMessage(&message); +} + + +/*! Handles keyboard input before it gets forwarded to the target handler. This includes shortcut evaluation, keyboard navigation, etc. \return handled if true, the event was already handled, and will not @@ -3475,21 +3506,12 @@ BWindow::_HandleKeyDown(BMessage* event) return true; } + int32 rawKey; + event->FindInt32("key", &rawKey); + // Deskbar's Switcher - if (key == B_TAB && (modifiers & B_CONTROL_KEY) != 0) { - BMessenger deskbar(kDeskbarSignature); - int32 rawKey; - if (event->FindInt32("key", &rawKey) == B_OK - && !event->HasInt32("be:key_repeat") - && deskbar.IsValid()) { - // only send the first key press, no repeats - BMessage message('TASK'); - message.AddInt32("key", rawKey); - message.AddInt32("modifiers", modifiers); - message.AddInt64("when", system_time()); - message.AddInt32("team", Team()); - deskbar.SendMessage(&message); - } + if ((key == B_TAB || rawKey == 0x11) && (modifiers & B_CONTROL_KEY) != 0) { + _Switcher(rawKey, modifiers, event->HasInt32("be:key_repeat")); return true; } @@ -3502,22 +3524,18 @@ BWindow::_HandleKeyDown(BMessage* event) return true; } - if (key == B_FUNCTION_KEY) { - // Check for Print Screen - int32 rawKey; - if (event->FindInt32("key", &rawKey) == B_OK && rawKey == B_PRINT_KEY) { - BMessage message(B_REFS_RECEIVED); - message.AddBool("silent", true); + if (key == B_FUNCTION_KEY && rawKey == B_PRINT_KEY) { + BMessage message(B_REFS_RECEIVED); + message.AddBool("silent", true); - if ((modifiers & B_CONTROL_KEY) != 0) - message.AddBool("window", true); + if ((modifiers & B_CONTROL_KEY) != 0) + message.AddBool("window", true); - if ((modifiers & B_SHIFT_KEY) != 0 || (modifiers & B_OPTION_KEY) != 0) - message.ReplaceBool("silent", false); + if ((modifiers & B_SHIFT_KEY) != 0 || (modifiers & B_OPTION_KEY) != 0) + message.ReplaceBool("silent", false); - be_roster->Launch("application/x-vnd.haiku-screenshot", &message); - return true; - } + be_roster->Launch("application/x-vnd.haiku-screenshot", &message); + return true; } // Handle shortcuts @@ -3544,10 +3562,8 @@ BWindow::_HandleKeyDown(BMessage* event) // example) if (shortcut->MenuItem() != NULL) { BMenu* menu = shortcut->MenuItem()->Menu(); - if (menu != NULL) { - MenuPrivate(menu).InvokeItem(shortcut->MenuItem(), - true); - } + if (menu != NULL) + MenuPrivate(menu).InvokeItem(shortcut->MenuItem(), true); } else { BHandler* target = shortcut->Target(); if (target == NULL) @@ -3578,6 +3594,30 @@ BWindow::_HandleKeyDown(BMessage* event) } +bool +BWindow::_HandleUnmappedKeyDown(BMessage* event) +{ + // Only handle special functions when the event targeted the active focus + // view + if (!_IsFocusMessage(event)) + return false; + + uint32 modifiers; + int32 rawKey; + if (event->FindInt32("modifiers", (int32*)&modifiers) != B_OK + || event->FindInt32("key", &rawKey)) + return false; + + // Deskbar's Switcher + if (rawKey == 0x11 && (modifiers & B_CONTROL_KEY) != 0) { + _Switcher(rawKey, modifiers, event->HasInt32("be:key_repeat")); + return true; + } + + return false; +} + + void BWindow::_KeyboardNavigation() {