clients: support ivi-application.xml for clients/window.c
[profile/ivi/weston-ivi-shell.git] / xwayland / window-manager.c
index 7a042e5..4e91f9d 100644 (file)
@@ -681,6 +681,8 @@ weston_wm_create_surface(struct wl_listener *listener, void *data)
                if (window->surface_id ==
                    wl_resource_get_id(surface->resource)) {
                        xserver_map_shell_surface(window, surface);
+                       window->surface_id = 0;
+                       wl_list_remove(&window->link);
                        break;
                }       
 }
@@ -699,6 +701,9 @@ weston_wm_window_activate(struct wl_listener *listener, void *data)
        }
 
        if (window) {
+               if (window->override_redirect)
+                       return;
+
                client_message.response_type = XCB_CLIENT_MESSAGE;
                client_message.format = 32;
                client_message.window = window->id;
@@ -942,7 +947,8 @@ weston_wm_window_draw_decoration(void *data)
        cairo_t *cr;
        int x, y, width, height;
        int32_t input_x, input_y, input_w, input_h;
-
+       struct weston_shell_interface *shell_interface =
+               &wm->server->compositor->shell_interface;
        uint32_t flags = 0;
 
        weston_wm_window_read_properties(window);
@@ -1004,6 +1010,9 @@ weston_wm_window_draw_decoration(void *data)
 
                pixman_region32_init_rect(&window->surface->pending.input,
                                          input_x, input_y, input_w, input_h);
+
+               shell_interface->set_window_geometry(window->shsurf,
+                                                    input_x, input_y, input_w, input_h);
        }
 }
 
@@ -1120,6 +1129,9 @@ weston_wm_window_destroy(struct weston_wm_window *window)
                window->frame_id = XCB_WINDOW_NONE;
        }
 
+       if (window->surface_id)
+               wl_list_remove(&window->link);
+
        hash_table_remove(window->wm->window_hash, window->id);
        free(window);
 }
@@ -1194,6 +1206,26 @@ weston_wm_pick_seat(struct weston_wm *wm)
                            struct weston_seat, link);
 }
 
+static struct weston_seat *
+weston_wm_pick_seat_for_window(struct weston_wm_window *window)
+{
+       struct weston_wm *wm = window->wm;
+       struct weston_seat *seat, *s;
+
+       seat = NULL;
+       wl_list_for_each(s, &wm->server->compositor->seat_list, link) {
+               if (s->pointer != NULL &&
+                   s->pointer->focus == window->view &&
+                   s->pointer->button_count > 0 &&
+                   (seat == NULL ||
+                    s->pointer->grab_serial -
+                    seat->pointer->grab_serial < (1 << 30)))
+                       seat = s;
+       }
+
+       return seat;
+}
+
 static void
 weston_wm_window_handle_moveresize(struct weston_wm_window *window,
                                   xcb_client_message_event_t *client_message)
@@ -1210,13 +1242,13 @@ weston_wm_window_handle_moveresize(struct weston_wm_window *window,
        };
 
        struct weston_wm *wm = window->wm;
-       struct weston_seat *seat = weston_wm_pick_seat(wm);
+       struct weston_seat *seat = weston_wm_pick_seat_for_window(window);
        int detail;
        struct weston_shell_interface *shell_interface =
                &wm->server->compositor->shell_interface;
 
-       if (seat->pointer->button_count != 1 || !window->view
-           || seat->pointer->focus != window->view)
+       if (seat == NULL || seat->pointer->button_count != 1
+           || !window->view || seat->pointer->focus != window->view)
                return;
 
        detail = client_message->data.data32[2];
