Skip to content

[linux] Implements basic ASCII text input #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
May 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion linux/library/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ LDFLAGS= -L$(CURDIR) \

LIBRARIES=lib$(FLUTTER_ENGINE_LIB).so
HEADERS=$(shell find include/ -type f -name '*.h')
SOURCES=$(wildcard src/*.cc)
SOURCES=$(shell find src/ -type f -name '*.cc')

.PHONY: all
all: $(LIBRARY_OUT)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_COMMON_PLATFORM_PROTOCOL_H_
#define LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_COMMON_PLATFORM_PROTOCOL_H_

// Defines a set of common JSON keys for communicating with the Flutter Engine's
// platform message protocol.
namespace flutter_desktop_embedding {

extern const char kMethodKey[];
extern const char kArgumentsKey[];

} // namespace flutter_desktop_embedding

#endif // LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_COMMON_PLATFORM_PROTOCOL_H_
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LINUX_INCLUDE_FILE_CHOOSER_PLUGIN_H_
#define LINUX_INCLUDE_FILE_CHOOSER_PLUGIN_H_
#ifndef LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_FILE_CHOOSER_PLUGIN_H_
#define LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_FILE_CHOOSER_PLUGIN_H_
#include "plugin.h"

namespace flutter_desktop_embedding {
Expand All @@ -28,4 +28,4 @@ class FileChooserPlugin : public Plugin {

} // namespace flutter_desktop_embedding

#endif // LINUX_INCLUDE_FILE_CHOOSER_PLUGIN_H_
#endif // LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_FILE_CHOOSER_PLUGIN_H_
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LINUX_LIBRARY_INCLUDE_FLUTTER_EMBEDDER_H_
#define LINUX_LIBRARY_INCLUDE_FLUTTER_EMBEDDER_H_
#ifndef LINUX_LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_FLUTTER_EMBEDDER_H_
#define LINUX_LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_FLUTTER_EMBEDDER_H_

// Epoxy must be included before any graphics-related code.
#include <epoxy/gl.h>
Expand Down Expand Up @@ -79,4 +79,4 @@ void FlutterWindowLoop(GLFWwindow *flutter_window);

} // namespace flutter_desktop_embedding

#endif // LINUX_LIBRARY_INCLUDE_FLUTTER_EMBEDDER_H_
#endif // LINUX_LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_FLUTTER_EMBEDDER_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_INPUT_KEYBOARD_HOOK_HANDLER_H_
#define LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_INPUT_KEYBOARD_HOOK_HANDLER_H_

#include <GLFW/glfw3.h>

namespace flutter_desktop_embedding {

// Abstract class for handling keyboard input events.
class KeyboardHookHandler {
public:
// A function for hooking into keyboard input.
virtual void KeyboardHook(GLFWwindow *window, int key, int scancode,
int action, int mods) = 0;

// A function for hooking into unicode code point input.
virtual void CharHook(GLFWwindow *window, unsigned int code_point) = 0;
};

} // namespace flutter_desktop_embedding

#endif // LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_INPUT_KEYBOARD_HOOK_HANDLER_H_
29 changes: 21 additions & 8 deletions linux/library/include/flutter_desktop_embedding/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LINUX_INCLUDE_PLUGIN_H_
#define LINUX_INCLUDE_PLUGIN_H_
#ifndef LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_PLUGIN_H_
#define LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_PLUGIN_H_
#include <json/json.h>

#include <functional>
#include <string>

#include <embedder.h>

namespace flutter_desktop_embedding {

// Represents a plugin that can be registered with the Flutter Embedder.
Expand All @@ -31,14 +34,13 @@ class Plugin {
// |input_blocking| Determines whether user input should be blocked during the
// duration of this plugin's platform callback handler (in most cases this
// can be set to false).
explicit Plugin(std::string channel, bool input_blocking = false)
: channel_(channel), input_blocking_(input_blocking) {}
virtual ~Plugin() {}
explicit Plugin(std::string channel, bool input_blocking = false);
virtual ~Plugin();

// Handles a platform message sent on this platform's channel.
//
// If some error has occurred or there is no valid response that can be made,
// must return a Json::nullValue object.
// If some error has occurred or there is no valid response that can be
// made, must return a Json::nullValue object.
virtual Json::Value HandlePlatformMessage(const Json::Value &message) = 0;

// Returns the channel on which this plugin listens.
Expand All @@ -50,11 +52,22 @@ class Plugin {
// while waiting for this plugin to handle its platform message.
virtual bool input_blocking() const { return input_blocking_; }

// Sets the pointer to the caller-owned Flutter Engine.
//
// The embedder typically sets this pointer rather than the client.
virtual void set_flutter_engine(FlutterEngine engine) { engine_ = engine; }

protected:
// Sends a message to the flutter engine on this Plugin's channel.
void SendMessageToFlutterEngine(const Json::Value &json);

private:
std::string channel_;
// Caller-owned instance of the Flutter Engine.
FlutterEngine engine_;
bool input_blocking_;
};

} // namespace flutter_desktop_embedding

#endif // LINUX_INCLUDE_FLUTTER_EMBEDDER_PLUGIN_H_
#endif // LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_PLUGIN_H_
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LINUX_INCLUDE_PLUGIN_HANDLER_H_
#define LINUX_INCLUDE_PLUGIN_HANDLER_H_
#include <json/json.h>
#ifndef LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_PLUGIN_HANDLER_H_
#define LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_PLUGIN_HANDLER_H_

#include <functional>
#include <json/json.h>
#include <map>
#include <memory>
#include <string>
Expand Down Expand Up @@ -58,4 +57,4 @@ class PluginHandler {

} // namespace flutter_desktop_embedding

#endif // LINUX_INCLUDE_PLUGIN_HANDLER_H_
#endif // LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_PLUGIN_HANDLER_H_
97 changes: 97 additions & 0 deletions linux/library/include/flutter_desktop_embedding/text_input_model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_TEXT_INPUT_MODEL_H_
#define LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_TEXT_INPUT_MODEL_H_

#include <json/json.h>
#include <string>

namespace flutter_desktop_embedding {
// Handles underlying text input state, using a simple ASCII model.
//
// Ignores special states like "insert mode" for now.
class TextInputModel {
public:
explicit TextInputModel(int client_id);
virtual ~TextInputModel();

// Attempts to set the text state.
//
// Returns false if the state is not valid (base or extent are out of
// bounds, or base is less than extent).
bool SetEditingState(size_t selection_base, size_t selection_extent,
const std::string &text);

// Adds a character.
//
// Either appends after the cursor (when selection base and extent are the
// same), or deletes the selected characters, replacing the text with the
// character specified.
void AddCharacter(char c);

// Deletes either the selection, or one character ahead of the cursor.
//
// Deleting one character ahead of the cursor occurs when the selection base
// and extent are the same.
//
// Returns true if any deletion actually occurred.
bool Delete();

// Deletes either the selection, or one character behind the cursor.
//
// Deleting one character behind the cursor occurs when the selection base
// and extent are the same.
//
// Returns true if any deletion actually occurred.
bool Backspace();

// Attempts to move the cursor backward.
//
// Returns true if the cursor could be moved. Changes base and extent to be
// equal to either the extent (if extent is at the end of the string), or
// for extent to be equal to
bool MoveCursorBack();

// Attempts to move the cursor forward.
//
// Returns true if the cursor could be moved.
bool MoveCursorForward();

// Attempts to move the cursor to the beginning.
//
// Returns true if the cursor could be moved.
void MoveCursorToBeginning();

// Attempts to move the cursor to the back.
//
// Returns true if the cursor could be moved.
void MoveCursorToEnd();

// Returns the state in the form of a platform message.
Json::Value GetState();

int client_id() const { return client_id_; }

private:
void DeleteSelected();

std::string text_;
int client_id_;
std::string::iterator selection_base_;
std::string::iterator selection_extent_;
};

} // namespace flutter_desktop_embedding

#endif // LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_TEXT_INPUT_MODEL_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_TEXT_INPUT_PLUGIN_H_
#define LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_TEXT_INPUT_PLUGIN_H_

#include <map>
#include <memory>

#include <flutter_desktop_embedding/input/keyboard_hook_handler.h>

#include "plugin.h"
#include "text_input_model.h"

namespace flutter_desktop_embedding {

// Implements a text input plugin.
//
// Specifically handles window events within GLFW.
class TextInputPlugin : public KeyboardHookHandler, public Plugin {
public:
TextInputPlugin();
virtual ~TextInputPlugin();

// Plugin.
Json::Value HandlePlatformMessage(const Json::Value &message) override;

// KeyboardHookHandler.
void KeyboardHook(GLFWwindow *window, int key, int scancode, int action,
int mods) override;

// KeyboardHookHandler.
void CharHook(GLFWwindow *window, unsigned int code_point) override;

private:
// Mapping of client IDs to text input models.
std::map<int, std::unique_ptr<TextInputModel>> input_models_;

// The active model. nullptr if not set.
TextInputModel *active_model_;
};

} // namespace flutter_desktop_embedding

#endif // LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_TEXT_INPUT_PLUGIN_H_
21 changes: 21 additions & 0 deletions linux/library/src/common/platform_protocol.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <flutter_desktop_embedding/common/platform_protocol.h>

namespace flutter_desktop_embedding {

constexpr char kMethodKey[] = "method";
constexpr char kArgumentsKey[] = "args";

} // namespace flutter_desktop_embedding
3 changes: 2 additions & 1 deletion linux/library/src/file_chooser_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ Json::Value FileChooserPlugin::HandlePlatformMessage(
g_slist_free(files);
}
g_object_unref(chooser);
return CreateCallback(filenames, chooser_res, args);
SendMessageToFlutterEngine(CreateCallback(filenames, chooser_res, args));
return Json::nullValue;
}

} // namespace flutter_desktop_embedding
Loading