From ef5ab08df309a3a9ddf7211df822bfd8eec42c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 21 Aug 2005 14:44:53 +0000 Subject: [PATCH] Fixed keyboard navigation; it should now behave pretty much like R5 AFAICT: - moved standard keyboard navigation into the BView::KeyDown() hook - the window now only handles tab+option/command key - B_COMMAND_KEY triggers group jumping, not B_CONTROL_KEY (that activates the switcher, but directly in the app_server) - fixed broken group navigation: (modifiers & B_COMMAND_KEY & B_SHIFT_KEY) is different to (modifiers & (B_COMMAND_KEY | B_SHIFT_KEY)) and is just never true with these constants. That allows the tab key completion to be used again in Terminal. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14038 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/Window.h | 17 +++++----- src/kits/interface/View.cpp | 36 ++++++++++---------- src/kits/interface/Window.cpp | 63 ++++++++++++++++++++++------------- 3 files changed, 65 insertions(+), 51 deletions(-) diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index fb5eaa5157..e773012db8 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -353,8 +353,6 @@ private: void BuildTopView(); void setFocus(BView *focusView, bool notifyIputServer = false); - bool handleKeyDown(uint32 key, uint32 modifiers); - // message: B_MOUSE_UP, B_MOUSE_DOWN, B_MOUSE_MOVED void sendMessageUsingEventMask(int32 message, BPoint where); BView* sendMessageUsingEventMask2(BView* aView, int32 message, BPoint where); @@ -363,15 +361,16 @@ private: BView* findView(BView* aView, const char* viewName) const; BView* findView(BView* aView, BPoint point) const; BView* findView(BView* aView, int32 token); - - BView* findNextView(BView *focus, uint32 flags); - BView* findPrevView(BView *focus, uint32 flags); BView* findLastChild(BView *parent); - bool handleKeyDown(const char key, uint32 modifiers); - void handleActivation( bool active); - void drawAllViews(BView* aView); - void DoUpdate(BView* aView, BRect& area); + BView* _FindNextNavigable(BView *focus, uint32 flags); + BView* _FindPreviousNavigable(BView *focus, uint32 flags); + bool _HandleKeyDown(char key, uint32 modifiers); + void _KeyboardNavigation(); + void handleActivation(bool active); + + void drawAllViews(BView* view); + void DoUpdate(BView* view, BRect& area); // Debug void PrintToStream() const; diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index d13a4cab11..8025364203 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -1050,7 +1050,7 @@ BView::Window() const void BView::AttachedToWindow() { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::AttachedToWindow()\n", Name())); } @@ -1058,7 +1058,7 @@ BView::AttachedToWindow() void BView::AllAttached() { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::AllAttached()\n", Name())); } @@ -1066,7 +1066,7 @@ BView::AllAttached() void BView::DetachedFromWindow() { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::DetachedFromWindow()\n", Name())); } @@ -1074,7 +1074,7 @@ BView::DetachedFromWindow() void BView::AllDetached() { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::AllDetached()\n", Name())); } @@ -1082,7 +1082,7 @@ BView::AllDetached() void BView::Draw(BRect updateRect) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::Draw()\n", Name())); } @@ -1098,7 +1098,7 @@ BView::DrawAfterChildren(BRect r) void BView::FrameMoved(BPoint newPosition) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::FrameMoved()\n", Name())); } @@ -1106,7 +1106,7 @@ BView::FrameMoved(BPoint newPosition) void BView::FrameResized(float newWidth, float newHeight) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::FrameResized()\n", Name())); } @@ -1137,18 +1137,18 @@ BView::ResizeToPreferred() void BView::KeyDown(const char* bytes, int32 numBytes) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::KeyDown()\n", Name())); - if (numBytes > 0 && bytes[0] == B_TAB) { - // TODO: handle tab navigation here instead of in BWindow - } + + if (Window()) + Window()->_KeyboardNavigation(); } void BView::KeyUp(const char* bytes, int32 numBytes) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::KeyUp()\n", Name())); } @@ -1156,7 +1156,7 @@ BView::KeyUp(const char* bytes, int32 numBytes) void BView::MouseDown(BPoint where) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::MouseDown()\n", Name())); } @@ -1164,7 +1164,7 @@ BView::MouseDown(BPoint where) void BView::MouseUp(BPoint where) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::MouseUp()\n", Name())); } @@ -1172,7 +1172,7 @@ BView::MouseUp(BPoint where) void BView::MouseMoved(BPoint where, uint32 code, const BMessage* a_message) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::MouseMoved()\n", Name())); } @@ -1180,7 +1180,7 @@ BView::MouseMoved(BPoint where, uint32 code, const BMessage* a_message) void BView::Pulse() { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::Pulse()\n", Name())); } @@ -1188,7 +1188,7 @@ BView::Pulse() void BView::TargetedByScrollView(BScrollView* scroll_view) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::TargetedByScrollView()\n", Name())); } @@ -1196,7 +1196,7 @@ BView::TargetedByScrollView(BScrollView* scroll_view) void BView::WindowActivated(bool state) { - // HOOK function + // Hook function STRACE(("\tHOOK: BView(%s)::WindowActivated()\n", Name())); } diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index dd9e5e5457..af60f847ec 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -690,7 +690,7 @@ BWindow::DispatchMessage(BMessage *msg, BHandler *target) msg->FindString("bytes", &string); // TODO: USE target !!!! - if (!handleKeyDown(string[0], (uint32)modifiers)) { + if (!_HandleKeyDown(string[0], (uint32)modifiers)) { if (fFocus) fFocus->KeyDown(string, strlen(string)); else @@ -702,7 +702,7 @@ BWindow::DispatchMessage(BMessage *msg, BHandler *target) case B_KEY_UP: { const char *string = NULL; - msg->FindString( "bytes", &string); + msg->FindString("bytes", &string); // TODO: USE target !!!! if (fFocus) @@ -2456,7 +2456,7 @@ BWindow::determine_target(BMessage *msg, BHandler *target, bool pref) bool -BWindow::handleKeyDown(const char key, uint32 modifiers) +BWindow::_HandleKeyDown(char key, uint32 modifiers) { // TODO: ask people if using 'raw_char' is OK ? @@ -2476,23 +2476,10 @@ BWindow::handleKeyDown(const char key, uint32 modifiers) return true; } - // Keyboard navigation through views!!!! - // TODO: Not correct, only Option-Tab should be handled here. - if (key == B_TAB) { - BView *nextFocus; - - if (modifiers & B_CONTROL_KEY & B_SHIFT_KEY) - nextFocus = findPrevView(fFocus, B_NAVIGABLE_JUMP); - else if (modifiers & B_CONTROL_KEY) - nextFocus = findNextView(fFocus, B_NAVIGABLE_JUMP); - else if (modifiers & B_SHIFT_KEY) - nextFocus = findPrevView(fFocus, B_NAVIGABLE); - else - nextFocus = findNextView(fFocus, B_NAVIGABLE); - - if (nextFocus && nextFocus != fFocus) - setFocus(nextFocus, false); - + // Keyboard navigation through views + // (B_OPTION_KEY makes BTextViews and friends navigable, even in editing mode) + if (key == B_TAB && (modifiers & (B_COMMAND_KEY | B_OPTION_KEY)) != 0) { + _KeyboardNavigation(); return true; } @@ -2547,6 +2534,34 @@ BWindow::handleKeyDown(const char key, uint32 modifiers) return false; } + +void +BWindow::_KeyboardNavigation() +{ + BMessage *message = CurrentMessage(); + if (message == NULL) + return; + + const char *bytes; + uint32 modifiers; + if (message->FindString("bytes", &bytes) != B_OK + || bytes[0] != B_TAB) + return; + + message->FindInt32("modifiers", (int32*)&modifiers); + + BView *nextFocus; + int32 jumpGroups = modifiers & B_CONTROL_KEY ? B_NAVIGABLE_JUMP : B_NAVIGABLE; + if (modifiers & B_SHIFT_KEY) + nextFocus = _FindPreviousNavigable(fFocus, jumpGroups); + else + nextFocus = _FindNextNavigable(fFocus, jumpGroups); + + if (nextFocus && nextFocus != fFocus) + setFocus(nextFocus, false); +} + + BView * BWindow::sendMessageUsingEventMask2(BView *view, int32 message, BPoint where) { @@ -2744,15 +2759,14 @@ BWindow::findView(BView *view, BPoint point) const BView * -BWindow::findNextView(BView *focus, uint32 flags) +BWindow::_FindNextNavigable(BView *focus, uint32 flags) { if (focus == NULL) focus = top_view; BView *nextFocus = focus; - // Ufff... this took me some time... this is the best form I've reached. - // This algorithm searches the tree for BViews that accept focus. + // Search the tree for views that accept focus while (true) { if (nextFocus->fFirstChild) nextFocus = nextFocus->fFirstChild; @@ -2780,10 +2794,11 @@ BWindow::findNextView(BView *focus, uint32 flags) BView * -BWindow::findPrevView(BView *focus, uint32 flags) +BWindow::_FindPreviousNavigable(BView *focus, uint32 flags) { BView *prevFocus = focus; + // Search the tree for views that accept focus while (true) { BView *view; if ((view = findLastChild(prevFocus)) != NULL)