@@ -1342,14 +1374,17 @@ weston_wm_window_handle_surface_id(struct weston_wm_window *window,
         * hasn't been created yet.  In that case put the window on
         * the unpaired window list and continue when the surface gets
         * created. */
-       window->surface_id = client_message->data.data32[0];
-       resource = wl_client_get_object(wm->server->client,
-                                       window->surface_id);
-       if (resource)
+       uint32_t id = client_message->data.data32[0];
+       resource = wl_client_get_object(wm->server->client, id);
+       if (resource) {
+               window->surface_id = 0;
                xserver_map_shell_surface(window,
                                          wl_resource_get_user_data(resource));
-       else
+       }
+       else {
+               window->surface_id = id;
                wl_list_insert(&wm->unpaired_window_list, &window->link);
+       }
 }
 
 static void
@@ -1371,6 +1406,12 @@ weston_wm_handle_client_message(struct weston_wm *wm,
               client_message->data.data32[4],
               client_message->window);
 
+       /* The window may get created and destroyed before we actually
+        * handle the message.  If it doesn't exist, bail.
+        */
+       if (!window)
+               return;
+
        if (client_message->type == wm->atom.net_wm_moveresize)
                weston_wm_window_handle_moveresize(window, client_message);
        else if (client_message->type == wm->atom.net_wm_state)
@@ -1574,7 +1615,7 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
        xcb_button_press_event_t *button = (xcb_button_press_event_t *) event;
        struct weston_shell_interface *shell_interface =
                &wm->server->compositor->shell_interface;
-       struct weston_seat *seat = weston_wm_pick_seat(wm);
+       struct weston_seat *seat;
        struct weston_wm_window *window;
        enum theme_location location;
        enum frame_button_state button_state;
@@ -1591,22 +1632,33 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
        if (button->detail != 1 && button->detail != 2)
                return;
 
+       seat = weston_wm_pick_seat_for_window(window);
+
        button_state = button->response_type == XCB_BUTTON_PRESS ?
                FRAME_BUTTON_PRESSED : FRAME_BUTTON_RELEASED;
        button_id = button->detail == 1 ? BTN_LEFT : BTN_RIGHT;
 
+       /* Make sure we're looking at the right location.  The frame
+        * could have received a motion event from a pointer from a
+        * different wl_seat, but under X it looks like our core
+        * pointer moved.  Move the frame pointer to the button press
+        * location before deciding what to do. */
+       location = frame_pointer_motion(window->frame, NULL,
+                                       button->event_x, button->event_y);
        location = frame_pointer_button(window->frame, NULL,
                                        button_id, button_state);
        if (frame_status(window->frame) & FRAME_STATUS_REPAINT)
                weston_wm_window_schedule_repaint(window);
 
        if (frame_status(window->frame) & FRAME_STATUS_MOVE) {
-               shell_interface->move(window->shsurf, seat);
+               if (seat != NULL)
+                       shell_interface->move(window->shsurf, seat);
                frame_status_clear(window->frame, FRAME_STATUS_MOVE);
        }
 
        if (frame_status(window->frame) & FRAME_STATUS_RESIZE) {
-               shell_interface->resize(window->shsurf, seat, location);
+               if (seat != NULL)
+                       shell_interface->resize(window->shsurf, seat, location);
                frame_status_clear(window->frame, FRAME_STATUS_RESIZE);
        }
 
@@ -2134,23 +2186,19 @@ weston_wm_window_configure(void *data)
 }
 
 static void
-send_configure(struct weston_surface *surface,
-              uint32_t edges, int32_t width, int32_t height)
+send_configure(struct weston_surface *surface, int32_t width, int32_t height)
 {
        struct weston_wm_window *window = get_wm_window(surface);
        struct weston_wm *wm = window->wm;
        struct theme *t = window->wm->theme;
        int vborder, hborder;
 
-       if (window->fullscreen) {
+       if (window->decorate) {
+               hborder = 2 * t->width;
+               vborder = t->titlebar_height + t->width;
+       } else {
                hborder = 0;
                vborder = 0;
-       } else if (window->decorate) {
-               hborder = 2 * (t->margin + t->width);
-               vborder = 2 * t->margin + t->titlebar_height + t->width;
-       } else {
-               hborder = 2 * t->margin;
-               vborder = 2 * t->margin;
        }
 
        if (width > hborder)