widget/windows/WinModifierKeyState.h
author Masayuki Nakano <masayuki@d-toybox.com>
Wed, 30 May 2018 17:27:31 +0900
changeset 423599 c2e17337f8b84e8c921007347698d49fb4290bf6
parent 376425 397cfed5073f34740aed9e20460810316ee8ec25
child 448947 6f3709b3878117466168c40affa7bca0b60cf75b
permissions -rw-r--r--
Bug 900750 - part 2: Make ModifierKeyState and VirtualKey treat AltGraph as new modifier and won't set Control and Alt state while AltGraph is active r=m_kato,smaug By the proposal from Google, <https://github.com/w3c/uievents/issues/147>, Chromium treat AltRight key as "AltGraph" modifier if the keyboard layout has AltGr key. When AltRight key is pressed with a keyboard layout which has AltGr key, modifiers should as following: 1. "keydown" for ControlLeft: ctrlKey: true, altKey: false, getModifierState("AltGraph"): false 2. "keydown" for AltRight: ctrlKey: false, altKey: false, getModifierState("AltGraph"): true 3. Some "keydown", "keypress" and "keyup" events: ctrlKey: false, altKey: false, getModifierState("AltGraph"): true 4. "keyup" for ControlLeft: ctrlKey: false, altKey: false, getModifierState("AltGraph"): true 5. "keyup" for AltRight: ctrlKey: false, altKey: false, getModifierState("AltGraph"): false So, only when the preceding "keydown" event for ControlLeft, ctrlKey should be set to true as usual. However, after AltRight key is pressed actually, we should treat "AltGraph" modifier is true and both ctrlKey and altKey should be set to false for web apps can handle text input normally. So, MODIFIER_ALTGRAPH and MODIFIER_CONTROL/MODIFIER_ALT should not be set at the same time. This patch makes ModifierKeyState have only MODIFIER_ALTGRAPH or MODIFIER_CONTROL/MODIFIER_ALT. Additionally, this patch makes VirtualKey::ShiftState treat "AltGraph" as a modifier. So, now, VirtualKey needs to convert ShiftState to index value when it accesses its mShiftStates array. Therefore, this patch adds VirtualKey::ToIndex() and make each VirtualKey method use it before accessing mShiftStates. Note that this patch also fixes bug of WinUtils::SetupKeyModifiersSequence(). The constructor of KeyPair takes 2 keycode values, but the second virtual keycode can have scancode to distinguish if the key is left or right. However, WinUtils::SetupKeyModifiersSequence() never sets scancode to KeyPair. Therefore, it fails to dispatch AltRight key event. MozReview-Commit-ID: 7ealxJH9KlZ

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_widget_WinModifierKeyState_h_
#define mozilla_widget_WinModifierKeyState_h_

#include "mozilla/RefPtr.h"
#include "mozilla/EventForwards.h"
#include "nsStringFwd.h"
#include <windows.h>

namespace mozilla {
namespace widget {

class MOZ_STACK_CLASS ModifierKeyState final
{
public:
  ModifierKeyState();
  explicit ModifierKeyState(Modifiers aModifiers);

  void Update();

  void Unset(Modifiers aRemovingModifiers);
  void Set(Modifiers aAddingModifiers);

  void InitInputEvent(WidgetInputEvent& aInputEvent) const;

  // Do not create IsAltGr() because it's unclear whether:
  // - AltGr key is actually pressed.
  // - Both Ctrl and Alt keys are pressed when a keyboard layout which
  //   has AltGr key.
  // - Both Ctrl and Alt keys are pressed when a keyboard layout which
  //   does not have AltGr key.
  bool IsShift() const;
  bool IsControl() const;
  bool IsAlt() const;
  bool IsWin() const;

  bool MaybeMatchShortcutKey() const;

  bool IsCapsLocked() const;
  bool IsNumLocked() const;
  bool IsScrollLocked() const;

  MOZ_ALWAYS_INLINE Modifiers GetModifiers() const
  {
    return mModifiers;
  }

private:
  Modifiers mModifiers;

  void InitMouseEvent(WidgetInputEvent& aMouseEvent) const;
};

const nsCString ToString(const ModifierKeyState& aModifierKeyState);

} // namespace widget
} // namespace mozilla

#endif // #ifndef mozilla_widget_WinModifierKeyState_h_