File: native_web_keyboard_event_mac.mm

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (135 lines) | stat: -rw-r--r-- 4,971 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "components/input/native_web_keyboard_event.h"

#import <AppKit/AppKit.h>

#include "base/containers/span.h"
#include "components/input/web_input_event_builders_mac.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/web_input_event.h"
#include "ui/events/event.h"

namespace input {

namespace {

int modifiersForEvent(int modifiers) {
  int flags = 0;
  if (modifiers & blink::WebInputEvent::kControlKey) {
    flags |= NSEventModifierFlagControl;
  }
  if (modifiers & blink::WebInputEvent::kShiftKey) {
    flags |= NSEventModifierFlagShift;
  }
  if (modifiers & blink::WebInputEvent::kAltKey) {
    flags |= NSEventModifierFlagOption;
  }
  if (modifiers & blink::WebInputEvent::kMetaKey) {
    flags |= NSEventModifierFlagCommand;
  }
  if (modifiers & blink::WebInputEvent::kCapsLockOn) {
    flags |= NSEventModifierFlagCapsLock;
  }
  return flags;
}

size_t WebKeyboardEventTextLength(
    base::span<const char16_t, blink::WebKeyboardEvent::kTextLengthCap> text) {
  size_t text_length = 0;
  while (text_length < text.size() && text[text_length]) {
    ++text_length;
  }
  return text_length;
}

}  // namespace

NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type type,
                                               int modifiers,
                                               base::TimeTicks timestamp)
    : WebKeyboardEvent(type, modifiers, timestamp), skip_if_unhandled(false) {}

NativeWebKeyboardEvent::NativeWebKeyboardEvent(
    const blink::WebKeyboardEvent& web_event,
    gfx::NativeView native_view)
    : WebKeyboardEvent(web_event), skip_if_unhandled(false) {
  NSEventType type = NSEventTypeKeyUp;
  int flags = modifiersForEvent(web_event.GetModifiers());
  if (web_event.GetType() == blink::WebInputEvent::Type::kChar ||
      web_event.GetType() == blink::WebInputEvent::Type::kRawKeyDown ||
      web_event.GetType() == blink::WebInputEvent::Type::kKeyDown) {
    type = NSEventTypeKeyDown;
  }
  size_t text_length = WebKeyboardEventTextLength(web_event.text);
  size_t unmod_text_length =
      WebKeyboardEventTextLength(web_event.unmodified_text);

  // Perform the reverse operation on type that was done in
  // UnmodifiedTextFromEvent(). Avoid using text_length as the control key may
  // cause Mac to set [NSEvent characters] to "\0" which for us is
  // indistinguishable from "".
  if (unmod_text_length == 0) {
    type = NSEventTypeFlagsChanged;
  }

  NSString* text = [[NSString alloc]
      initWithCharacters:reinterpret_cast<const UniChar*>(web_event.text.data())
                  length:text_length];
  NSString* unmodified_text =
      [[NSString alloc] initWithCharacters:reinterpret_cast<const UniChar*>(
                                               web_event.unmodified_text.data())
                                    length:unmod_text_length];

  os_event = base::apple::OwnedNSEvent([NSEvent
                 keyEventWithType:type
                         location:NSZeroPoint
                    modifierFlags:flags
                        timestamp:ui::EventTimeStampToSeconds(
                                      web_event.TimeStamp())
                     windowNumber:[[native_view.GetNativeNSView() window]
                                      windowNumber]
                          context:nil
                       characters:text
      charactersIgnoringModifiers:unmodified_text
                        isARepeat:NO
                          keyCode:web_event.native_key_code]);
  // The eventRef is necessary for MacOS code (like NSMenu) to work later in the
  // pipeline. As per documentation:
  // https://developer.apple.com/documentation/appkit/nsevent/1525143-eventref
  // "Other NSEvent objects create an EventRef when this property is first
  // accessed, if possible".
  [os_event.Get() eventRef];
}

NativeWebKeyboardEvent::NativeWebKeyboardEvent(gfx::NativeEvent native_event)
    : WebKeyboardEvent(WebKeyboardEventBuilder::Build(native_event.Get())),
      os_event(native_event),
      skip_if_unhandled(false) {}

NativeWebKeyboardEvent::NativeWebKeyboardEvent(const ui::KeyEvent& key_event)
    : WebKeyboardEvent(ui::MakeWebKeyboardEvent(key_event)),
      os_event(base::apple::OwnedNSEvent(key_event.native_event())),
      skip_if_unhandled(false) {}

NativeWebKeyboardEvent::NativeWebKeyboardEvent(
    const NativeWebKeyboardEvent& other)
    : WebKeyboardEvent(other),
      os_event(other.os_event),
      skip_if_unhandled(other.skip_if_unhandled) {}

NativeWebKeyboardEvent& NativeWebKeyboardEvent::operator=(
    const NativeWebKeyboardEvent& other) {
  WebKeyboardEvent::operator=(other);

  os_event = other.os_event;
  skip_if_unhandled = other.skip_if_unhandled;

  return *this;
}

NativeWebKeyboardEvent::~NativeWebKeyboardEvent() = default;

}  // namespace input