| Index: native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/coding/view-focus-input-events.html
|
| diff --git a/native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/coding/view-focus-input-events.html b/native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/coding/view-focus-input-events.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9c231791c9970e139719f01385b2e42e2c4d2435
|
| --- /dev/null
|
| +++ b/native_client_sdk/src/doc/_developer.chrome.com_generated/devguide/coding/view-focus-input-events.html
|
| @@ -0,0 +1,345 @@
|
| +{{+bindTo:partials.standard_nacl_article}}
|
| +
|
| +<section id="view-change-focus-and-input-events">
|
| +<span id="view-focus-input-events"></span><h1 id="view-change-focus-and-input-events"><span id="view-focus-input-events"></span>View Change, Focus, and Input Events</h1>
|
| +<div class="contents local topic" id="contents">
|
| +<ul class="small-gap">
|
| +<li><a class="reference internal" href="#overview" id="id2">Overview</a></li>
|
| +<li><p class="first"><a class="reference internal" href="#handling-browser-events" id="id3">Handling browser events</a></p>
|
| +<ul class="small-gap">
|
| +<li><a class="reference internal" href="#didchangeview" id="id4">DidChangeView()</a></li>
|
| +<li><a class="reference internal" href="#didchangefocus" id="id5">DidChangeFocus()</a></li>
|
| +</ul>
|
| +</li>
|
| +<li><p class="first"><a class="reference internal" href="#handling-input-events" id="id6">Handling input events</a></p>
|
| +<ul class="small-gap">
|
| +<li><a class="reference internal" href="#registering-a-module-to-accept-input-events" id="id7">Registering a module to accept input events</a></li>
|
| +<li><a class="reference internal" href="#determining-and-branching-on-event-types" id="id8">Determining and branching on event types</a></li>
|
| +<li><a class="reference internal" href="#threading-and-blocking" id="id9">Threading and blocking</a></li>
|
| +</ul>
|
| +</li>
|
| +</ul>
|
| +</div>
|
| +<p>This chapter describes view change, focus, and input event handling for a
|
| +Native Client module. The chapter assumes you are familiar with the
|
| +material presented in the <a class="reference internal" href="/native-client/overview.html"><em>Technical Overview</em></a>.</p>
|
| +<p>There are two examples used in this chapter to illustrate basic
|
| +programming techniques. The <code>input_events</code> example is used to
|
| +illustrate how your module can react to keyboard and mouse input
|
| +event. The <code>mouse_lock</code> example is used to illustrate how your module
|
| +can react to view change events. You can find these examples in the
|
| +<code>/examples/api/input_events</code> and <code>/examples/api/mouse_lock</code>
|
| +directories in the Native Client SDK. There is also the
|
| +ppapi_simple library that can be used to to implement most of the
|
| +boiler plate. The <code>pi_generator</code> example in
|
| +<code>/examples/demo/pi_generator</code> uses ppapi_simple to manage view
|
| +change events and 2D graphics.</p>
|
| +<section id="overview">
|
| +<h2 id="overview">Overview</h2>
|
| +<p>When a user interacts with the web page using a keyboard, mouse or
|
| +some other input device, the browser generates input events.
|
| +In a traditional web application, these input events are
|
| +passed to and handled in JavaScript, typically through event listeners
|
| +and event handlers. In a Native Client application, user interaction
|
| +with an instance of a module (e.g., clicking inside the rectangle
|
| +managed by a module) also generates input events, which are passed to
|
| +the module. The browser also passes view change and focus events that
|
| +affect a module’s instance to the module. Native Client modules can
|
| +override certain functions in the <a class="reference external" href="https://developers.google.com/native-client/peppercpp/classpp_1_1_instance">pp::Instance</a>
|
| +class to handle input and browser events. These functions are listed in
|
| +the table below:</p>
|
| +<table border="1" class="docutils">
|
| +<colgroup>
|
| +</colgroup>
|
| +<thead valign="bottom">
|
| +<tr class="row-odd"><th class="head">Function</th>
|
| +<th class="head">Event</th>
|
| +<th class="head">Use</th>
|
| +</tr>
|
| +</thead>
|
| +<tbody valign="top">
|
| +<tr class="row-even"><td><code>DidChangeView</code></td>
|
| +<td>Called when the position,
|
| +size, or clip rectangle
|
| +of the module’s instance in
|
| +the browser has changed.
|
| +This event also occurs
|
| +when browser window is
|
| +resized or mouse wheel
|
| +is scrolled.</td>
|
| +<td>An implementation
|
| +of this function
|
| +might check the size
|
| +of the module
|
| +instance’s rectangle
|
| +has changed and
|
| +reallocate the
|
| +graphics context
|
| +when a different
|
| +size is received.</td>
|
| +</tr>
|
| +<tr class="row-odd"><td><code>DidChangeFocus</code></td>
|
| +<td>Called when the module’s
|
| +instance in the browser
|
| +has gone in or out of
|
| +focus (usually by
|
| +clicking inside or
|
| +outside the module
|
| +instance). Having focus
|
| +means that keyboard
|
| +events will be sent to
|
| +the module instance.
|
| +An instance’s default
|
| +condition is that it
|
| +does not have focus.</td>
|
| +<td>An implementation
|
| +of this function
|
| +might start or stop
|
| +an animation or a
|
| +blinking cursor.</td>
|
| +</tr>
|
| +<tr class="row-even"><td><code>HandleDocumentLoad</code></td>
|
| +<td>Called after
|
| +<code>pp::Instance::Init()</code>
|
| +for a full-frame module
|
| +instance that was
|
| +instantiated based on
|
| +the MIME type of a
|
| +DOMWindow navigation.
|
| +This situation only
|
| +applies to modules that
|
| +are pre-registered to
|
| +handle certain MIME
|
| +types. If you haven’t
|
| +specifically registered
|
| +to handle a MIME type or
|
| +aren’t positive this
|
| +applies to you, your
|
| +implementation of this
|
| +function can just return
|
| +false.</td>
|
| +<td>This API is only
|
| +applicable when you
|
| +are writing an
|
| +extension to enhance
|
| +the abilities of
|
| +the Chrome web
|
| +browser. For
|
| +example, a PDF
|
| +viewer might
|
| +implement this
|
| +function to download
|
| +and display a PDF
|
| +file.</td>
|
| +</tr>
|
| +<tr class="row-odd"><td><code>HandleInputEvent</code></td>
|
| +<td>Called when a user
|
| +interacts with the
|
| +module’s instance in the
|
| +browser using an input
|
| +device such as a mouse
|
| +or keyboard. You must
|
| +register your module to
|
| +accept input events
|
| +using
|
| +<code>RequestInputEvents()</code>
|
| +for mouse events and
|
| +<code>RequestFilteringInputEvents</code>
|
| +for keyboard events
|
| +prior to overriding this
|
| +function.</td>
|
| +<td>An implementation of
|
| +this function
|
| +examines the input
|
| +event type and
|
| +branches accordingly.</td>
|
| +</tr>
|
| +</tbody>
|
| +</table>
|
| +<p>These interfaces are found in the <a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_instance">pp::Instance class</a>.
|
| +The sections below provide examples of how to handle these events.</p>
|
| +</section><section id="handling-browser-events">
|
| +<h2 id="handling-browser-events">Handling browser events</h2>
|
| +<section id="didchangeview">
|
| +<h3 id="didchangeview">DidChangeView()</h3>
|
| +<p>In the <code>mouse_lock</code> example, <code>DidChangeView()</code> checks the previous size
|
| +of instance’s rectangle versus the new size. It also compares
|
| +other state such as whether or not the app is running in full screen mode.
|
| +If none of the state has actually changed, no action is needed.
|
| +However, if the size of the view or other state has changed, it frees the
|
| +old graphics context and allocates a new one.</p>
|
| +<pre class="prettyprint">
|
| +void MouseLockInstance::DidChangeView(const pp::View& view) {
|
| + // DidChangeView can get called for many reasons, so we only want to
|
| + // rebuild the device context if we really need to.
|
| + if ((size_ == view.GetRect().size()) &&
|
| + (was_fullscreen_ == view.IsFullscreen()) && is_context_bound_) {
|
| + return;
|
| + }
|
| +
|
| + // ...
|
| +
|
| + // Reallocate the graphics context.
|
| + size_ = view.GetRect().size();
|
| + device_context_ = pp::Graphics2D(this, size_, false);
|
| + waiting_for_flush_completion_ = false;
|
| +
|
| + is_context_bound_ = BindGraphics(device_context_);
|
| + // ...
|
| +
|
| + // Remember if we are fullscreen or not
|
| + was_fullscreen_ = view.IsFullscreen();
|
| + // ...
|
| +}
|
| +</pre>
|
| +<p>For more information about graphics contexts and how to manipulate images, see:</p>
|
| +<ul class="small-gap">
|
| +<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_image_data">pp::ImageData class</a></li>
|
| +<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_graphics2_d">pp::Graphics2D class</a></li>
|
| +</ul>
|
| +</section><section id="didchangefocus">
|
| +<h3 id="didchangefocus">DidChangeFocus()</h3>
|
| +<p><code>DidChangeFocus()</code> is called when you click inside or outside of a
|
| +module’s instance in the web page. When the instance goes out
|
| +of focus (click outside of the instance), you might do something
|
| +like stop an animation. When the instance regains focus, you can
|
| +restart the animation.</p>
|
| +<pre class="prettyprint">
|
| +void DidChangeFocus(bool focus) {
|
| + // Do something like stopping animation or a blinking cursor in
|
| + // the instance.
|
| +}
|
| +</pre>
|
| +</section></section><section id="handling-input-events">
|
| +<h2 id="handling-input-events">Handling input events</h2>
|
| +<p>Input events are events that occur when the user interacts with a
|
| +module instance using the mouse, keyboard, or other input device
|
| +(e.g., touch screen). This section describes how the <code>input_events</code>
|
| +example handles input events.</p>
|
| +<section id="registering-a-module-to-accept-input-events">
|
| +<h3 id="registering-a-module-to-accept-input-events">Registering a module to accept input events</h3>
|
| +<p>Before your module can handle these events, you must register your
|
| +module to accept input events using <code>RequestInputEvents()</code> for mouse
|
| +events and <code>RequestFilteringInputEvents()</code> for keyboard events. For the
|
| +<code>input_events</code> example, this is done in the constructor of the
|
| +<code>InputEventInstance</code> class:</p>
|
| +<pre class="prettyprint">
|
| +class InputEventInstance : public pp::Instance {
|
| + public:
|
| + explicit InputEventInstance(PP_Instance instance)
|
| + : pp::Instance(instance), event_thread_(NULL), callback_factory_(this) {
|
| + RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_WHEEL |
|
| + PP_INPUTEVENT_CLASS_TOUCH);
|
| + RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
|
| + }
|
| + // ...
|
| +};
|
| +</pre>
|
| +<p><code>RequestInputEvents()</code> and <code>RequestFilteringInputEvents()</code> accept a
|
| +combination of flags that identify the class of events that the
|
| +instance is requesting to receive. Input event classes are defined in
|
| +the <a class="reference external" href="https://developers.google.com/native-client/dev/pepperc/group___enums.html#gafe68e3c1031daa4a6496845ff47649cd">PP_InputEvent_Class</a>
|
| +enumeration in <a class="reference external" href="https://developers.google.com/native-client/dev/pepperc/ppb__input__event_8h">ppb_input_event.h</a>.</p>
|
| +</section><section id="determining-and-branching-on-event-types">
|
| +<h3 id="determining-and-branching-on-event-types">Determining and branching on event types</h3>
|
| +<p>In a typical implementation, the <code>HandleInputEvent()</code> function
|
| +determines the type of each event using the <code>GetType()</code> function found
|
| +in the <code>InputEvent</code> class. The <code>HandleInputEvent()</code> function then uses a
|
| +switch statement to branch on the type of input event. Input events
|
| +are defined in the <a class="reference external" href="https://developers.google.com/native-client/dev/pepperc/group___enums.html#gaca7296cfec99fcb6646b7144d1d6a0c5">PP_InputEvent_Type</a>
|
| +enumeration in <a class="reference external" href="https://developers.google.com/native-client/dev/pepperc/ppb__input__event_8h">ppb_input_event.h</a>.</p>
|
| +<pre class="prettyprint">
|
| +virtual bool HandleInputEvent(const pp::InputEvent& event) {
|
| + Event* event_ptr = NULL;
|
| + switch (event.GetType()) {
|
| + case PP_INPUTEVENT_TYPE_UNDEFINED:
|
| + break;
|
| + case PP_INPUTEVENT_TYPE_MOUSEDOWN:
|
| + case PP_INPUTEVENT_TYPE_MOUSEUP:
|
| + case PP_INPUTEVENT_TYPE_MOUSEMOVE:
|
| + case PP_INPUTEVENT_TYPE_MOUSEENTER:
|
| + case PP_INPUTEVENT_TYPE_MOUSELEAVE:
|
| + case PP_INPUTEVENT_TYPE_CONTEXTMENU: {
|
| + pp::MouseInputEvent mouse_event(event);
|
| + PP_InputEvent_MouseButton pp_button = mouse_event.GetButton();
|
| + MouseEvent::MouseButton mouse_button = MouseEvent::kNone;
|
| + switch (pp_button) {
|
| + case PP_INPUTEVENT_MOUSEBUTTON_NONE:
|
| + mouse_button = MouseEvent::kNone;
|
| + break;
|
| + case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
|
| + mouse_button = MouseEvent::kLeft;
|
| + break;
|
| + case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
|
| + mouse_button = MouseEvent::kMiddle;
|
| + break;
|
| + case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
|
| + mouse_button = MouseEvent::kRight;
|
| + break;
|
| + }
|
| + event_ptr =
|
| + new MouseEvent(ConvertEventModifier(mouse_event.GetModifiers()),
|
| + mouse_button,
|
| + mouse_event.GetPosition().x(),
|
| + mouse_event.GetPosition().y(),
|
| + mouse_event.GetClickCount(),
|
| + mouse_event.GetTimeStamp(),
|
| + event.GetType() == PP_INPUTEVENT_TYPE_CONTEXTMENU);
|
| + } break;
|
| + case PP_INPUTEVENT_TYPE_WHEEL: {
|
| + pp::WheelInputEvent wheel_event(event);
|
| + event_ptr =
|
| + new WheelEvent(ConvertEventModifier(wheel_event.GetModifiers()),
|
| + wheel_event.GetDelta().x(),
|
| + wheel_event.GetDelta().y(),
|
| + wheel_event.GetTicks().x(),
|
| + wheel_event.GetTicks().y(),
|
| + wheel_event.GetScrollByPage(),
|
| + wheel_event.GetTimeStamp());
|
| + } break;
|
| + case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
|
| + case PP_INPUTEVENT_TYPE_KEYDOWN:
|
| + case PP_INPUTEVENT_TYPE_KEYUP:
|
| + case PP_INPUTEVENT_TYPE_CHAR: {
|
| + pp::KeyboardInputEvent key_event(event);
|
| + event_ptr = new KeyEvent(ConvertEventModifier(key_event.GetModifiers()),
|
| + key_event.GetKeyCode(),
|
| + key_event.GetTimeStamp(),
|
| + key_event.GetCharacterText().DebugString());
|
| + } break;
|
| + default: {
|
| + // For any unhandled events, send a message to the browser
|
| + // so that the user is aware of these and can investigate.
|
| + std::stringstream oss;
|
| + oss << "Default (unhandled) event, type=" << event.GetType();
|
| + PostMessage(oss.str());
|
| + } break;
|
| + }
|
| + event_queue_.Push(event_ptr);
|
| + return true;
|
| +}
|
| +</pre>
|
| +<p>Notice that the generic <code>InputEvent</code> received by <code>HandleInputEvent()</code> is
|
| +converted into a specific type after the event type is
|
| +determined. The event types handled in the example code are
|
| +<code>MouseInputEvent</code>, <code>WheelInputEvent</code>, and <code>KeyboardInputEvent</code>.
|
| +There are also <code>TouchInputEvents</code>. For the latest list of event types,
|
| +see the <a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_input_event">InputEvent documentation</a>.
|
| +For reference information related to the these event classes, see the
|
| +following documentation:</p>
|
| +<ul class="small-gap">
|
| +<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_mouse_input_event">pp::MouseInputEvent class</a></li>
|
| +<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_wheel_input_event">pp::WheelInputEvent class</a></li>
|
| +<li><a class="reference external" href="https://developers.google.com/native-client/dev/peppercpp/classpp_1_1_keyboard_input_event">pp::KeyboardInputEvent class</a></li>
|
| +</ul>
|
| +</section><section id="threading-and-blocking">
|
| +<h3 id="threading-and-blocking">Threading and blocking</h3>
|
| +<p><code>HandleInputEvent()</code> in this example runs on the main module thread.
|
| +However, the bulk of the work happens on a separate worker thread (see
|
| +<code>ProcessEventOnWorkerThread</code>). <code>HandleInputEvent()</code> puts events in
|
| +the <code>event_queue_</code> and the worker thread takes events from the
|
| +<code>event_queue_</code>. This processing happens independently of the main
|
| +thread, so as not to slow down the browser.</p>
|
| +</section></section></section>
|
| +
|
| +{{/partials.standard_nacl_article}}
|
|
|