未验证 提交 101e8549 编写于 作者: R Robert Ancell 提交者: GitHub

Add FlMouseCursorPlugin (#18888)

Fixes https://github.com/flutter/flutter/issues/57595
上级 4dc06ad1
......@@ -1225,6 +1225,8 @@ FILE: ../../../flutter/shell/platform/linux/fl_method_codec_private.h
FILE: ../../../flutter/shell/platform/linux/fl_method_codec_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_response.cc
FILE: ../../../flutter/shell/platform/linux/fl_method_response_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_mouse_cursor_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_mouse_cursor_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_platform_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_platform_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_plugin_registrar.cc
......
......@@ -89,6 +89,7 @@ source_set("flutter_linux_sources") {
"fl_method_channel.cc",
"fl_method_codec.cc",
"fl_method_response.cc",
"fl_mouse_cursor_plugin.cc",
"fl_platform_plugin.cc",
"fl_plugin_registrar.cc",
"fl_plugin_registry.cc",
......
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/linux/fl_mouse_cursor_plugin.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"
#include <gtk/gtk.h>
static constexpr char kChannelName[] = "flutter/mousecursor";
static constexpr char kBadArgumentsError[] = "Bad Arguments";
static constexpr char kActivateSystemCursorMethod[] = "activateSystemCursor";
static constexpr char kKindKey[] = "kind";
struct _FlMouseCursorPlugin {
GObject parent_instance;
FlMethodChannel* channel;
FlView* view;
};
G_DEFINE_TYPE(FlMouseCursorPlugin, fl_mouse_cursor_plugin, G_TYPE_OBJECT)
// Sets the mouse cursor.
FlMethodResponse* activate_system_cursor(FlMouseCursorPlugin* self,
FlValue* args) {
if (fl_value_get_type(args) != FL_VALUE_TYPE_MAP) {
return FL_METHOD_RESPONSE(fl_method_error_response_new(
kBadArgumentsError, "Argument map missing or malformed", nullptr));
}
FlValue* kind_value = fl_value_lookup_string(args, kKindKey);
const gchar* kind = nullptr;
if (fl_value_get_type(kind_value) == FL_VALUE_TYPE_STRING)
kind = fl_value_get_string(kind_value);
const gchar* cursor_name = nullptr;
if (g_strcmp0(kind, "none") == 0)
cursor_name = "none";
else if (g_strcmp0(kind, "basic") == 0)
cursor_name = "default";
else if (g_strcmp0(kind, "click") == 0)
cursor_name = "pointer";
else if (g_strcmp0(kind, "text") == 0)
cursor_name = "text";
else if (g_strcmp0(kind, "forbidden") == 0)
cursor_name = "not-allowed";
else if (g_strcmp0(kind, "grab") == 0)
cursor_name = "grab";
else if (g_strcmp0(kind, "grabbing") == 0)
cursor_name = "grabbing";
else if (g_strcmp0(kind, "resizeLeftRight") == 0)
cursor_name = "ew-resize";
else if (g_strcmp0(kind, "resizeUpDown") == 0)
cursor_name = "ns-resize";
else
cursor_name = "default";
GdkWindow* window =
gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(self->view)));
g_autoptr(GdkCursor) cursor =
gdk_cursor_new_from_name(gdk_window_get_display(window), cursor_name);
gdk_window_set_cursor(window, cursor);
return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}
// Called when a method call is received from Flutter.
static void method_call_cb(FlMethodChannel* channel,
FlMethodCall* method_call,
gpointer user_data) {
FlMouseCursorPlugin* self = FL_MOUSE_CURSOR_PLUGIN(user_data);
const gchar* method = fl_method_call_get_name(method_call);
FlValue* args = fl_method_call_get_args(method_call);
g_autoptr(FlMethodResponse) response = nullptr;
if (strcmp(method, kActivateSystemCursorMethod) == 0)
response = activate_system_cursor(self, args);
else
response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
g_autoptr(GError) error = nullptr;
if (!fl_method_call_respond(method_call, response, &error))
g_warning("Failed to send method call response: %s", error->message);
}
static void view_weak_notify_cb(gpointer user_data, GObject* object) {
FlMouseCursorPlugin* self = FL_MOUSE_CURSOR_PLUGIN(object);
self->view = nullptr;
}
static void fl_mouse_cursor_plugin_dispose(GObject* object) {
FlMouseCursorPlugin* self = FL_MOUSE_CURSOR_PLUGIN(object);
g_clear_object(&self->channel);
if (self->view != nullptr) {
g_object_weak_unref(G_OBJECT(self->view), view_weak_notify_cb, self);
self->view = nullptr;
}
G_OBJECT_CLASS(fl_mouse_cursor_plugin_parent_class)->dispose(object);
}
static void fl_mouse_cursor_plugin_class_init(FlMouseCursorPluginClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_mouse_cursor_plugin_dispose;
}
static void fl_mouse_cursor_plugin_init(FlMouseCursorPlugin* self) {}
FlMouseCursorPlugin* fl_mouse_cursor_plugin_new(FlBinaryMessenger* messenger,
FlView* view) {
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
FlMouseCursorPlugin* self = FL_MOUSE_CURSOR_PLUGIN(
g_object_new(fl_mouse_cursor_plugin_get_type(), nullptr));
g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
self->channel =
fl_method_channel_new(messenger, kChannelName, FL_METHOD_CODEC(codec));
fl_method_channel_set_method_call_handler(self->channel, method_call_cb, self,
nullptr);
self->view = view;
g_object_weak_ref(G_OBJECT(view), view_weak_notify_cb, self);
return self;
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_SHELL_MOUSE_CURSOR_LINUX_FL_MOUSE_CURSOR_PLUGIN_H_
#define FLUTTER_SHELL_MOUSE_CURSOR_LINUX_FL_MOUSE_CURSOR_PLUGIN_H_
#include <gdk/gdk.h>
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_view.h"
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE(FlMouseCursorPlugin,
fl_mouse_cursor_plugin,
FL,
MOUSE_CURSOR_PLUGIN,
GObject);
/**
* FlMouseCursorPlugin:
*
* #FlMouseCursorPlugin is a mouse_cursor channel that implements the shell side
* of SystemChannels.mouseCursor from the Flutter services library.
*/
/**
* fl_mouse_cursor_plugin_new:
* @messenger: an #FlBinaryMessenger.
* @view: an #FlView to control.
*
* Creates a new plugin that implements SystemChannels.mouseCursor from the
* Flutter services library.
*
* Returns: a new #FlMouseCursorPlugin.
*/
FlMouseCursorPlugin* fl_mouse_cursor_plugin_new(FlBinaryMessenger* messenger,
FlView* view);
G_END_DECLS
#endif // FLUTTER_SHELL_MOUSE_CURSOR_LINUX_FL_MOUSE_CURSOR_PLUGIN_H_
......@@ -6,6 +6,7 @@
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/fl_key_event_plugin.h"
#include "flutter/shell/platform/linux/fl_mouse_cursor_plugin.h"
#include "flutter/shell/platform/linux/fl_platform_plugin.h"
#include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
#include "flutter/shell/platform/linux/fl_renderer_x11.h"
......@@ -34,6 +35,7 @@ struct _FlView {
// Flutter system channel handlers.
FlKeyEventPlugin* key_event_plugin;
FlMouseCursorPlugin* mouse_cursor_plugin;
FlPlatformPlugin* platform_plugin;
FlTextInputPlugin* text_input_plugin;
};
......@@ -131,6 +133,7 @@ static void fl_view_constructed(GObject* object) {
// Create system channel handlers.
FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(self->engine);
self->key_event_plugin = fl_key_event_plugin_new(messenger);
self->mouse_cursor_plugin = fl_mouse_cursor_plugin_new(messenger, self);
self->platform_plugin = fl_platform_plugin_new(messenger);
self->text_input_plugin = fl_text_input_plugin_new(messenger);
}
......@@ -186,6 +189,7 @@ static void fl_view_dispose(GObject* object) {
g_clear_object(&self->renderer);
g_clear_object(&self->engine);
g_clear_object(&self->key_event_plugin);
g_clear_object(&self->mouse_cursor_plugin);
g_clear_object(&self->platform_plugin);
g_clear_object(&self->text_input_plugin);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册