<br><div class="gmail_quote">On Fri Dec 05 2014 at 10:47:05 PM Derek Foreman <<a href="mailto:derekf@osg.samsung.com">derekf@osg.samsung.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Multi-seat configurations currently break the text-backend, crashing<br>
weston. This is an attempt to clean up any crashes and have somewhat<br>
sensible input panel behavior with multi-seat.<br>
<br>
Signed-off-by: Derek Foreman <<a href="mailto:derekf@osg.samsung.com" target="_blank">derekf@osg.samsung.com</a>><br>
---<br>
src/text-backend.c | 76 ++++++++++++++++++++++++++++++<u></u>++++--------------------<br>
1 file changed, 48 insertions(+), 28 deletions(-)<br>
<br>
diff --git a/src/text-backend.c b/src/text-backend.c<br>
index b8b526e..46113e3 100644<br>
--- a/src/text-backend.c<br>
+++ b/src/text-backend.c<br>
@@ -33,6 +33,7 @@<br>
#include "text-server-protocol.h"<br>
#include "input-method-server-protocol.<u></u>h"<br>
<br>
+struct text_input_manager;<br>
struct input_method;<br>
struct input_method_context;<br>
struct text_backend;<br>
@@ -49,12 +50,16 @@ struct text_input {<br>
pixman_box32_t cursor_rectangle;<br>
<br>
bool input_panel_visible;<br>
+<br>
+ struct text_input_manager *manager;<br>
};<br>
<br>
struct text_input_manager {<br>
struct wl_global *text_input_manager_global;<br>
struct wl_listener destroy_listener;<br>
<br>
+ struct text_input *current_panel;<br>
+<br>
struct weston_compositor *ec;<br>
};<br>
<br>
@@ -113,25 +118,28 @@ static void<br>
input_method_init_seat(struct weston_seat *seat);<br>
<br>
static void<br>
-deactivate_text_input(struct text_input *text_input,<br>
- struct input_method *input_method)<br>
+deactivate_input_method(<u></u>struct input_method *input_method)<br>
{<br>
+ struct text_input *text_input = input_method->model;<br>
struct weston_compositor *ec = text_input->ec;<br>
<br>
- if (input_method->model == text_input) {<br>
- if (input_method->context && input_method->input_method_<u></u>binding) {<br>
- input_method_context_end_<u></u>keyboard_grab(input_method-><u></u>context);<br>
- wl_input_method_send_<u></u>deactivate(input_method-><u></u>input_method_binding,<br>
- input_method->context-><u></u>resource);<br>
- input_method->context->model = NULL;<br>
- }<br>
-<br>
- wl_list_remove(&input_method-><u></u>link);<br>
- input_method->model = NULL;<br>
- input_method->context = NULL;<br>
+ if (input_method->context && input_method->input_method_<u></u>binding) {<br>
+ input_method_context_end_<u></u>keyboard_grab(input_method-><u></u>context);<br>
+ wl_input_method_send_<u></u>deactivate(input_method-><u></u>input_method_binding,<br>
+ input_method->context-><u></u>resource);<br>
+ }<br>
+<br>
+ wl_list_remove(&input_method-><u></u>link);<br>
+ input_method->model = NULL;<br>
+ input_method->context = NULL;<br>
+<br>
+ if (wl_list_empty(&text_input-><u></u>input_methods) &&<br>
+ text_input->input_panel_<u></u>visible) {<br>
wl_signal_emit(&ec->hide_<u></u>input_panel_signal, ec);<br>
- wl_text_input_send_leave(text_<u></u>input->resource);<br>
+ text_input->input_panel_<u></u>visible = false;<br>
+ text_input->manager->current_<u></u>panel = NULL;<br>
}<br>
+ wl_text_input_send_leave(text_<u></u>input->resource);<br>
}<br>
<br>
static void<br>
@@ -141,7 +149,7 @@ destroy_text_input(struct wl_resource *resource)<br>
struct input_method *input_method, *next;<br>
<br>
wl_list_for_each_safe(input_<u></u>method, next, &text_input->input_methods, link)<br>
- deactivate_text_input(text_<u></u>input, input_method);<br>
+ deactivate_input_method(input_<u></u>method);<br>
<br>
free(text_input);<br>
}<br>
@@ -175,16 +183,14 @@ text_input_activate(struct wl_client *client,<br>
struct text_input *text_input = wl_resource_get_user_data(<u></u>resource);<br>
struct weston_seat *weston_seat = wl_resource_get_user_data(<u></u>seat);<br>
struct input_method *input_method = weston_seat->input_method;<br>
- struct text_input *old = weston_seat->input_method-><u></u>model;<br>
struct weston_compositor *ec = text_input->ec;<br>
+ struct text_input *current;<br>
<br>
- if (old == text_input)<br>
+ if (input_method->model == text_input)<br>
return;<br>
<br>
- if (old) {<br>
- deactivate_text_input(old,<br>
- weston_seat->input_method);<br>
- }<br>
+ if (input_method->model)<br>
+ deactivate_input_method(input_<u></u>method);<br>
<br>
input_method->model = text_input;<br>
wl_list_insert(&text_input-><u></u>input_methods, &input_method->link);<br>
@@ -194,9 +200,18 @@ text_input_activate(struct wl_client *client,<br>
<br>
input_method_context_create(<u></u>text_input, input_method);<br>
<br>
+ current = text_input->manager->current_<u></u>panel;<br>
+<br>
+ if (current && current != text_input) {<br>
+ current->input_panel_visible = false;<br>
+ wl_signal_emit(&ec->hide_<u></u>input_panel_signal, ec);<br>
+ text_input->manager->current_<u></u>panel = NULL;<br>
+ }<br>
+<br>
if (text_input->input_panel_<u></u>visible) {<br>
wl_signal_emit(&ec->show_<u></u>input_panel_signal, text_input->surface);<br>
wl_signal_emit(&ec->update_<u></u>input_panel_signal, &text_input->cursor_rectangle)<u></u>;<br>
+ text_input->manager->current_<u></u>panel = text_input;<br>
}<br>
<br>
wl_text_input_send_enter(text_<u></u>input->resource, text_input->surface->resource)<u></u>;<br>
@@ -207,11 +222,10 @@ text_input_deactivate(struct wl_client *client,<br>
struct wl_resource *resource,<br>
struct wl_resource *seat)<br>
{<br>
- struct text_input *text_input = wl_resource_get_user_data(<u></u>resource);<br>
struct weston_seat *weston_seat = wl_resource_get_user_data(<u></u>seat);<br>
<br>
- deactivate_text_input(text_<u></u>input,<br>
- weston_seat->input_method);<br>
+ if (weston_seat->input_method-><u></u>model)<br>
+ deactivate_input_method(<u></u>weston_seat->input_method);<br>
}<br>
<br>
static void<br>
@@ -318,8 +332,11 @@ text_input_hide_input_panel(<u></u>struct wl_client *client,<br>
<br>
text_input->input_panel_<u></u>visible = false;<br>
<br>
- if (!wl_list_empty(&text_input-><u></u>input_methods))<br>
+ if (!wl_list_empty(&text_input-><u></u>input_methods) &&<br>
+ text_input == text_input->manager->current_<u></u>panel) {<br>
+ text_input->manager->current_<u></u>panel = NULL;<br>
wl_signal_emit(&ec->hide_<u></u>input_panel_signal, ec);<br>
+ }<br>
}<br>
<br>
static void<br>
@@ -370,6 +387,7 @@ static void text_input_manager_create_<u></u>text_input(struct wl_client *client,<br>
text_input, destroy_text_input);<br>
<br>
text_input->ec = text_input_manager->ec;<br>
+ text_input->manager = text_input_manager;<br>
<br>
wl_list_init(&text_input-><u></u>input_methods);<br>
};<br>
@@ -719,6 +737,9 @@ destroy_input_method_context(<u></u>struct wl_resource *resource)<br>
wl_resource_destroy(context-><u></u>keyboard);<br>
}<br>
<br>
+ if (context->input_method && context->input_method->context == context)<br>
+ context->input_method->context = NULL;<br>
+<br>
free(context);<br>
}<br>
<br>
@@ -823,7 +844,7 @@ input_method_notifier_destroy(<u></u>struct wl_listener *listener, void *data)<br>
container_of(listener, struct input_method, destroy_listener);<br>
<br>
if (input_method->model)<br>
- deactivate_text_input(input_<u></u>method->model, input_method);<br>
+ deactivate_input_method(input_<u></u>method);<br>
<br>
wl_global_destroy(input_<u></u>method->input_method_global);<br>
wl_list_remove(&input_method-><u></u>destroy_listener.link);<br>
@@ -843,8 +864,7 @@ handle_keyboard_focus(struct wl_listener *listener, void *data)<br>
return;<br>
<br>
if (!surface || input_method->model->surface != surface)<br>
- deactivate_text_input(input_<u></u>method->model,<br>
- input_method);<br>
+ deactivate_input_method(input_<u></u>method);<br>
}<br>
<br>
static void<br>
--<br>
2.1.3<br></blockquote><div><br></div><div>Looks good.</div><div><br></div><div>Regards</div><div>Jan Arne </div></div>