diff options
author | serya@google.com <serya@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-08 09:52:34 +0000 |
---|---|---|
committer | serya@google.com <serya@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-08 09:52:34 +0000 |
commit | 85a6b157624975c6d0ebcf29600a38899c653f62 (patch) | |
tree | 5d07ae90640077322d297e4438f5ed0295775512 | |
parent | d6a48af44917f4d0984cdc331f58df4dc56cb63e (diff) | |
download | chromium_src-85a6b157624975c6d0ebcf29600a38899c653f62.zip chromium_src-85a6b157624975c6d0ebcf29600a38899c653f62.tar.gz chromium_src-85a6b157624975c6d0ebcf29600a38899c653f62.tar.bz2 |
Sound volume and bightness bubbles don't grab focus anymore.
Pressing the escape key to close such a bubble is handled on a higher level. So this key closes the bubble first and then closes other popups (such as a combo box popup).
BUG=chromium-os:16684
TEST=Open a page with popup element (translate bar popup element would suit). Open the popup. Press the "Volume up" button. Press Esc. Ensure the volume bubble has closed (not the popup). Open a search page. Put focus to the search box. Press the "Volume up" key. Ensure any keys except volume contol keys and Esc are handled by the search box.
Review URL: http://codereview.chromium.org/7294024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@91829 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chromeos/setting_level_bubble.cc | 7 | ||||
-rw-r--r-- | chrome/browser/chromeos/setting_level_bubble.h | 1 | ||||
-rw-r--r-- | chrome/browser/chromeos/system_key_event_listener.cc | 17 | ||||
-rw-r--r-- | chrome/browser/chromeos/system_key_event_listener.h | 8 | ||||
-rw-r--r-- | chrome/browser/ui/views/bubble/bubble.cc | 28 | ||||
-rw-r--r-- | chrome/browser/ui/views/bubble/bubble.h | 16 |
6 files changed, 65 insertions, 12 deletions
diff --git a/chrome/browser/chromeos/setting_level_bubble.cc b/chrome/browser/chromeos/setting_level_bubble.cc index d3f58e7..fc0d55f 100644 --- a/chrome/browser/chromeos/setting_level_bubble.cc +++ b/chrome/browser/chromeos/setting_level_bubble.cc @@ -112,6 +112,9 @@ void SettingLevelBubble::ShowBubble(int percent) { const int x = view_size.width() / 2 + kBubbleXRatio * (bounds.width() - view_size.width()); const int y = bounds.height() - view_size.height() / 2 - kBubbleBottomGap; + + // ShowFocusless doesn't set ESC accelerator. The Esc key is handled in + // SystemKeyEventListener instead. bubble_ = Bubble::ShowFocusless(widget, // parent gfx::Rect(x, y, 0, 20), BubbleBorder::FLOAT, @@ -136,6 +139,10 @@ void SettingLevelBubble::HideBubble() { bubble_->Close(); } +bool SettingLevelBubble::IsShown() const { + return bubble_ != NULL; +} + void SettingLevelBubble::UpdateWithoutShowingBubble(int percent) { percent = LimitPercent(percent); diff --git a/chrome/browser/chromeos/setting_level_bubble.h b/chrome/browser/chromeos/setting_level_bubble.h index 454ad85..7d5af90 100644 --- a/chrome/browser/chromeos/setting_level_bubble.h +++ b/chrome/browser/chromeos/setting_level_bubble.h @@ -25,6 +25,7 @@ class SettingLevelBubble : public BubbleDelegate, public: void ShowBubble(int percent); void HideBubble(); + bool IsShown() const; // Update the bubble's current level without showing the bubble onscreen. // We _do_ still animate the level moving to |percent| in case the bubble is diff --git a/chrome/browser/chromeos/system_key_event_listener.cc b/chrome/browser/chromeos/system_key_event_listener.cc index 8e1b9dd..fc165fe 100644 --- a/chrome/browser/chromeos/system_key_event_listener.cc +++ b/chrome/browser/chromeos/system_key_event_listener.cc @@ -43,6 +43,7 @@ SystemKeyEventListener::SystemKeyEventListener() key_f8_ = XKeysymToKeycode(GDK_DISPLAY(), XK_F8); key_f9_ = XKeysymToKeycode(GDK_DISPLAY(), XK_F9); key_f10_ = XKeysymToKeycode(GDK_DISPLAY(), XK_F10); + key_esc_ = XKeysymToKeycode(GDK_DISPLAY(), XK_Escape); if (key_volume_mute_) GrabKey(key_volume_mute_, 0); @@ -53,6 +54,7 @@ SystemKeyEventListener::SystemKeyEventListener() GrabKey(key_f8_, 0); GrabKey(key_f9_, 0); GrabKey(key_f10_, 0); + GrabKey(key_esc_, 0); int xkb_major_version = XkbMajorVersion; int xkb_minor_version = XkbMinorVersion; @@ -229,6 +231,9 @@ bool SystemKeyEventListener::ProcessedXEvent(XEvent* xevent) { UserMetrics::RecordAction(UserMetricsAction("Accel_VolumeUp_F10")); OnVolumeUp(); return true; + } else if (keycode == key_esc_ && IsBubbleShown()) { + HideBubble(); + return true; } } } @@ -236,4 +241,16 @@ bool SystemKeyEventListener::ProcessedXEvent(XEvent* xevent) { return false; } +// static +bool SystemKeyEventListener::IsBubbleShown() { + return BrightnessBubble::GetInstance()->IsShown() || + VolumeBubble::GetInstance()->IsShown(); +} + +// static +void SystemKeyEventListener::HideBubble() { + BrightnessBubble::GetInstance()->HideBubble(); + VolumeBubble::GetInstance()->HideBubble(); +} + } // namespace chromeos diff --git a/chrome/browser/chromeos/system_key_event_listener.h b/chrome/browser/chromeos/system_key_event_listener.h index ade270f..fbc2855 100644 --- a/chrome/browser/chromeos/system_key_event_listener.h +++ b/chrome/browser/chromeos/system_key_event_listener.h @@ -85,9 +85,17 @@ class SystemKeyEventListener : public WmMessageListener::Observer, int32 key_f8_; int32 key_f9_; int32 key_f10_; + int32 key_esc_; bool stopped_; + // Tells if one of system setting bubble (VolumeBubble or BrightnessBubble) + // is shown. + static bool IsBubbleShown(); + + // Hides all shown system setting bubbles (VolumeBubble and BrightnessBubble). + static void HideBubble(); + ObserverList<CapslockObserver> capslock_observers_; int xkb_event_base_code_; diff --git a/chrome/browser/ui/views/bubble/bubble.cc b/chrome/browser/ui/views/bubble/bubble.cc index 477e96b..6886d72 100644 --- a/chrome/browser/ui/views/bubble/bubble.cc +++ b/chrome/browser/ui/views/bubble/bubble.cc @@ -55,6 +55,10 @@ Bubble* Bubble::Show(views::Widget* parent, Bubble* bubble = new Bubble; bubble->InitBubble(parent, position_relative_to, arrow_location, contents, delegate); + + // Register the Escape accelerator for closing. + bubble->RegisterEscapeAccelerator(); + return bubble; } @@ -139,7 +143,8 @@ Bubble::Bubble() show_while_screen_is_locked_(false), #endif arrow_location_(BubbleBorder::NONE), - contents_(NULL) { + contents_(NULL), + accelerator_registered_(false) { } #if defined(OS_CHROMEOS) @@ -267,10 +272,6 @@ void Bubble::InitBubble(views::Widget* parent, #endif GetWidget()->SetBounds(window_bounds); - // Register the Escape accelerator for closing. - GetWidget()->GetFocusManager()->RegisterAccelerator( - views::Accelerator(ui::VKEY_ESCAPE, false, false, false), this); - // Done creating the bubble. NotificationService::current()->Notify(NotificationType::INFO_BUBBLE_CREATED, Source<Bubble>(this), @@ -287,6 +288,19 @@ void Bubble::InitBubble(views::Widget* parent, #endif } +void Bubble::RegisterEscapeAccelerator() { + GetWidget()->GetFocusManager()->RegisterAccelerator( + views::Accelerator(ui::VKEY_ESCAPE, false, false, false), this); + accelerator_registered_ = true; +} + +void Bubble::UnregisterEscapeAccelerator() { + DCHECK(accelerator_registered_); + GetWidget()->GetFocusManager()->UnregisterAccelerator( + views::Accelerator(ui::VKEY_ESCAPE, false, false, false), this); + accelerator_registered_ = false; +} + BorderContents* Bubble::CreateBorderContents() { return new BorderContents(); } @@ -334,8 +348,8 @@ void Bubble::DoClose(bool closed_by_escape) { if (show_status_ == kClosed) return; - GetWidget()->GetFocusManager()->UnregisterAccelerator( - views::Accelerator(ui::VKEY_ESCAPE, false, false, false), this); + if (accelerator_registered_) + UnregisterEscapeAccelerator(); if (delegate_) delegate_->BubbleClosing(this, closed_by_escape); show_status_ = kClosed; diff --git a/chrome/browser/ui/views/bubble/bubble.h b/chrome/browser/ui/views/bubble/bubble.h index 9c2735c..c79430d 100644 --- a/chrome/browser/ui/views/bubble/bubble.h +++ b/chrome/browser/ui/views/bubble/bubble.h @@ -98,11 +98,12 @@ class Bubble BubbleDelegate* delegate); #if defined(OS_CHROMEOS) - // Shows the Bubble without grabbing the focus. Others are the same as - // above. TYPE_POPUP widget is used to achieve the focusless effect. - // If |show_while_screen_is_locked| is true, a property is set telling the - // window manager to continue showing the bubble even while the screen is - // locked. + // Shows the Bubble without grabbing the focus. Doesn't set the Escape + // accelerator so user code is responsible for closing the bubble on pressing + // the Esc key. Others are the same as above. TYPE_POPUP widget is used + // to achieve the focusless effect. If |show_while_screen_is_locked| is true, + // a property is set telling the window manager to continue showing the bubble + // even while the screen is locked. static Bubble* ShowFocusless(views::Widget* parent, const gfx::Rect& position_relative_to, BubbleBorder::ArrowLocation arrow_location, @@ -190,6 +191,9 @@ class Bubble // Animates to a visible/hidden state (visible if |fade_in| is true). void Fade(bool fade_in); + void RegisterEscapeAccelerator(); + void UnregisterEscapeAccelerator(); + // Overridden from AcceleratorTarget: virtual bool AcceleratorPressed(const views::Accelerator& accelerator); @@ -220,6 +224,8 @@ class Bubble views::View* contents_; + bool accelerator_registered_; + DISALLOW_COPY_AND_ASSIGN(Bubble); }; |