Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/display/window.c

    r90f1f19 r0d00e53  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4444#include <memgfx/memgc.h>
    4545#include <stdlib.h>
     46#include <str.h>
     47#include <wndmgt.h>
    4648#include "client.h"
    4749#include "display.h"
    4850#include "seat.h"
    4951#include "window.h"
     52#include "wmclient.h"
    5053
    5154static void ds_window_invalidate_cb(void *, gfx_rect_t *);
     
    5356static void ds_window_get_preview_rect(ds_window_t *, gfx_rect_t *);
    5457
     58static mem_gc_cb_t ds_window_mem_gc_cb = {
     59        .invalidate = ds_window_invalidate_cb,
     60        .update = ds_window_update_cb
     61};
     62
    5563/** Create window.
    5664 *
     
    5967 * @param client Client owning the window
    6068 * @param params Window parameters
    61  * @param rgc Place to store pointer to new GC.
     69 * @param rwnd Place to store pointer to new window.
    6270 *
    6371 * @return EOK on success or an error code
    6472 */
    6573errno_t ds_window_create(ds_client_t *client, display_wnd_params_t *params,
    66     ds_window_t **rgc)
     74    ds_window_t **rwnd)
    6775{
    6876        ds_window_t *wnd = NULL;
     
    8088        }
    8189
     90        /* Caption */
     91        wnd->caption = str_dup(params->caption);
     92        if (wnd->caption == NULL) {
     93                rc = ENOMEM;
     94                goto error;
     95        }
     96
     97        wnd->flags = params->flags;
     98
    8299        ds_client_add_window(client, wnd);
    83100        ds_display_add_window(client->display, wnd);
     
    85102        gfx_bitmap_params_init(&bparams);
    86103        bparams.rect = params->rect;
     104
     105        /* Allocate window bitmap */
    87106
    88107        dgc = ds_display_get_gc(wnd->display);
     
    108127        }
    109128
    110         rc = mem_gc_create(&params->rect, &alloc, ds_window_invalidate_cb,
    111             ds_window_update_cb, (void *)wnd, &wnd->mgc);
     129        rc = mem_gc_create(&params->rect, &alloc, &ds_window_mem_gc_cb,
     130            (void *)wnd, &wnd->mgc);
    112131        if (rc != EOK)
    113132                goto error;
     
    117136        wnd->gc = mem_gc_get_ctx(wnd->mgc);
    118137        wnd->cursor = wnd->display->cursor[dcurs_arrow];
    119         wnd->flags = params->flags;
    120138
    121139        if ((params->flags & wndf_setpos) != 0) {
     
    128146        }
    129147
    130         seat = ds_display_first_seat(client->display);
    131 
    132         if ((params->flags & wndf_popup) != 0)
     148        /* Determine which seat should own the window */
     149        if (params->idev_id != 0)
     150                seat = ds_display_seat_by_idev(wnd->display, params->idev_id);
     151        else
     152                seat = ds_display_default_seat(wnd->display);
     153
     154        /* Is this a popup window? */
     155        if ((params->flags & wndf_popup) != 0) {
    133156                ds_seat_set_popup(seat, wnd);
    134         else
    135                 ds_seat_set_focus(seat, wnd);
     157        } else {
     158                if ((params->flags & wndf_nofocus) == 0)
     159                        ds_seat_set_focus(seat, wnd);
     160        }
     161
     162        /* Is this window a panel? */
     163        if ((params->flags & wndf_avoid) != 0)
     164                ds_display_update_max_rect(wnd->display);
    136165
    137166        (void) ds_display_paint(wnd->display, NULL);
    138167
    139         *rgc = wnd;
     168        *rwnd = wnd;
    140169        return EOK;
    141170error:
    142171        if (wnd != NULL) {
     172                ds_client_remove_window(wnd);
     173                ds_display_remove_window(wnd);
     174                if (wnd->mgc != NULL)
     175                        mem_gc_delete(wnd->mgc);
    143176                if (wnd->bitmap != NULL)
    144177                        gfx_bitmap_destroy(wnd->bitmap);
     178                if (wnd->caption != NULL)
     179                        free(wnd->caption);
    145180                free(wnd);
    146181        }
     
    158193
    159194        disp = wnd->display;
     195
     196        ds_window_unfocus(wnd);
    160197
    161198        ds_client_remove_window(wnd);
    162199        ds_display_remove_window(wnd);
    163200
     201        if ((wnd->flags & wndf_avoid) != 0)
     202                ds_display_update_max_rect(disp);
     203
    164204        mem_gc_delete(wnd->mgc);
    165205
     
    167207                gfx_bitmap_destroy(wnd->bitmap);
    168208
     209        free(wnd->caption);
    169210        free(wnd);
    170211
     
    178219void ds_window_bring_to_top(ds_window_t *wnd)
    179220{
    180         ds_display_t *disp = wnd->display;
    181 
    182         ds_display_remove_window(wnd);
    183         ds_display_add_window(disp, wnd);
     221        ds_display_window_to_top(wnd);
    184222        (void) ds_display_paint(wnd->display, NULL);
    185223}
     
    193231{
    194232        return wnd->gc;
     233}
     234
     235/** Determine if window is visible.
     236 *
     237 * @param wnd Window
     238 * @return @c true iff window is visible
     239 */
     240bool ds_window_is_visible(ds_window_t *wnd)
     241{
     242        return (wnd->flags & wndf_minimized) == 0;
    195243}
    196244
     
    207255        gfx_rect_t crect;
    208256
    209         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_paint");
     257        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_paint");
     258
     259        /* Skip painting the window if not visible */
     260        if (!ds_window_is_visible(wnd))
     261                return EOK;
    210262
    211263        if (rect != NULL) {
     
    352404        bool newr;
    353405
    354         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_repaint_preview");
     406        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_repaint_preview");
    355407
    356408        /*
     
    396448 * @param wnd Window
    397449 * @param pos Position where mouse button was pressed
    398  */
    399 static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos)
     450 * @param pos_id Positioning device ID
     451 */
     452static void ds_window_start_move(ds_window_t *wnd, gfx_coord2_t *pos,
     453    sysarg_t pos_id)
    400454{
    401455        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_start_move (%d, %d)",
     
    406460
    407461        wnd->orig_pos = *pos;
     462        wnd->orig_pos_id = pos_id;
    408463        wnd->state = dsw_moving;
    409464        wnd->preview_pos = wnd->dpos;
     
    435490        wnd->dpos = nwpos;
    436491        wnd->state = dsw_idle;
     492        wnd->orig_pos_id = 0;
    437493
    438494        (void) ds_display_paint(wnd->display, NULL);
     
    450506        gfx_rect_t old_rect;
    451507
    452         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_move (%d, %d)",
     508        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_update_move (%d, %d)",
    453509            (int) pos->x, (int) pos->y);
    454510
     
    469525 * @param rsztype Resize type (which part of window is being dragged)
    470526 * @param pos Position where mouse button was pressed
     527 * @param pos_id Positioning device ID
    471528 */
    472529static void ds_window_start_resize(ds_window_t *wnd,
    473     display_wnd_rsztype_t rsztype, gfx_coord2_t *pos)
     530    display_wnd_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
    474531{
    475532        ds_seat_t *seat;
     
    482539                return;
    483540
     541        /* Determine which seat started the resize */
     542        seat = ds_display_seat_by_idev(wnd->display, pos_id);
     543        if (seat == NULL)
     544                return;
     545
    484546        wnd->orig_pos = *pos;
     547        wnd->orig_pos_id = pos_id;
    485548        wnd->state = dsw_resizing;
    486549        wnd->rsztype = rsztype;
    487550        wnd->preview_rect = wnd->rect;
    488551
    489         // XXX Need client to tell us which seat started the resize!
    490         seat = ds_display_first_seat(wnd->display);
    491552        ctype = display_cursor_from_wrsz(rsztype);
    492553        ds_seat_set_wm_cursor(seat, wnd->display->cursor[ctype]);
     
    518579        ds_client_post_resize_event(wnd->client, wnd, &nrect);
    519580
    520         // XXX Need to know which seat started the resize!
    521         seat = ds_display_first_seat(wnd->display);
    522         ds_seat_set_wm_cursor(seat, NULL);
     581        /* Determine which seat started the resize */
     582        seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id);
     583        if (seat != NULL)
     584                ds_seat_set_wm_cursor(seat, NULL);
     585
     586        wnd->orig_pos_id = 0;
    523587
    524588        (void) ds_display_paint(wnd->display, NULL);
     
    536600        gfx_rect_t old_rect;
    537601
    538         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_update_resize (%d, %d)",
     602        log_msg(LOG_DEFAULT, LVL_DEBUG2, "ds_window_update_resize (%d, %d)",
    539603            (int) pos->x, (int) pos->y);
    540604
     
    575639 * @param wnd Window
    576640 * @param event Position event
     641 *
     642 * @return EOK on success or an error code
    577643 */
    578644errno_t ds_window_post_pos_event(ds_window_t *wnd, pos_event_t *event)
     
    580646        pos_event_t tevent;
    581647        gfx_coord2_t pos;
     648        sysarg_t pos_id;
    582649        gfx_rect_t drect;
    583650        bool inside;
    584651
    585         log_msg(LOG_DEFAULT, LVL_DEBUG,
     652        log_msg(LOG_DEFAULT, LVL_DEBUG2,
    586653            "ds_window_post_pos_event type=%d pos=%d,%d", event->type,
    587654            (int) event->hpos, (int) event->vpos);
     
    589656        pos.x = event->hpos;
    590657        pos.y = event->vpos;
     658        pos_id = event->pos_id;
    591659        gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    592660        inside = gfx_pix_inside_rect(&pos, &drect);
    593661
    594         if (event->type == POS_PRESS && event->btn_num == 2 && inside) {
    595                 ds_window_start_move(wnd, &pos);
     662        if (event->type == POS_PRESS && event->btn_num == 2 && inside &&
     663            (wnd->flags & wndf_maximized) == 0) {
     664                ds_window_start_move(wnd, &pos, pos_id);
    596665                return EOK;
    597666        }
    598667
    599668        if (event->type == POS_RELEASE) {
    600                 if (wnd->state == dsw_moving) {
     669                /* Finish move/resize if they were started by the same seat */
     670                if (wnd->state == dsw_moving &&
     671                    ds_window_orig_seat(wnd, pos_id)) {
    601672                        ds_window_finish_move(wnd, &pos);
    602673                        return EOK;
    603674                }
    604675
    605                 if (wnd->state == dsw_resizing) {
     676                if (wnd->state == dsw_resizing &&
     677                    ds_window_orig_seat(wnd, pos_id)) {
    606678                        ds_window_finish_resize(wnd, &pos);
    607679                        return EOK;
     
    610682
    611683        if (event->type == POS_UPDATE) {
    612                 if (wnd->state == dsw_moving) {
     684                /* Update move/resize if they were started by the same seat */
     685                if (wnd->state == dsw_moving &&
     686                    ds_window_orig_seat(wnd, pos_id)) {
    613687                        ds_window_update_move(wnd, &pos);
    614688                        return EOK;
    615689                }
    616690
    617                 if (wnd->state == dsw_resizing) {
     691                if (wnd->state == dsw_resizing &&
     692                    ds_window_orig_seat(wnd, pos_id)) {
    618693                        ds_window_update_resize(wnd, &pos);
    619694                        return EOK;
     
    632707 *
    633708 * @param wnd Window
     709 * @return EOK on success or an error code
    634710 */
    635711errno_t ds_window_post_focus_event(ds_window_t *wnd)
    636712{
     713        display_wnd_focus_ev_t efocus;
     714        errno_t rc;
     715        ds_wmclient_t *wmclient;
     716
    637717        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_focus_event");
    638718
    639         return ds_client_post_focus_event(wnd->client, wnd);
     719        /* Increase focus counter */
     720        ++wnd->nfocus;
     721        efocus.nfocus = wnd->nfocus;
     722
     723        rc = ds_client_post_focus_event(wnd->client, wnd, &efocus);
     724        if (rc != EOK)
     725                return rc;
     726
     727        /* Notify window managers about window information change */
     728        wmclient = ds_display_first_wmclient(wnd->display);
     729        while (wmclient != NULL) {
     730                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     731                wmclient = ds_display_next_wmclient(wmclient);
     732        }
     733
     734        return EOK;
    640735}
    641736
     
    643738 *
    644739 * @param wnd Window
     740 * @return EOK on success or an error code
    645741 */
    646742errno_t ds_window_post_unfocus_event(ds_window_t *wnd)
    647743{
     744        display_wnd_unfocus_ev_t eunfocus;
     745        errno_t rc;
     746        ds_wmclient_t *wmclient;
     747
    648748        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_post_unfocus_event");
    649749
    650         return ds_client_post_unfocus_event(wnd->client, wnd);
     750        /* Decrease focus counter */
     751        --wnd->nfocus;
     752        eunfocus.nfocus = wnd->nfocus;
     753
     754        rc = ds_client_post_unfocus_event(wnd->client, wnd, &eunfocus);
     755        if (rc != EOK)
     756                return rc;
     757
     758        /* Notify window managers about window information change */
     759        wmclient = ds_display_first_wmclient(wnd->display);
     760        while (wmclient != NULL) {
     761                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     762                wmclient = ds_display_next_wmclient(wmclient);
     763        }
     764
     765        return EOK;
    651766}
    652767
     
    656771 * @param pos Position where the pointer was when the move started
    657772 *            relative to the window
     773 * @param pos_id Positioning device ID
    658774 * @param event Button press event
    659775 */
    660 void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)
     776void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos, sysarg_t pos_id)
    661777{
    662778        gfx_coord2_t orig_pos;
     
    666782
    667783        gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
    668         ds_window_start_move(wnd, &orig_pos);
     784        ds_window_start_move(wnd, &orig_pos, pos_id);
    669785}
    670786
     
    686802{
    687803        *dpos = wnd->dpos;
     804}
     805
     806/** Get maximized window rectangle.
     807 *
     808 * @param wnd Window
     809 */
     810void ds_window_get_max_rect(ds_window_t *wnd, gfx_rect_t *rect)
     811{
     812        *rect = wnd->display->max_rect;
    688813}
    689814
     
    694819 * @param pos Position where the pointer was when the resize started
    695820 *            relative to the window
     821 * @param pos_id Positioning device ID
    696822 * @param event Button press event
    697823 */
    698824void ds_window_resize_req(ds_window_t *wnd, display_wnd_rsztype_t rsztype,
    699     gfx_coord2_t *pos)
     825    gfx_coord2_t *pos, sysarg_t pos_id)
    700826{
    701827        gfx_coord2_t orig_pos;
    702828
    703         log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d)",
    704             (int) rsztype, (int) pos->x, (int) pos->y);
     829        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_resize_req (%d, %d, %d, %d)",
     830            (int)rsztype, (int)pos->x, (int)pos->y, (int)pos_id);
    705831
    706832        gfx_coord2_add(&wnd->dpos, pos, &orig_pos);
    707         ds_window_start_resize(wnd, rsztype, &orig_pos);
     833        ds_window_start_resize(wnd, rsztype, &orig_pos, pos_id);
    708834}
    709835
     
    711837 *
    712838 * @param wnd Window
     839 * @return EOK on success or an error code
    713840 */
    714841errno_t ds_window_resize(ds_window_t *wnd, gfx_coord2_t *offs,
     
    761888        wnd->rect = *nrect;
    762889
     890        if ((wnd->flags & wndf_avoid) != 0)
     891                ds_display_update_max_rect(wnd->display);
     892
    763893        (void) ds_display_paint(wnd->display, NULL);
     894        return EOK;
     895}
     896
     897/** Minimize window.
     898 *
     899 * @param wnd Window
     900 * @return EOK on success or an error code
     901 */
     902errno_t ds_window_minimize(ds_window_t *wnd)
     903{
     904        /* If already minimized, do nothing and return success. */
     905        if ((wnd->flags & wndf_minimized) != 0)
     906                return EOK;
     907
     908        ds_window_unfocus(wnd);
     909
     910        wnd->flags |= wndf_minimized;
     911        (void) ds_display_paint(wnd->display, NULL);
     912        return EOK;
     913}
     914
     915/** Unminimize window.
     916 *
     917 * @param wnd Window
     918 * @return EOK on success or an error code
     919 */
     920errno_t ds_window_unminimize(ds_window_t *wnd)
     921{
     922        /* If not minimized, do nothing and return success. */
     923        if ((wnd->flags & wndf_minimized) == 0)
     924                return EOK;
     925
     926        wnd->flags &= ~wndf_minimized;
     927        (void) ds_display_paint(wnd->display, NULL);
     928        return EOK;
     929}
     930
     931/** Maximize window.
     932 *
     933 * @param wnd Window
     934 * @return EOK on success or an error code
     935 */
     936errno_t ds_window_maximize(ds_window_t *wnd)
     937{
     938        gfx_coord2_t old_dpos;
     939        gfx_rect_t old_rect;
     940        gfx_coord2_t offs;
     941        gfx_rect_t max_rect;
     942        gfx_rect_t nrect;
     943        errno_t rc;
     944
     945        /* If already maximized, do nothing and return success. */
     946        if ((wnd->flags & wndf_maximized) != 0)
     947                return EOK;
     948
     949        /* Remember the old window rectangle and display position */
     950        old_rect = wnd->rect;
     951        old_dpos = wnd->dpos;
     952
     953        ds_window_get_max_rect(wnd, &max_rect);
     954
     955        /* Keep window contents on the same position on the screen */
     956        offs.x = max_rect.p0.x - wnd->dpos.x;
     957        offs.y = max_rect.p0.y - wnd->dpos.y;
     958
     959        /* Maximized window's coordinates will start at 0,0 */
     960        gfx_rect_rtranslate(&max_rect.p0, &max_rect, &nrect);
     961
     962        rc = ds_window_resize(wnd, &offs, &nrect);
     963        if (rc != EOK)
     964                return rc;
     965
     966        /* Set window flags, remember normal rectangle */
     967        wnd->flags |= wndf_maximized;
     968        wnd->normal_rect = old_rect;
     969        wnd->normal_dpos = old_dpos;
     970
     971        return EOK;
     972}
     973
     974/** Unmaximize window.
     975 *
     976 * @param wnd Window
     977 * @return EOK on success or an error code
     978 */
     979errno_t ds_window_unmaximize(ds_window_t *wnd)
     980{
     981        gfx_coord2_t offs;
     982        errno_t rc;
     983
     984        /* If not maximized, do nothing and return success. */
     985        if ((wnd->flags & wndf_maximized) == 0)
     986                return EOK;
     987
     988        /* Keep window contents on the same position on the screen */
     989        offs.x = wnd->normal_dpos.x - wnd->dpos.x;
     990        offs.y = wnd->normal_dpos.y - wnd->dpos.y;
     991
     992        rc = ds_window_resize(wnd, &offs, &wnd->normal_rect);
     993        if (rc != EOK)
     994                return rc;
     995
     996        /* Clear maximized flag */
     997        wnd->flags &= ~wndf_maximized;
     998
    764999        return EOK;
    7651000}
     
    8071042 *
    8081043 * @param wnd Window
     1044 * @param cursor New cursor
    8091045 * @return EOK on success, EINVAL if @a cursor is invalid
    8101046 */
     
    8201056}
    8211057
     1058/** Set window caption.
     1059 *
     1060 * @param wnd Window
     1061 * @param caption New caption
     1062 *
     1063 * @return EOK on success, EINVAL if @a cursor is invalid
     1064 */
     1065errno_t ds_window_set_caption(ds_window_t *wnd, const char *caption)
     1066{
     1067        char *dcaption;
     1068        ds_wmclient_t *wmclient;
     1069
     1070        dcaption = str_dup(caption);
     1071        if (dcaption == NULL)
     1072                return ENOMEM;
     1073
     1074        free(wnd->caption);
     1075        wnd->caption = dcaption;
     1076
     1077        /* Notify window managers about window information change */
     1078        wmclient = ds_display_first_wmclient(wnd->display);
     1079        while (wmclient != NULL) {
     1080                ds_wmclient_post_wnd_changed_event(wmclient, wnd->id);
     1081                wmclient = ds_display_next_wmclient(wmclient);
     1082        }
     1083
     1084        return EOK;
     1085}
     1086
     1087/** Find alternate window with the allowed flags.
     1088 *
     1089 * An alternate window is a *different* window that is preferably previous
     1090 * in the display order and only has the @a allowed flags.
     1091 *
     1092 * @param wnd Window
     1093 * @param allowed_flags Bitmask of flags that the window is allowed to have
     1094 *
     1095 * @return Alternate window matching the criteria or @c NULL if there is none
     1096 */
     1097ds_window_t *ds_window_find_prev(ds_window_t *wnd,
     1098    display_wnd_flags_t allowed_flags)
     1099{
     1100        ds_window_t *nwnd;
     1101
     1102        /* Try preceding windows in display order */
     1103        nwnd = ds_display_next_window(wnd);
     1104        while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {
     1105                nwnd = ds_display_next_window(nwnd);
     1106        }
     1107
     1108        /* Do we already have a matching window? */
     1109        if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {
     1110                return nwnd;
     1111        }
     1112
     1113        /* Try succeeding windows in display order */
     1114        nwnd = ds_display_first_window(wnd->display);
     1115        while (nwnd != NULL && nwnd != wnd &&
     1116            (nwnd->flags & ~allowed_flags) != 0) {
     1117                nwnd = ds_display_next_window(nwnd);
     1118        }
     1119
     1120        if (nwnd == wnd)
     1121                return NULL;
     1122
     1123        return nwnd;
     1124}
     1125
     1126/** Find alternate window with the allowed flags.
     1127 *
     1128 * An alternate window is a *different* window that is preferably previous
     1129 * in the display order and only has the @a allowed flags.
     1130 *
     1131 * @param wnd Window
     1132 * @param allowed_flags Bitmask of flags that the window is allowed to have
     1133 *
     1134 * @return Alternate window matching the criteria or @c NULL if there is none
     1135 */
     1136ds_window_t *ds_window_find_next(ds_window_t *wnd,
     1137    display_wnd_flags_t allowed_flags)
     1138{
     1139        ds_window_t *nwnd;
     1140
     1141        /* Try preceding windows in display order */
     1142        nwnd = ds_display_prev_window(wnd);
     1143        while (nwnd != NULL && (nwnd->flags & ~allowed_flags) != 0) {
     1144                nwnd = ds_display_prev_window(nwnd);
     1145        }
     1146
     1147        /* Do we already have a matching window? */
     1148        if (nwnd != NULL && (nwnd->flags & ~allowed_flags) == 0) {
     1149                return nwnd;
     1150        }
     1151
     1152        /* Try succeeding windows in display order */
     1153        nwnd = ds_display_last_window(wnd->display);
     1154        while (nwnd != NULL && nwnd != wnd &&
     1155            (nwnd->flags & ~allowed_flags) != 0) {
     1156                nwnd = ds_display_prev_window(nwnd);
     1157        }
     1158
     1159        if (nwnd == wnd)
     1160                return NULL;
     1161
     1162        return nwnd;
     1163}
     1164
     1165/** Remove focus from window.
     1166 *
     1167 * Used to switch focus to another window when closing or minimizing window.
     1168 *
     1169 * @param wnd Window
     1170 */
     1171void ds_window_unfocus(ds_window_t *wnd)
     1172{
     1173        ds_seat_t *seat;
     1174
     1175        /* Make sure window is no longer focused in any seat */
     1176        seat = ds_display_first_seat(wnd->display);
     1177        while (seat != NULL) {
     1178                ds_seat_unfocus_wnd(seat, wnd);
     1179                seat = ds_display_next_seat(seat);
     1180        }
     1181}
     1182
     1183/** Determine if input device belongs to the same seat as the original device.
     1184 *
     1185 * Compare the seat ownning @a idev_id with the seat owning @a wnd->orig_pos_id
     1186 * (the device that started the window move or resize).
     1187 *
     1188 * This is used to make sure that, when two seats focus the same window,
     1189 * only devices owned by the seat that started the resize or move can
     1190 * affect it. Otherwise moving the other pointer(s) would disrupt the
     1191 * resize or move operation.
     1192 *
     1193 * @param wnd Window (that is currently being resized or moved)
     1194 * @param idev_id Input device ID
     1195 * @return @c true iff idev_id is owned by the same seat as the input
     1196 *         device that started the resize or move
     1197 */
     1198bool ds_window_orig_seat(ds_window_t *wnd, sysarg_t idev_id)
     1199{
     1200        ds_seat_t *orig_seat;
     1201        ds_seat_t *seat;
     1202
     1203        /* Window must be in state such that wnd->orig_pos_id is valid */
     1204        assert(wnd->state == dsw_moving || wnd->state == dsw_resizing);
     1205
     1206        orig_seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id);
     1207        seat = ds_display_seat_by_idev(wnd->display, idev_id);
     1208
     1209        return seat == orig_seat;
     1210}
     1211
    8221212/** Window memory GC invalidate callback.
    8231213 *
Note: See TracChangeset for help on using the changeset viewer.