text: Move input_panel interface to input-method
Move the input_panel interface from desktop-shell to input-method (since it is not really tied to desktop-shell). Add an input_panel_surface interface like wl_shell_surface to make it easier to extend it. Also add a parameter to the set_toplevel request to be able to specify where to show an input panel surface on the screen. Signed-off-by: Jan Arne Petersen <jpetersen@openismus.com>
This commit is contained in:
parent
23ccfb3ef9
commit
ffbb20f730
|
@ -31,8 +31,6 @@
|
|||
#include "window.h"
|
||||
#include "input-method-client-protocol.h"
|
||||
#include "text-client-protocol.h"
|
||||
#include "desktop-shell-client-protocol.h"
|
||||
|
||||
|
||||
struct virtual_keyboard {
|
||||
struct input_panel *input_panel;
|
||||
|
@ -641,6 +639,7 @@ keyboard_create(struct output *output, struct virtual_keyboard *virtual_keyboard
|
|||
{
|
||||
struct keyboard *keyboard;
|
||||
const struct layout *layout;
|
||||
struct input_panel_surface *ips;
|
||||
|
||||
layout = get_current_layout(virtual_keyboard);
|
||||
|
||||
|
@ -664,9 +663,11 @@ keyboard_create(struct output *output, struct virtual_keyboard *virtual_keyboard
|
|||
layout->columns * key_width,
|
||||
layout->rows * key_height);
|
||||
|
||||
input_panel_set_surface(virtual_keyboard->input_panel,
|
||||
window_get_wl_surface(keyboard->window),
|
||||
output_get_wl_output(output));
|
||||
|
||||
ips = input_panel_get_input_panel_surface(virtual_keyboard->input_panel,
|
||||
window_get_wl_surface(keyboard->window));
|
||||
|
||||
input_panel_surface_set_toplevel(ips, INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -98,22 +98,4 @@
|
|||
</request>
|
||||
|
||||
</interface>
|
||||
|
||||
<interface name="input_panel" version="1">
|
||||
<description summary="interface for implementing keyboards">
|
||||
Only one client can bind this interface at a time.
|
||||
</description>
|
||||
|
||||
<request name="set_surface">
|
||||
<description summary="set the surface type as a keyboard">
|
||||
A keybaord surface is only shown, when a text model is active
|
||||
</description>
|
||||
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
<arg name="output" type="object" interface="wl_output"/>
|
||||
</request>
|
||||
|
||||
</interface>
|
||||
|
||||
|
||||
</protocol>
|
||||
|
|
|
@ -157,4 +157,28 @@
|
|||
<arg name="context" type="object" interface="input_method_context"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="input_panel" version="1">
|
||||
<description summary="interface for implementing keyboards">
|
||||
Only one client can bind this interface at a time.
|
||||
</description>
|
||||
|
||||
<request name="get_input_panel_surface">
|
||||
<arg name="id" type="new_id" interface="input_panel_surface"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="input_panel_surface" version="1">
|
||||
<enum name="position">
|
||||
<entry name="center_bottom" value="0"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_toplevel">
|
||||
<description summary="set the surface type as a keyboard">
|
||||
A keybaord surface is only shown, when a text model is active
|
||||
</description>
|
||||
<arg name="position" type="uint"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
||||
|
|
143
src/shell.c
143
src/shell.c
|
@ -35,6 +35,7 @@
|
|||
#include <wayland-server.h>
|
||||
#include "compositor.h"
|
||||
#include "desktop-shell-server-protocol.h"
|
||||
#include "input-method-server-protocol.h"
|
||||
#include "workspaces-server-protocol.h"
|
||||
#include "../shared/config-parser.h"
|
||||
|
||||
|
@ -65,9 +66,13 @@ struct workspace {
|
|||
};
|
||||
|
||||
struct input_panel_surface {
|
||||
struct wl_resource resource;
|
||||
|
||||
struct desktop_shell *shell;
|
||||
|
||||
struct wl_list link;
|
||||
struct weston_surface *surface;
|
||||
struct wl_listener listener;
|
||||
struct wl_listener surface_destroy_listener;
|
||||
};
|
||||
|
||||
struct desktop_shell {
|
||||
|
@ -3282,59 +3287,129 @@ input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy)
|
|||
}
|
||||
|
||||
static void
|
||||
destroy_input_panel_surface(struct wl_listener *listener,
|
||||
void *data)
|
||||
destroy_input_panel_surface(struct input_panel_surface *input_panel_surface)
|
||||
{
|
||||
struct input_panel_surface *input_panel_surface =
|
||||
container_of(listener, struct input_panel_surface, listener);
|
||||
|
||||
wl_list_remove(&listener->link);
|
||||
wl_list_remove(&input_panel_surface->surface_destroy_listener.link);
|
||||
wl_list_remove(&input_panel_surface->link);
|
||||
|
||||
input_panel_surface->surface->configure = NULL;
|
||||
|
||||
free(input_panel_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
input_panel_set_surface(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
struct wl_resource *surface_resource,
|
||||
struct wl_resource *output_resource)
|
||||
static struct input_panel_surface *
|
||||
get_input_panel_surface(struct weston_surface *surface)
|
||||
{
|
||||
if (surface->configure == input_panel_configure) {
|
||||
return surface->private;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
input_panel_handle_surface_destroy(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct input_panel_surface *ipsurface = container_of(listener,
|
||||
struct input_panel_surface,
|
||||
surface_destroy_listener);
|
||||
|
||||
if (ipsurface->resource.client) {
|
||||
wl_resource_destroy(&ipsurface->resource);
|
||||
} else {
|
||||
wl_signal_emit(&ipsurface->resource.destroy_signal,
|
||||
&ipsurface->resource);
|
||||
destroy_input_panel_surface(ipsurface);
|
||||
}
|
||||
}
|
||||
static struct input_panel_surface *
|
||||
create_input_panel_surface(struct desktop_shell *shell,
|
||||
struct weston_surface *surface)
|
||||
{
|
||||
struct desktop_shell *shell = resource->data;
|
||||
struct weston_surface *surface = surface_resource->data;
|
||||
struct weston_output *output = output_resource->data;
|
||||
struct input_panel_surface *input_panel_surface;
|
||||
|
||||
input_panel_surface = calloc(1, sizeof *input_panel_surface);
|
||||
if (!input_panel_surface)
|
||||
return NULL;
|
||||
|
||||
surface->configure = input_panel_configure;
|
||||
surface->private = shell;
|
||||
surface->output = output;
|
||||
surface->private = input_panel_surface;
|
||||
|
||||
/* Do not do anything when surface is already in the list of
|
||||
* input panel surfaces
|
||||
*/
|
||||
wl_list_for_each(input_panel_surface, &shell->input_panel.surfaces, link) {
|
||||
if (input_panel_surface->surface == surface)
|
||||
return;
|
||||
}
|
||||
|
||||
input_panel_surface = malloc(sizeof *input_panel_surface);
|
||||
if (!input_panel_surface) {
|
||||
wl_resource_post_no_memory(resource);
|
||||
return;
|
||||
}
|
||||
input_panel_surface->shell = shell;
|
||||
|
||||
input_panel_surface->surface = surface;
|
||||
input_panel_surface->listener.notify = destroy_input_panel_surface;
|
||||
|
||||
wl_signal_add(&surface_resource->destroy_signal,
|
||||
&input_panel_surface->listener);
|
||||
wl_signal_init(&input_panel_surface->resource.destroy_signal);
|
||||
input_panel_surface->surface_destroy_listener.notify = input_panel_handle_surface_destroy;
|
||||
wl_signal_add(&surface->surface.resource.destroy_signal,
|
||||
&input_panel_surface->surface_destroy_listener);
|
||||
|
||||
wl_list_init(&input_panel_surface->link);
|
||||
|
||||
return input_panel_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
input_panel_surface_set_toplevel(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t position)
|
||||
{
|
||||
struct input_panel_surface *input_panel_surface = resource->data;
|
||||
struct desktop_shell *shell = input_panel_surface->shell;
|
||||
|
||||
wl_list_insert(&shell->input_panel.surfaces,
|
||||
&input_panel_surface->link);
|
||||
}
|
||||
|
||||
static const struct input_panel_surface_interface input_panel_surface_implementation = {
|
||||
input_panel_surface_set_toplevel
|
||||
};
|
||||
|
||||
static void
|
||||
destroy_input_panel_surface_resource(struct wl_resource *resource)
|
||||
{
|
||||
struct input_panel_surface *ipsurf = resource->data;
|
||||
|
||||
destroy_input_panel_surface(ipsurf);
|
||||
}
|
||||
|
||||
static void
|
||||
input_panel_get_input_panel_surface(struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
uint32_t id,
|
||||
struct wl_resource *surface_resource)
|
||||
{
|
||||
struct weston_surface *surface = surface_resource->data;
|
||||
struct desktop_shell *shell = resource->data;
|
||||
struct input_panel_surface *ipsurf;
|
||||
|
||||
if (get_input_panel_surface(surface)) {
|
||||
wl_resource_post_error(surface_resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"input_panel::get_input_panel_surface already requested");
|
||||
return;
|
||||
}
|
||||
|
||||
ipsurf = create_input_panel_surface(shell, surface);
|
||||
if (!ipsurf) {
|
||||
wl_resource_post_error(surface_resource,
|
||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"surface->configure already set");
|
||||
return;
|
||||
}
|
||||
|
||||
ipsurf->resource.destroy = destroy_input_panel_surface_resource;
|
||||
ipsurf->resource.object.id = id;
|
||||
ipsurf->resource.object.interface = &input_panel_surface_interface;
|
||||
ipsurf->resource.object.implementation =
|
||||
(void (**)(void)) &input_panel_surface_implementation;
|
||||
ipsurf->resource.data = ipsurf;
|
||||
|
||||
wl_client_add_resource(client, &ipsurf->resource);
|
||||
}
|
||||
|
||||
static const struct input_panel_interface input_panel_implementation = {
|
||||
input_panel_set_surface
|
||||
input_panel_get_input_panel_surface
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in New Issue