From: Jan Arne Petersen Date: Thu, 18 Apr 2013 14:47:28 +0000 (+0200) Subject: text: Add support for panels following the cursor X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=14da96bf81b5fdf720698b633de2a742c4f644dd;p=platform%2Fupstream%2Fweston.git 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 --- diff --git a/protocol/input-method.xml b/protocol/input-method.xml index 3fc468c..8a4ea7f 100644 --- a/protocol/input-method.xml +++ b/protocol/input-method.xml @@ -210,5 +210,8 @@ + + + diff --git a/src/compositor.c b/src/compositor.c index a6610e6..fc69ee2 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -3155,6 +3155,7 @@ weston_compositor_init(struct weston_compositor *ec, wl_signal_init(&ec->wake_signal); wl_signal_init(&ec->show_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->output_created_signal); ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK"); diff --git a/src/compositor.h b/src/compositor.h index 7da6c48..93a82b2 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -319,6 +319,7 @@ struct weston_compositor { struct wl_signal show_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 output_created_signal; diff --git a/src/shell.c b/src/shell.c index 9d0ae02..281e2f5 100644 --- a/src/shell.c +++ b/src/shell.c @@ -78,6 +78,8 @@ struct input_panel_surface { struct wl_list link; struct weston_surface *surface; struct wl_listener surface_destroy_listener; + + uint32_t panel; }; struct desktop_shell { @@ -88,6 +90,7 @@ struct desktop_shell { struct wl_listener destroy_listener; struct wl_listener show_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 panel_layer; @@ -111,6 +114,11 @@ struct desktop_shell { bool showing_input_panels; bool prepare_event_sent; + struct { + struct weston_surface *surface; + pixman_box32_t cursor_rectangle; + } text_input; + struct weston_surface *lock_surface; 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 weston_surface *ws; + shell->text_input.surface = (struct weston_surface*)data; + if (shell->showing_input_panels) return; @@ -3046,6 +3056,9 @@ show_input_panels(struct wl_listener *listener, void *data) wl_list_for_each_safe(surface, next, &shell->input_panel.surfaces, link) { ws = surface->surface; + if (!weston_surface_is_mapped(ws)) { + continue; + } wl_list_insert(&shell->input_panel_layer.surface_list, &ws->layer_link); weston_surface_geometry_dirty(ws); @@ -3077,6 +3090,16 @@ hide_input_panels(struct wl_listener *listener, void *data) } 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 center_on_output(struct weston_surface *surface, struct weston_output *output) { int32_t width = weston_surface_buffer_width(surface); @@ -3490,26 +3513,47 @@ bind_screensaver(struct wl_client *client, static void 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; float x, y; + uint32_t show_surface = 0; if (width == 0) return; - if (!weston_surface_is_mapped(surface)) - return; + if (!weston_surface_is_mapped(surface)) { + if (!shell->showing_input_panels) + 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; - 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 * show_input_panels signal. */ weston_surface_configure(surface, - surface->output->x + x, - surface->output->y + y, + x, y, width, height); + + if (show_surface) { + weston_surface_damage(surface); + weston_slide_run(surface, surface->geometry.height, 0, NULL, NULL); + } } static void @@ -3585,10 +3629,26 @@ input_panel_surface_set_toplevel(struct wl_client *client, wl_list_insert(&shell->input_panel.surfaces, &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 = { - input_panel_surface_set_toplevel + input_panel_surface_set_toplevel, + input_panel_surface_set_panel }; 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); shell->hide_input_panel_listener.notify = hide_input_panels; 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->shell_interface.shell = shell; ec->shell_interface.create_shell_surface = create_shell_surface; diff --git a/src/text-backend.c b/src/text-backend.c index 13fff24..07a066c 100644 --- a/src/text-backend.c +++ b/src/text-backend.c @@ -41,6 +41,8 @@ struct text_input { struct wl_surface *surface; + pixman_box32_t cursor_rectangle; + 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); - if (text_input->input_panel_visible) - wl_signal_emit(&ec->show_input_panel_signal, ec); + if (text_input->input_panel_visible) { + 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); } @@ -226,6 +230,15 @@ text_input_set_cursor_rectangle(struct wl_client *client, int32_t width, 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 @@ -283,8 +296,10 @@ text_input_show_input_panel(struct wl_client *client, text_input->input_panel_visible = 1; - if (!wl_list_empty(&text_input->input_methods)) - wl_signal_emit(&ec->show_input_panel_signal, ec); + if (!wl_list_empty(&text_input->input_methods)) { + 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