text: Add support for panels following the cursor
Add input_panel_surface::set_panel to specify input panel surfaces which are overlaying the application and are following the input cursor. Signed-off-by: Jan Arne Petersen <jpetersen@openismus.com>
This commit is contained in:
committed by
Kristian Høgsberg
parent
fe89e713ca
commit
14da96bf81
@@ -210,5 +210,8 @@
|
|||||||
</description>
|
</description>
|
||||||
<arg name="position" type="uint"/>
|
<arg name="position" type="uint"/>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
|
<request name="set_panel">
|
||||||
|
</request>
|
||||||
</interface>
|
</interface>
|
||||||
</protocol>
|
</protocol>
|
||||||
|
|||||||
@@ -3155,6 +3155,7 @@ weston_compositor_init(struct weston_compositor *ec,
|
|||||||
wl_signal_init(&ec->wake_signal);
|
wl_signal_init(&ec->wake_signal);
|
||||||
wl_signal_init(&ec->show_input_panel_signal);
|
wl_signal_init(&ec->show_input_panel_signal);
|
||||||
wl_signal_init(&ec->hide_input_panel_signal);
|
wl_signal_init(&ec->hide_input_panel_signal);
|
||||||
|
wl_signal_init(&ec->update_input_panel_signal);
|
||||||
wl_signal_init(&ec->seat_created_signal);
|
wl_signal_init(&ec->seat_created_signal);
|
||||||
wl_signal_init(&ec->output_created_signal);
|
wl_signal_init(&ec->output_created_signal);
|
||||||
ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
|
ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ struct weston_compositor {
|
|||||||
|
|
||||||
struct wl_signal show_input_panel_signal;
|
struct wl_signal show_input_panel_signal;
|
||||||
struct wl_signal hide_input_panel_signal;
|
struct wl_signal hide_input_panel_signal;
|
||||||
|
struct wl_signal update_input_panel_signal;
|
||||||
|
|
||||||
struct wl_signal seat_created_signal;
|
struct wl_signal seat_created_signal;
|
||||||
struct wl_signal output_created_signal;
|
struct wl_signal output_created_signal;
|
||||||
|
|||||||
+68
-6
@@ -78,6 +78,8 @@ struct input_panel_surface {
|
|||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct weston_surface *surface;
|
struct weston_surface *surface;
|
||||||
struct wl_listener surface_destroy_listener;
|
struct wl_listener surface_destroy_listener;
|
||||||
|
|
||||||
|
uint32_t panel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct desktop_shell {
|
struct desktop_shell {
|
||||||
@@ -88,6 +90,7 @@ struct desktop_shell {
|
|||||||
struct wl_listener destroy_listener;
|
struct wl_listener destroy_listener;
|
||||||
struct wl_listener show_input_panel_listener;
|
struct wl_listener show_input_panel_listener;
|
||||||
struct wl_listener hide_input_panel_listener;
|
struct wl_listener hide_input_panel_listener;
|
||||||
|
struct wl_listener update_input_panel_listener;
|
||||||
|
|
||||||
struct weston_layer fullscreen_layer;
|
struct weston_layer fullscreen_layer;
|
||||||
struct weston_layer panel_layer;
|
struct weston_layer panel_layer;
|
||||||
@@ -111,6 +114,11 @@ struct desktop_shell {
|
|||||||
bool showing_input_panels;
|
bool showing_input_panels;
|
||||||
bool prepare_event_sent;
|
bool prepare_event_sent;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct weston_surface *surface;
|
||||||
|
pixman_box32_t cursor_rectangle;
|
||||||
|
} text_input;
|
||||||
|
|
||||||
struct weston_surface *lock_surface;
|
struct weston_surface *lock_surface;
|
||||||
struct wl_listener lock_surface_listener;
|
struct wl_listener lock_surface_listener;
|
||||||
|
|
||||||
@@ -3034,6 +3042,8 @@ show_input_panels(struct wl_listener *listener, void *data)
|
|||||||
struct input_panel_surface *surface, *next;
|
struct input_panel_surface *surface, *next;
|
||||||
struct weston_surface *ws;
|
struct weston_surface *ws;
|
||||||
|
|
||||||
|
shell->text_input.surface = (struct weston_surface*)data;
|
||||||
|
|
||||||
if (shell->showing_input_panels)
|
if (shell->showing_input_panels)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -3046,6 +3056,9 @@ show_input_panels(struct wl_listener *listener, void *data)
|
|||||||
wl_list_for_each_safe(surface, next,
|
wl_list_for_each_safe(surface, next,
|
||||||
&shell->input_panel.surfaces, link) {
|
&shell->input_panel.surfaces, link) {
|
||||||
ws = surface->surface;
|
ws = surface->surface;
|
||||||
|
if (!weston_surface_is_mapped(ws)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
wl_list_insert(&shell->input_panel_layer.surface_list,
|
wl_list_insert(&shell->input_panel_layer.surface_list,
|
||||||
&ws->layer_link);
|
&ws->layer_link);
|
||||||
weston_surface_geometry_dirty(ws);
|
weston_surface_geometry_dirty(ws);
|
||||||
@@ -3076,6 +3089,16 @@ hide_input_panels(struct wl_listener *listener, void *data)
|
|||||||
weston_surface_unmap(surface);
|
weston_surface_unmap(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_input_panels(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct desktop_shell *shell =
|
||||||
|
container_of(listener, struct desktop_shell,
|
||||||
|
update_input_panel_listener);
|
||||||
|
|
||||||
|
memcpy(&shell->text_input.cursor_rectangle, data, sizeof(pixman_box32_t));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
center_on_output(struct weston_surface *surface, struct weston_output *output)
|
center_on_output(struct weston_surface *surface, struct weston_output *output)
|
||||||
{
|
{
|
||||||
@@ -3490,26 +3513,47 @@ bind_screensaver(struct wl_client *client,
|
|||||||
static void
|
static void
|
||||||
input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
|
input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy, int32_t width, int32_t height)
|
||||||
{
|
{
|
||||||
|
struct input_panel_surface *ip_surface = surface->configure_private;
|
||||||
|
struct desktop_shell *shell = ip_surface->shell;
|
||||||
struct weston_mode *mode;
|
struct weston_mode *mode;
|
||||||
float x, y;
|
float x, y;
|
||||||
|
uint32_t show_surface = 0;
|
||||||
|
|
||||||
if (width == 0)
|
if (width == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!weston_surface_is_mapped(surface))
|
if (!weston_surface_is_mapped(surface)) {
|
||||||
|
if (!shell->showing_input_panels)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wl_list_insert(&shell->input_panel_layer.surface_list,
|
||||||
|
&surface->layer_link);
|
||||||
|
weston_surface_geometry_dirty(surface);
|
||||||
|
weston_surface_update_transform(surface);
|
||||||
|
show_surface = 1;
|
||||||
|
}
|
||||||
|
|
||||||
mode = surface->output->current;
|
mode = surface->output->current;
|
||||||
x = (mode->width - width) / 2;
|
|
||||||
y = mode->height - height;
|
if (ip_surface->panel) {
|
||||||
|
x = shell->text_input.surface->geometry.x + shell->text_input.cursor_rectangle.x2;
|
||||||
|
y = shell->text_input.surface->geometry.y + shell->text_input.cursor_rectangle.y2;
|
||||||
|
} else {
|
||||||
|
x = surface->output->x + (mode->width - width) / 2;
|
||||||
|
y = surface->output->y + mode->height - height;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't map the input panel here, wait for
|
/* Don't map the input panel here, wait for
|
||||||
* show_input_panels signal. */
|
* show_input_panels signal. */
|
||||||
|
|
||||||
weston_surface_configure(surface,
|
weston_surface_configure(surface,
|
||||||
surface->output->x + x,
|
x, y,
|
||||||
surface->output->y + y,
|
|
||||||
width, height);
|
width, height);
|
||||||
|
|
||||||
|
if (show_surface) {
|
||||||
|
weston_surface_damage(surface);
|
||||||
|
weston_slide_run(surface, surface->geometry.height, 0, NULL, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3585,10 +3629,26 @@ input_panel_surface_set_toplevel(struct wl_client *client,
|
|||||||
|
|
||||||
wl_list_insert(&shell->input_panel.surfaces,
|
wl_list_insert(&shell->input_panel.surfaces,
|
||||||
&input_panel_surface->link);
|
&input_panel_surface->link);
|
||||||
|
|
||||||
|
input_panel_surface->panel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_panel_surface_set_panel(struct wl_client *client,
|
||||||
|
struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
input_panel_surface->panel = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct input_panel_surface_interface input_panel_surface_implementation = {
|
static const struct input_panel_surface_interface input_panel_surface_implementation = {
|
||||||
input_panel_surface_set_toplevel
|
input_panel_surface_set_toplevel,
|
||||||
|
input_panel_surface_set_panel
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -4197,6 +4257,8 @@ module_init(struct weston_compositor *ec,
|
|||||||
wl_signal_add(&ec->show_input_panel_signal, &shell->show_input_panel_listener);
|
wl_signal_add(&ec->show_input_panel_signal, &shell->show_input_panel_listener);
|
||||||
shell->hide_input_panel_listener.notify = hide_input_panels;
|
shell->hide_input_panel_listener.notify = hide_input_panels;
|
||||||
wl_signal_add(&ec->hide_input_panel_signal, &shell->hide_input_panel_listener);
|
wl_signal_add(&ec->hide_input_panel_signal, &shell->hide_input_panel_listener);
|
||||||
|
shell->update_input_panel_listener.notify = update_input_panels;
|
||||||
|
wl_signal_add(&ec->update_input_panel_signal, &shell->update_input_panel_listener);
|
||||||
ec->ping_handler = ping_handler;
|
ec->ping_handler = ping_handler;
|
||||||
ec->shell_interface.shell = shell;
|
ec->shell_interface.shell = shell;
|
||||||
ec->shell_interface.create_shell_surface = create_shell_surface;
|
ec->shell_interface.create_shell_surface = create_shell_surface;
|
||||||
|
|||||||
+19
-4
@@ -41,6 +41,8 @@ struct text_input {
|
|||||||
|
|
||||||
struct wl_surface *surface;
|
struct wl_surface *surface;
|
||||||
|
|
||||||
|
pixman_box32_t cursor_rectangle;
|
||||||
|
|
||||||
uint32_t input_panel_visible;
|
uint32_t input_panel_visible;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -185,8 +187,10 @@ text_input_activate(struct wl_client *client,
|
|||||||
|
|
||||||
input_method_context_create(text_input, input_method, serial);
|
input_method_context_create(text_input, input_method, serial);
|
||||||
|
|
||||||
if (text_input->input_panel_visible)
|
if (text_input->input_panel_visible) {
|
||||||
wl_signal_emit(&ec->show_input_panel_signal, ec);
|
wl_signal_emit(&ec->show_input_panel_signal, text_input->surface);
|
||||||
|
wl_signal_emit(&ec->update_input_panel_signal, &text_input->cursor_rectangle);
|
||||||
|
}
|
||||||
|
|
||||||
text_input_send_enter(&text_input->resource, &text_input->surface->resource);
|
text_input_send_enter(&text_input->resource, &text_input->surface->resource);
|
||||||
}
|
}
|
||||||
@@ -226,6 +230,15 @@ text_input_set_cursor_rectangle(struct wl_client *client,
|
|||||||
int32_t width,
|
int32_t width,
|
||||||
int32_t height)
|
int32_t height)
|
||||||
{
|
{
|
||||||
|
struct text_input *text_input = resource->data;
|
||||||
|
struct weston_compositor *ec = text_input->ec;
|
||||||
|
|
||||||
|
text_input->cursor_rectangle.x1 = x;
|
||||||
|
text_input->cursor_rectangle.y1 = y;
|
||||||
|
text_input->cursor_rectangle.x2 = x + width;
|
||||||
|
text_input->cursor_rectangle.y2 = y + height;
|
||||||
|
|
||||||
|
wl_signal_emit(&ec->update_input_panel_signal, &text_input->cursor_rectangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -283,8 +296,10 @@ text_input_show_input_panel(struct wl_client *client,
|
|||||||
|
|
||||||
text_input->input_panel_visible = 1;
|
text_input->input_panel_visible = 1;
|
||||||
|
|
||||||
if (!wl_list_empty(&text_input->input_methods))
|
if (!wl_list_empty(&text_input->input_methods)) {
|
||||||
wl_signal_emit(&ec->show_input_panel_signal, ec);
|
wl_signal_emit(&ec->show_input_panel_signal, text_input->surface);
|
||||||
|
wl_signal_emit(&ec->update_input_panel_signal, &text_input->cursor_rectangle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
Reference in New Issue
Block a user